Skip to main content

Triggers

The ballerinax/whatsapp.business package supports event-driven integration through WhatsApp Business Cloud webhooks. When a message arrives or an account, template, or phone number state changes, the listener receives the webhook request and dispatches it to the matching service callback automatically.

Three components work together:

ComponentRole
business:ListenerWraps an http:Listener, handles the Meta subscription handshake and X-Hub-Signature-256 verification, and dispatches events to an attached WhatsAppService.
business:WhatsAppServiceDefines the webhook-field callbacks, such as onMessages, onAccountUpdate, and onSecurity.
business:MessagesNotificationThe payload passed to onMessages: either a batch of inbound messages (Messages) or a batch of status updates (MessageStatuses).
business:CallerProvided to a handler's optional second parameter for manual acknowledgement when autoAck is false.

For action-based operations, see the Action Reference.

Error handling​

Each service callback returns error?. If a callback returns an error, the listener logs it and continues processing subsequent events. Declare the eleventh, optional onError handler to react to a handler failure beyond logging. It receives the originating error and the webhook field being dispatched at the time.

Listener​

The business:Listener receives webhook requests from Meta, handles the GET subscription handshake automatically, and routes POST notifications to the attached service.

Configuration​

Config TypeDescription
int|http:ListenerA port number to bind a new http:Listener to, or an existing http:Listener.
ListenerConfigThe verify token and app secret; both required.

business:ListenerConfig fields:

FieldTypeDefaultDescription
verifyTokenstringRequiredThe verification token configured in the Meta App dashboard.
appSecretstringRequiredThe Meta app secret, used to verify the X-Hub-Signature-256 header on inbound webhook notifications.

Initializing the listener​

import ballerinax/whatsapp.business as business;

configurable string verifyToken = ?;
configurable string appSecret = ?;

listener business:Listener whatsappListener = new (8090, verifyToken = verifyToken, appSecret = appSecret);

Service​

A WhatsApp Business trigger service is a Ballerina service attached to a business:Listener, implementing business:WhatsAppService. None of its handlers are required. Declare only the ones you care about. A field whose handler you didn't declare (or a field outside this closed set) is logged and dropped rather than delivered anywhere.

By default, the listener acknowledges (200 OK) each notification automatically, before any handler runs. Meta requires a fast 2xx and retries otherwise, so this is the safe default for slow handlers. Annotate the service @business:ServiceConfig {autoAck: false} to take control of this yourself: declare a handler's optional second parameter as a business:Caller and call caller->complete() when ready. See Manual acknowledgement.

Callback signatures​

CallbackSignatureDescription
onMessagesremote function onMessages(business:MessagesNotification notification) returns error?Invoked for inbound messages and outbound message status updates.
onAccountReviewUpdateremote function onAccountReviewUpdate(business:AccountReviewUpdate update) returns error?Invoked when a WABA review decision changes.
onAccountUpdateremote function onAccountUpdate(business:AccountUpdate update) returns error?Invoked on an account-lifecycle or compliance change.
onBusinessCapabilityUpdateremote function onBusinessCapabilityUpdate(business:BusinessCapabilityUpdate update) returns error?Invoked when a WABA's messaging or phone-number capability limits change.
onMessageTemplateQualityUpdateremote function onMessageTemplateQualityUpdate(business:MessageTemplateQualityUpdate update) returns error?Invoked when a message template's quality score changes.
onMessageTemplateStatusUpdateremote function onMessageTemplateStatusUpdate(business:MessageTemplateStatusUpdate update) returns error?Invoked when a message template's status changes.
onPhoneNumberNameUpdateremote function onPhoneNumberNameUpdate(business:PhoneNumberNameUpdate update) returns error?Invoked when a phone number's display-name review outcome is available.
onPhoneNumberQualityUpdateremote function onPhoneNumberQualityUpdate(business:PhoneNumberQualityUpdate update) returns error?Invoked when a phone number's messaging throughput or quality tier changes.
onSecurityremote function onSecurity(business:Security security) returns error?Invoked on a two-step-verification PIN change or reset request.
onTemplateCategoryUpdateremote function onTemplateCategoryUpdate(business:TemplateCategoryUpdate update) returns error?Invoked when a message template's category changes.
onErrorremote function onError(business:HandlerError handlerError) returns error?Invoked when any handler above returned an error while being dispatched.
note

A compiler plugin validates every handler you declare: its name must be one of the eleven above, its parameter must match the documented event type, and it must return error?. Every handler may optionally declare a second parameter typed business:Caller, for manual acknowledgement.

Full usage example​

import ballerina/log;
import ballerinax/whatsapp.business as business;

