Corteksa
GuidesMessaging

Webhooks

Messaging — Webhooks

Inbound provider events (a customer replies, a receipt updates) arrive at the UnifiedWebhookController, base path /api/v1/messaging/webhook. These routes are public (no admin JWT) — they're authenticated by per-provider signatures instead.

Endpoints & signature validation

RouteVerification
POST /messaging/webhook/wahax-webhook-hmac — HMAC (sha256) of the raw body with WAHA_HMAC_SECRET, compared with timingSafeEqual
GET /messaging/webhook/whatsapp-cloudHub verify: hub.verify_token == WHATSAPP_CLOUD_VERIFY_TOKEN → echoes hub.challenge
POST /messaging/webhook/whatsapp-cloudx-hub-signature-256sha256= HMAC over raw body with WHATSAPP_CLOUD_APP_SECRET
GET/POST /messaging/webhook/instagramHub verify vs INSTAGRAM_VERIFY_TOKEN; x-hub-signature-256 with FACEBOOK_APP_SECRET
GET/POST /messaging/webhook/tiktoktiktok-signature (t=<ts>,s=<hmac>) — HMAC-sha256 of <ts>.<rawBody> with TIKTOK_APP_SECRET

Facebook Messenger events arrive through the shared Facebook webhook entry point and are routed into Messaging. In NODE_ENV=development with no secret set, verification is skipped (and warns). A bad signature throws 401.

Routing (factory pattern)

WebhookRouterService.route(providerType, payload) dispatches to a per-provider factory that picks the right handler:

ProviderFactory → handlers
WAHAWebhookEventHandlerFactoryMessageHandler, MessageAckHandler, SessionStatusHandler, CallHandler, MessageEditedHandler, MessageRevokedHandler, PresenceUpdateHandler, LabelChatsHandler, …
WhatsApp CloudWaCloudChangeHandlerFactory (by change.field) → MessagesChangeHandler, TemplatesChangeHandler
FacebookFbMessagingHandlerFactoryFbMessageHandler, FbDeliveryHandler, FbReadHandler
InstagramIgMessagingHandlerFactoryIgMessageHandler, IgDeliveryHandler, IgReadHandler
TikTokTiktokEventHandlerFactoryTiktokMessageHandler, TiktokReadHandler

Each handler writes to the DB, then publishes to Redis so the WebSocket gateway pushes the update to connected clients. Handlers are idempotent — providers retry.

These are provider → Corteksa webhooks. To receive Corteksa → your app events (e.g. a record changed), see the Receive webhooks recipe.

On this page