feat(whatsapp): ✨ Enhance webhook message handling
* Add support for new message types: audio, sticker, location, contacts, interactive, button, reaction, order, system, and unknown. * Implement logging for various webhook events for better visibility. * Update WebhookMessage struct to include new fields for enhanced message processing.
This commit is contained in:
@@ -12,6 +12,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.warky.dev/wdevs/whatshooked/pkg/events"
|
||||
@@ -44,14 +45,53 @@ func (c *Client) HandleWebhook(r *http.Request) error {
|
||||
func (c *Client) processChange(change WebhookChange) {
|
||||
ctx := context.Background()
|
||||
|
||||
// Process messages
|
||||
for _, msg := range change.Value.Messages {
|
||||
c.processMessage(ctx, msg, change.Value.Contacts)
|
||||
}
|
||||
// Handle different field types
|
||||
switch change.Field {
|
||||
case "messages":
|
||||
// Process messages
|
||||
for _, msg := range change.Value.Messages {
|
||||
c.processMessage(ctx, msg, change.Value.Contacts)
|
||||
}
|
||||
|
||||
// Process statuses
|
||||
for _, status := range change.Value.Statuses {
|
||||
c.processStatus(ctx, status)
|
||||
// Process statuses
|
||||
for _, status := range change.Value.Statuses {
|
||||
c.processStatus(ctx, status)
|
||||
}
|
||||
|
||||
case "message_template_status_update":
|
||||
// Log template status updates for visibility
|
||||
logging.Info("Message template status update received",
|
||||
"account_id", c.id,
|
||||
"phone_number_id", change.Value.Metadata.PhoneNumberID)
|
||||
|
||||
case "account_update":
|
||||
// Log account updates
|
||||
logging.Info("Account update received",
|
||||
"account_id", c.id,
|
||||
"phone_number_id", change.Value.Metadata.PhoneNumberID)
|
||||
|
||||
case "phone_number_quality_update":
|
||||
// Log quality updates
|
||||
logging.Info("Phone number quality update received",
|
||||
"account_id", c.id,
|
||||
"phone_number_id", change.Value.Metadata.PhoneNumberID)
|
||||
|
||||
case "phone_number_name_update":
|
||||
// Log name updates
|
||||
logging.Info("Phone number name update received",
|
||||
"account_id", c.id,
|
||||
"phone_number_id", change.Value.Metadata.PhoneNumberID)
|
||||
|
||||
case "account_alerts":
|
||||
// Log account alerts
|
||||
logging.Warn("Account alert received",
|
||||
"account_id", c.id,
|
||||
"phone_number_id", change.Value.Metadata.PhoneNumberID)
|
||||
|
||||
default:
|
||||
logging.Debug("Unknown webhook field type",
|
||||
"account_id", c.id,
|
||||
"field", change.Field)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,12 +170,114 @@ func (c *Client) processMessage(ctx context.Context, msg WebhookMessage, contact
|
||||
}
|
||||
}
|
||||
|
||||
case "audio":
|
||||
if msg.Audio != nil {
|
||||
messageType = "audio"
|
||||
mimeType = msg.Audio.MimeType
|
||||
|
||||
// Download and process media
|
||||
data, _, err := c.downloadMedia(ctx, msg.Audio.ID)
|
||||
if err != nil {
|
||||
logging.Error("Failed to download audio", "account_id", c.id, "media_id", msg.Audio.ID, "error", err)
|
||||
} else {
|
||||
filename, mediaURL = c.processMediaData(msg.ID, data, mimeType, &mediaBase64)
|
||||
}
|
||||
}
|
||||
|
||||
case "sticker":
|
||||
if msg.Sticker != nil {
|
||||
messageType = "sticker"
|
||||
mimeType = msg.Sticker.MimeType
|
||||
|
||||
// Download and process media
|
||||
data, _, err := c.downloadMedia(ctx, msg.Sticker.ID)
|
||||
if err != nil {
|
||||
logging.Error("Failed to download sticker", "account_id", c.id, "media_id", msg.Sticker.ID, "error", err)
|
||||
} else {
|
||||
filename, mediaURL = c.processMediaData(msg.ID, data, mimeType, &mediaBase64)
|
||||
}
|
||||
}
|
||||
|
||||
case "location":
|
||||
if msg.Location != nil {
|
||||
messageType = "location"
|
||||
// Format location as text
|
||||
text = fmt.Sprintf("Location: %s (%s) - %.6f, %.6f",
|
||||
msg.Location.Name, msg.Location.Address,
|
||||
msg.Location.Latitude, msg.Location.Longitude)
|
||||
}
|
||||
|
||||
case "contacts":
|
||||
if len(msg.Contacts) > 0 {
|
||||
messageType = "contacts"
|
||||
// Format contacts as text
|
||||
var contactNames []string
|
||||
for _, contact := range msg.Contacts {
|
||||
contactNames = append(contactNames, contact.Name.FormattedName)
|
||||
}
|
||||
text = fmt.Sprintf("Shared %d contact(s): %s", len(msg.Contacts), strings.Join(contactNames, ", "))
|
||||
}
|
||||
|
||||
case "interactive":
|
||||
if msg.Interactive != nil {
|
||||
messageType = "interactive"
|
||||
switch msg.Interactive.Type {
|
||||
case "button_reply":
|
||||
if msg.Interactive.ButtonReply != nil {
|
||||
text = msg.Interactive.ButtonReply.Title
|
||||
}
|
||||
case "list_reply":
|
||||
if msg.Interactive.ListReply != nil {
|
||||
text = msg.Interactive.ListReply.Title
|
||||
}
|
||||
case "nfm_reply":
|
||||
if msg.Interactive.NfmReply != nil {
|
||||
text = msg.Interactive.NfmReply.Body
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case "button":
|
||||
if msg.Button != nil {
|
||||
messageType = "button"
|
||||
text = msg.Button.Text
|
||||
}
|
||||
|
||||
case "reaction":
|
||||
if msg.Reaction != nil {
|
||||
messageType = "reaction"
|
||||
text = msg.Reaction.Emoji
|
||||
}
|
||||
|
||||
case "order":
|
||||
if msg.Order != nil {
|
||||
messageType = "order"
|
||||
text = fmt.Sprintf("Order with %d item(s): %s", len(msg.Order.ProductItems), msg.Order.Text)
|
||||
}
|
||||
|
||||
case "system":
|
||||
if msg.System != nil {
|
||||
messageType = "system"
|
||||
text = msg.System.Body
|
||||
}
|
||||
|
||||
case "unknown":
|
||||
messageType = "unknown"
|
||||
logging.Warn("Received unknown message type", "account_id", c.id, "message_id", msg.ID)
|
||||
return
|
||||
|
||||
default:
|
||||
logging.Warn("Unsupported message type", "account_id", c.id, "type", msg.Type)
|
||||
return
|
||||
}
|
||||
|
||||
// Publish message received event
|
||||
logging.Debug("Publishing message received event",
|
||||
"account_id", c.id,
|
||||
"message_id", msg.ID,
|
||||
"from", msg.From,
|
||||
"type", messageType)
|
||||
|
||||
c.eventBus.Publish(events.MessageReceivedEvent(
|
||||
ctx,
|
||||
c.id,
|
||||
@@ -276,7 +418,10 @@ func getExtensionFromMimeType(mimeType string) string {
|
||||
"text/plain": ".txt",
|
||||
"application/json": ".json",
|
||||
"audio/mpeg": ".mp3",
|
||||
"audio/mp4": ".m4a",
|
||||
"audio/ogg": ".ogg",
|
||||
"audio/amr": ".amr",
|
||||
"audio/opus": ".opus",
|
||||
}
|
||||
|
||||
if ext, ok := extensions[mimeType]; ok {
|
||||
|
||||
Reference in New Issue
Block a user