feat(whatsapp): 🎉 Add extended sending and template management
Some checks failed
CI / Test (1.23) (push) Failing after -24m15s
CI / Test (1.22) (push) Failing after -24m12s
CI / Build (push) Successful in -26m47s
CI / Lint (push) Successful in -26m36s

* 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:
Hein
2026-02-03 18:07:42 +02:00
parent 98fc28fc5f
commit a7a5831911
16 changed files with 2024 additions and 48 deletions

View File

@@ -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",