configurable string verifyToken = ?;
configurable string appSecret = ?;

listener business:Listener whatsappListener = new (8090, verifyToken = verifyToken, appSecret = appSecret);

service business:WhatsAppService on whatsappListener {

remote function onMessages(business:MessagesNotification notification) returns error? {
if notification is business:Messages {
// handle inbound messages: notification.messages
} else {
// handle status updates: notification.statuses
}
}

remote function onSecurity(business:Security security) returns error? {
// handle a PIN change/reset event
}
}

Manual acknowledgement​

import ballerina/log;
import ballerinax/whatsapp.business as business;

configurable string verifyToken = ?;
configurable string appSecret = ?;

listener business:Listener whatsappListener = new (8090, verifyToken = verifyToken, appSecret = appSecret);

@business:ServiceConfig {
autoAck: false
}
service business:WhatsAppService on whatsappListener {

remote function onMessages(business:MessagesNotification notification, business:Caller caller) returns error? {
check persistNotification(notification);
check caller->complete();
}
}
note

When autoAck is true (the default), the listener acknowledges the notification automatically before dispatching it. Set autoAck: false and declare a business:Caller to acknowledge only after your own processing has durably succeeded. If a handler declared with a Caller never calls caller->complete(), the listener never sends its own 200 OK; the underlying HTTP service falls back to a default 500, a non-2xx that Meta's own retry behavior treats the same as any other failed delivery.

Meta may redeliver a notification if the acknowledgement is slow, dropped, or never sent, under either autoAck setting, not just false. Make handler processing idempotent, or deduplicate using a scoped key: InboundMessage.messageId (wamid) alone for messages, but MessageStatusUpdate.messageId needs status alongside it, since one message's several status updates share the same messageId.

Event payload types​

InboundMessage​

One inbound message, part of a Messages batch.

FieldTypeDescription
fromstringThe WhatsApp ID (phone number) of the sender.
messageIdstringThe unique WhatsApp message ID (wamid...).
messageTypestringThe message type (for example, text, image, interactive).
textstring?The message body for text messages; () for non-text messages.
timestampstring?The provider-reported timestamp of the message, if present.
contactNamestring?The sender's WhatsApp profile name, if present.
rawjsonThe raw message object as received, for accessing type-specific fields.

MessageStatusUpdate​

One outbound message status update, part of a MessageStatuses batch.

FieldTypeDescription
messageIdstringThe message ID whose status changed.
statusstringThe new status (sent, delivered, read, or failed).
recipientIdstringThe WhatsApp ID of the recipient.
timestampstring?The provider-reported timestamp of the status change, if present.
errorsMessageErrorDetail[]?Delivery failure details; present only when status is failed.
rawjsonThe raw status object as received.

AccountUpdate​

A WABA account-lifecycle or compliance change. Only the sub-record matching event is populated.

FieldTypeDescription
wabaIdstringThe WhatsApp Business Account ID the change relates to.
eventstringThe event type (for example, ACCOUNT_DELETED, ACCOUNT_VIOLATION, DISABLED_UPDATE).
countrystring?The ISO country code; present only for location-related events.
timestampint?The entry-level webhook trigger timestamp (Unix epoch seconds), if present.
rawjsonThe raw value object as received, for accessing undocumented sub-fields.

Security​

A two-step-verification PIN change, reset request, or reset success for a business phone number.

FieldTypeDescription
wabaIdstringThe WhatsApp Business Account ID the phone number belongs to.
displayPhoneNumberstringThe business phone number the security event relates to.
eventstringThe security action (PIN_CHANGED, PIN_RESET_REQUEST, or PIN_REQUEST_SUCCESS).
requesterstring?The Meta Business Suite user ID that initiated the action; present only for reset requests.
timestampint?The entry-level webhook trigger timestamp (Unix epoch seconds), if present.
rawjsonThe raw value object as received.

HandlerError​

Reports an error returned by another WhatsAppService handler while it was being invoked. Delivered to onError, if declared.

FieldTypeDescription
errorerrorThe error the handler returned.
fieldstringThe webhook field being dispatched when the handler failed (for example, messages, account_update).
payloadjsonThe raw value object that was being dispatched, for diagnostics.

Caller​

Passed to a handler's optional second parameter for manual acknowledgement when the service is annotated @business:ServiceConfig {autoAck: false}.

MethodSignatureDescription
completeremote isolated function complete() returns business:Error?Acknowledges (200 OK) the notification. Idempotent: a no-op if already called.

What's next​

  • Action Reference: send messages and templates, and manage media.
  • Example: complete example integrations for the WhatsApp Business connector and trigger.
  • Setup Guide: create a Meta app and configure the webhook.