feat(whatsapp): 🎉 Add extended sending and template management
* Implemented new endpoints for sending various message types: - Audio - Sticker - Location - Contacts - Interactive messages - Template messages - Flow messages - Reactions - Marking messages as read * Added template management endpoints: - List templates - Upload templates - Delete templates * Introduced flow management endpoints: - List flows - Create flows - Get flow details - Upload flow assets - Publish flows - Delete flows * Added phone number management endpoints: - List phone numbers - Request verification code - Verify code * Enhanced media management with delete media endpoint. * Updated dependencies.
This commit is contained in:
@@ -52,58 +52,78 @@ func (c *Client) HandleWebhook(r *http.Request) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// processChange processes a webhook change
|
||||
// processChange processes a webhook change.
|
||||
// change.Value is json.RawMessage because Meta uses different payload shapes per field type.
|
||||
// Each case unmarshals into the appropriate struct.
|
||||
func (c *Client) processChange(change WebhookChange) {
|
||||
ctx := context.Background()
|
||||
|
||||
logging.Info("Processing webhook change",
|
||||
"account_id", c.id,
|
||||
"field", change.Field,
|
||||
"phone_number_id", change.Value.Metadata.PhoneNumberID)
|
||||
|
||||
// Handle different field types
|
||||
switch change.Field {
|
||||
case "messages":
|
||||
// Process messages
|
||||
for i := range change.Value.Messages {
|
||||
msg := change.Value.Messages[i]
|
||||
c.processMessage(ctx, msg, change.Value.Contacts)
|
||||
var value WebhookValue
|
||||
if err := json.Unmarshal(change.Value, &value); err != nil {
|
||||
logging.Error("Failed to parse messages webhook value",
|
||||
"account_id", c.id, "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Process statuses
|
||||
for _, status := range change.Value.Statuses {
|
||||
logging.Info("Processing webhook change",
|
||||
"account_id", c.id,
|
||||
"field", change.Field,
|
||||
"phone_number_id", value.Metadata.PhoneNumberID)
|
||||
|
||||
for i := range value.Messages {
|
||||
c.processMessage(ctx, value.Messages[i], value.Contacts)
|
||||
}
|
||||
for _, status := range 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)
|
||||
var value TemplateStatusValue
|
||||
if err := json.Unmarshal(change.Value, &value); err != nil {
|
||||
logging.Error("Failed to parse template status update",
|
||||
"account_id", c.id, "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
case "account_update":
|
||||
// Log account updates
|
||||
logging.Info("Account update received",
|
||||
logging.Info("Template status update received",
|
||||
"account_id", c.id,
|
||||
"phone_number_id", change.Value.Metadata.PhoneNumberID)
|
||||
"template_name", value.TemplateName,
|
||||
"template_id", value.TemplateID,
|
||||
"language", value.Language,
|
||||
"status", value.Status,
|
||||
"rejection_reasons", value.RejectionReasons)
|
||||
|
||||
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)
|
||||
c.eventBus.Publish(events.TemplateStatusUpdateEvent(
|
||||
ctx,
|
||||
c.id,
|
||||
value.TemplateName,
|
||||
value.TemplateID,
|
||||
value.Language,
|
||||
value.Status,
|
||||
value.RejectionReasons,
|
||||
))
|
||||
|
||||
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_update", "phone_number_quality_update", "phone_number_name_update", "account_alerts":
|
||||
// These all carry the standard WebhookValue with metadata
|
||||
var value WebhookValue
|
||||
if err := json.Unmarshal(change.Value, &value); err != nil {
|
||||
logging.Error("Failed to parse webhook value",
|
||||
"account_id", c.id, "field", change.Field, "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
case "account_alerts":
|
||||
// Log account alerts
|
||||
logging.Warn("Account alert received",
|
||||
"account_id", c.id,
|
||||
"phone_number_id", change.Value.Metadata.PhoneNumberID)
|
||||
if change.Field == "account_alerts" {
|
||||
logging.Warn("Account alert received",
|
||||
"account_id", c.id,
|
||||
"phone_number_id", value.Metadata.PhoneNumberID)
|
||||
} else {
|
||||
logging.Info("Webhook notification received",
|
||||
"account_id", c.id,
|
||||
"field", change.Field,
|
||||
"phone_number_id", value.Metadata.PhoneNumberID)
|
||||
}
|
||||
|
||||
default:
|
||||
logging.Debug("Unknown webhook field type",
|
||||
|
||||
Reference in New Issue
Block a user