Skip to main content
Glama
webhook-payload.md20.1 kB
# Webhook Payload Documentation This document provides comprehensive documentation for the webhook payload structure used by the Go WhatsApp Web Multidevice application. ## Overview The webhook system sends HTTP POST requests to configured URLs whenever WhatsApp events occur. Each webhook request includes event data in JSON format and security headers for verification. ## Security ### HMAC Signature Verification All webhook requests include an HMAC SHA256 signature for security verification: - **Header**: `X-Hub-Signature-256` - **Format**: `sha256={signature}` - **Algorithm**: HMAC SHA256 - **Default Secret**: `secret` (configurable via `--webhook-secret` or `WHATSAPP_WEBHOOK_SECRET`) ### Verification Example (Node.js) ```javascript const crypto = require('crypto'); function verifyWebhookSignature(payload, signature, secret) { const expectedSignature = crypto .createHmac('sha256', secret) .update(payload, 'utf8') .digest('hex'); const receivedSignature = signature.replace('sha256=', ''); return crypto.timingSafeEqual( Buffer.from(expectedSignature, 'hex'), Buffer.from(receivedSignature, 'hex') ); } ``` ### Verification Example (Python) ```python import hmac import hashlib def verify_webhook_signature(payload, signature, secret): expected_signature = hmac.new( secret.encode('utf-8'), payload, hashlib.sha256 ).hexdigest() received_signature = signature.replace('sha256=', '') return hmac.compare_digest(expected_signature, received_signature) ``` ## Common Payload Fields All webhook payloads share these common fields: | **Field** | **Type** | **Description** | |-------------|----------|-------------------------------------------------------------------| | `sender_id` | string | User part of sender JID (phone number, without `@s.whatsapp.net`) | | `chat_id` | string | User part of chat JID | | `from` | string | Full JID of the sender (e.g., `628123456789@s.whatsapp.net`) | | `timestamp` | string | RFC3339 formatted timestamp (e.g., `2023-10-15T10:30:00Z`) | | `pushname` | string | Display name of the sender | ## Message Events ### Text Message ```json { "sender_id": "628123456789", "chat_id": "628987654321", "from": "628123456789@s.whatsapp.net", "timestamp": "2023-10-15T10:30:00Z", "pushname": "John Doe", "message": { "text": "Hello, how are you?", "id": "3EB0C127D7BACC83D6A1", "replied_id": "", "quoted_message": "" } } ``` ### Reply Message ```json { "sender_id": "628123456789", "chat_id": "628987654321", "from": "628123456789@s.whatsapp.net", "timestamp": "2023-10-15T10:35:00Z", "pushname": "John Doe", "message": { "text": "I'm doing great, thanks!", "id": "3EB0C127D7BACC83D6A2", "replied_id": "3EB0C127D7BACC83D6A1", "quoted_message": "Hello, how are you?" } } ``` ### Reaction Message ```json { "sender_id": "628123456789", "chat_id": "628987654321", "from": "628123456789@s.whatsapp.net", "timestamp": "2023-10-15T10:40:00Z", "pushname": "John Doe", "reaction": { "message": "👍", "id": "3EB0C127D7BACC83D6A1" }, "message": { "text": "", "id": "88760C69D1F35FEB239102699AE9XXXX", "replied_id": "", "quoted_message": "" } } ``` ## Receipt Events Receipt events are triggered when messages receive acknowledgments such as delivery confirmations and read receipts. These events use the `message.ack` event type and provide information about message status changes. ### Message Delivered Triggered when a message is successfully delivered to the recipient's device. ```json { "event": "message.ack", "payload": { "chat_id": "120363402106XXXXX@g.us", "from": "6289685XXXXXX@s.whatsapp.net in 120363402106XXXXX@g.us", "ids": [ "3EB00106E8BE0F407E88EC" ], "receipt_type": "delivered", "receipt_type_description": "means the message was delivered to the device (but the user might not have noticed).", "sender_id": "6289685XXXXXX@s.whatsapp.net" }, "timestamp": "2025-07-18T22:44:20Z" } ``` ### Message Read Triggered when a message is read by the recipient (they opened the chat and saw the message). ```json { "event": "message.ack", "payload": { "chat_id": "120363402106XXXXX@g.us", "from": "6289685XXXXXX@s.whatsapp.net in 120363402106XXXXX@g.us", "ids": [ "3EB00106E8BE0F407E88EC" ], "receipt_type": "read", "receipt_type_description": "the user opened the chat and saw the message.", "sender_id": "6289685XXXXXX@s.whatsapp.net" }, "timestamp": "2025-07-18T22:44:44Z" } ``` ### Receipt Event Fields | **Field** | **Type** | **Description** | |------------------------------------|----------|-----------------------------------------------------------| | `event` | string | Always `"message.ack"` for receipt events | | `payload.chat_id` | string | Chat identifier (group or individual chat) | | `payload.from` | string | Sender information with chat context | | `payload.ids` | array | Array of message IDs that received the acknowledgment | | `payload.receipt_type` | string | Type of receipt: `"delivered"`, `"read"`, etc. | | `payload.receipt_type_description` | string | Human-readable description of the receipt type | | `payload.sender_id` | string | JID of the message sender | | `timestamp` | string | RFC3339 formatted timestamp when the receipt was received | ## Group Events Group events are triggered when group metadata changes, including member join/leave events, admin promotions/demotions, and group settings updates. These events use the `group.participants` event type and provide comprehensive information about group changes. ### Group Member Join Triggered when users join or are added to a group. ```json { "event": "group.participants", "payload": { "chat_id": "120363402106XXXXX@g.us", "type": "join", "jids": [ "6289685XXXXXX@s.whatsapp.net", "6289686YYYYYY@s.whatsapp.net" ] }, "timestamp": "2025-07-28T10:30:00Z" } ``` ### Group Member Leave Triggered when users leave or are removed from a group. ```json { "event": "group.participants", "payload": { "chat_id": "120363402106XXXXX@g.us", "type": "leave", "jids": [ "6289687ZZZZZZ@s.whatsapp.net" ] }, "timestamp": "2025-07-28T10:32:00Z" } ``` ### Group Member Promotion Triggered when users are promoted to admin. ```json { "event": "group.participants", "payload": { "chat_id": "120363402106XXXXX@g.us", "type": "promote", "jids": [ "6289688AAAAAA@s.whatsapp.net" ] }, "timestamp": "2025-07-28T10:33:00Z" } ``` ### Group Member Demotion Triggered when users are demoted from admin. ```json { "event": "group.participants", "payload": { "chat_id": "120363402106XXXXX@g.us", "type": "demote", "jids": [ "6289689BBBBBB@s.whatsapp.net" ] }, "timestamp": "2025-07-28T10:34:00Z" } ``` ### Group Event Fields | **Field** | **Type** | **Description** | |-------------------|----------|--------------------------------------------------------------| | `event` | string | Always `"group.participants"` for group events | | `payload.chat_id` | string | Group identifier (e.g., `"120363402106XXXXX@g.us"`) | | `payload.type` | string | Action type: `"join"`, `"leave"`, `"promote"`, or `"demote"` | | `payload.jids` | array | Array of user JIDs affected by this action | | `timestamp` | string | RFC3339 formatted timestamp when the group event occurred | ## Media Messages ### Image Message ```json { "sender_id": "628123456789", "chat_id": "628123456789", "from": "628123456789@s.whatsapp.net", "timestamp": "2025-07-13T11:05:51Z", "pushname": "John Doe", "message": { "text": "", "id": "********************", "replied_id": "", "quoted_message": "" }, "image": { "media_path": "statics/media/1752404751-ad9e37ac-c658-4fe5-8d25-ba4a3f4d58fd.jpe", "mime_type": "image/jpeg", "caption": "gijg" } } ``` ### Video Message ```json { "sender_id": "628123456789", "chat_id": "628123456789", "from": "628123456789@s.whatsapp.net", "timestamp": "2025-07-13T11:07:24Z", "pushname": "Notification System", "message": { "text": "", "id": "********************", "replied_id": "", "quoted_message": "" }, "video": { "media_path": "statics/media/1752404845-b9393cd1-8546-4df9-8a60-ee3276036aba.m4v", "mime_type": "video/mp4", "caption": "okk" } } ``` ### Audio Message ```json { "sender_id": "628123456789", "chat_id": "628987654321", "from": "628123456789@s.whatsapp.net", "timestamp": "2023-10-15T10:55:00Z", "pushname": "John Doe", "message": { "text": "", "id": "3EB0C127D7BACC83D6A5", "replied_id": "", "quoted_message": "" }, "audio": { "media_path": "statics/media/1752404905-b9393cd1-8546-4df9-8a60-ee3276036aba.m4v", "mime_type": "audio/ogg", "caption": "okk" } } ``` ### Document Message ```json { "sender_id": "628123456789", "chat_id": "628987654321", "from": "628123456789@s.whatsapp.net", "timestamp": "2023-10-15T11:00:00Z", "pushname": "John Doe", "message": { "text": "", "id": "3EB0C127D7BACC83D6A6", "replied_id": "", "quoted_message": "" }, "document": { "media_path": "statics/media/1752404965-b9393cd1-8546-4df9-8a60-ee3276036aba.m4v", "mime_type": "application/pdf", "caption": "okk" } } ``` ### Sticker Message ```json { "chat_id": "628968XXXXXXXX", "from": "628968XXXXXXXX@s.whatsapp.net", "message": { "text": "", "id": "446AC2BAF2061B53E24CA526DBDFBD4E", "replied_id": "", "quoted_message": "" }, "pushname": "Aldino Kemal", "sender_id": "628968XXXXXXXX", "sticker": { "media_path": "statics/media/1752404986-ff2464a6-c54c-4e6c-afde-c4c925ce3573.webp", "mime_type": "image/webp", "caption": "" }, "timestamp": "2025-07-13T11:09:45Z" } ``` ## Special Message Types ### Contact Message ```json { "chat_id": "6289XXXXXXXXX", "contact": { "displayName": "3Care", "vcard": "BEGIN:VCARD\nVERSION:3.0\nN:;3Care;;;\nFN:3Care\nTEL;type=Mobile:+62 132\nEND:VCARD", "contextInfo": { "expiration": 7776000, "ephemeralSettingTimestamp": 1751808692, "disappearingMode": { "initiator": 0, "trigger": 1, "initiatedByMe": true } } }, "from": "6289XXXXXXXXX@s.whatsapp.net", "message": { "text": "", "id": "56B3DFF4994284634E7AAFEEF6F1A0A2", "replied_id": "", "quoted_message": "" }, "pushname": "Aldino Kemal", "sender_id": "6289XXXXXXXXX", "timestamp": "2025-07-13T11:10:19Z" } ``` ### Location Message ```json { "sender_id": "628123456789", "chat_id": "628987654321", "from": "John Doe", "timestamp": "2023-10-15T11:15:00Z", "pushname": "John Doe", "message": { "text": "", "id": "3EB0C127D7BACC83D6A9", "replied_id": "", "quoted_message": "" }, "location": { "degreesLatitude": -6.2088, "degreesLongitude": 106.8456, "name": "Jakarta, Indonesia", "address": "Central Jakarta, DKI Jakarta, Indonesia" } } ``` ### Live Location Message ```json { "chat_id": "6289XXXXXXXXX", "from": "6289XXXXXXXXX@s.whatsapp.net", "location": { "degreesLatitude": -7.8050297, "degreesLongitude": 110.4549165, "JPEGThumbnail": "base64_image_thumbnail", "contextInfo": { "expiration": 7776000, "ephemeralSettingTimestamp": 1751808692, "disappearingMode": { "initiator": 0, "trigger": 1, "initiatedByMe": true } } }, "message": { "text": "", "id": "94D13237B4D7F33EE4A63228BBD79EC0", "replied_id": "", "quoted_message": "" }, "pushname": "Aldino Kemal", "sender_id": "6289685XXXXXX", "timestamp": "2025-07-13T11:11:22Z" } ``` ## Protocol Messages ### Message Revoked ```json { "action": "message_revoked", "chat_id": "6289XXXXXXXXX", "from": "6289XXXXXXXXX@s.whatsapp.net", "message": { "text": "", "id": "F4062F2BBCB19B7432195AD7080DA4E2", "replied_id": "", "quoted_message": "" }, "pushname": "Aldino Kemal", "revoked_chat": "6289XXXXXXXXX@s.whatsapp.net", "revoked_from_me": true, "revoked_message_id": "94D13237B4D7F33EE4A63228BBD79EC0", "sender_id": "6289XXXXXXXXX", "timestamp": "2025-07-13T11:13:30Z" } ``` ### Message Edited ```json { "action": "message_edited", "chat_id": "6289XXXXXXXXX", "edited_text": "hhhiawww", "from": "6289XXXXXXXXX@s.whatsapp.net", "message": { "text": "hhhiawww", "id": "D6271D8223A05B4DA6AE9FE3CD632543", "replied_id": "", "quoted_message": "" }, "pushname": "Aldino Kemal", "sender_id": "6289XXXXXXXXX", "timestamp": "2025-07-13T11:14:19Z" } ``` ## Special Flags ### View Once Message ```json { "sender_id": "628123456789", "chat_id": "628987654321", "from": "John Doe", "timestamp": "2023-10-15T11:40:00Z", "pushname": "John Doe", "message": { "text": "", "id": "3EB0C127D7BACC83D6B2", "replied_id": "", "quoted_message": "" }, "image": { "media_path": "statics/media/1752405060-b9393cd1-8546-4df9-8a60-ee3276036aba.m4v", "mime_type": "image/jpeg", "caption": "okk" }, "view_once": true } ``` ### Forwarded Message ```json { "sender_id": "628123456789", "chat_id": "628987654321", "from": "John Doe", "timestamp": "2023-10-15T11:45:00Z", "pushname": "John Doe", "message": { "text": "This is a forwarded message", "id": "3EB0C127D7BACC83D6B3", "replied_id": "", "quoted_message": "" }, "forwarded": true } ``` ## Integration Guide ### Setting Up Webhook Endpoint 1. **Configure webhook URL(s)**: ```bash ./whatsapp rest --webhook="https://yourapp.com/webhook" ``` 2. **Set webhook secret**: ```bash ./whatsapp rest --webhook-secret="your-secret-key" ``` 3. **Multiple webhooks**: ```bash ./whatsapp rest --webhook="https://app1.com/webhook,https://app2.com/webhook" ``` ### Webhook Endpoint Implementation (Express.js) ```javascript const express = require('express'); const crypto = require('crypto'); const app = express(); app.use(express.raw({type: 'application/json'})); app.post('/webhook', (req, res) => { const signature = req.headers['x-hub-signature-256']; const payload = req.body; const secret = 'your-secret-key'; // Verify signature if (!verifyWebhookSignature(payload, signature, secret)) { return res.status(401).send('Unauthorized'); } // Parse and process webhook data const data = JSON.parse(payload); console.log('Received webhook:', data); // Handle different event types if (data.event === 'message.ack') { console.log(`Message ${data.payload.receipt_type}:`, { chat_id: data.payload.chat_id, message_ids: data.payload.ids, description: data.payload.receipt_type_description }); } else if (data.event === 'group.participants') { console.log(`Group ${data.payload.type} event:`, { chat_id: data.payload.chat_id, type: data.payload.type, affected_users: data.payload.jids }); // Handle specific group actions switch (data.payload.type) { case 'join': console.log(`${data.payload.jids.length} users joined group ${data.payload.chat_id}`); // Auto-greet new members data.payload.jids.forEach(jid => { console.log(`Welcome ${jid} to the group!`); }); break; case 'leave': console.log(`${data.payload.jids.length} users left group ${data.payload.chat_id}`); // Update member database break; case 'promote': console.log(`${data.payload.jids.length} users promoted in group ${data.payload.chat_id}`); // Notify about new admins break; case 'demote': console.log(`${data.payload.jids.length} users demoted in group ${data.payload.chat_id}`); // Handle admin removal break; } } else if (data.action === 'message_deleted_for_me') { console.log('Message deleted:', data.deleted_message_id); } else if (data.action === 'message_revoked') { console.log('Message revoked:', data.revoked_message_id); } else if (data.message) { console.log('New message:', data.message.text); } res.status(200).send('OK'); }); function verifyWebhookSignature(payload, signature, secret) { const expectedSignature = crypto .createHmac('sha256', secret) .update(payload, 'utf8') .digest('hex'); const receivedSignature = signature.replace('sha256=', ''); return crypto.timingSafeEqual( Buffer.from(expectedSignature, 'hex'), Buffer.from(receivedSignature, 'hex') ); } app.listen(3001, () => { console.log('Webhook server listening on port 3001'); }); ``` ### Error Handling The webhook system includes retry logic with exponential backoff: - **Timeout**: 10 seconds per request - **Max Attempts**: 5 retries - **Backoff**: Exponential (1s, 2s, 4s, 8s, 16s) Ensure your webhook endpoint: - Responds within 10 seconds - Returns HTTP 2xx status for successful processing - Handles duplicate events gracefully - Validates signatures for security ## Configuration ### Environment Variables ```bash # Single webhook URL WHATSAPP_WEBHOOK=https://yourapp.com/webhook # Multiple webhook URLs (comma-separated) WHATSAPP_WEBHOOK=https://app1.com/webhook,https://app2.com/webhook # Webhook secret for HMAC verification WHATSAPP_WEBHOOK_SECRET=your-super-secret-key ``` ### Command Line Flags ```bash # Single webhook ./whatsapp rest --webhook="https://yourapp.com/webhook" # Multiple webhooks ./whatsapp rest --webhook="https://app1.com/webhook,https://app2.com/webhook" # Custom secret ./whatsapp rest --webhook-secret="your-secret-key" ``` ## Best Practices 1. **Always verify signatures** to ensure webhook authenticity 2. **Handle duplicates** - the same event might be sent multiple times 3. **Process quickly** - respond within 10 seconds to avoid timeouts 4. **Log errors** for debugging webhook integration issues 5. **Use HTTPS** for webhook URLs to ensure secure transmission 6. **Store media files** locally if you need to process them later 7. **Implement proper error handling** for different event types ## Troubleshooting ### Common Issues 1. **Webhook not receiving events**: - Check webhook URL is accessible from the internet - Verify webhook configuration - Check firewall and network settings 2. **Signature verification fails**: - Ensure webhook secret matches configuration - Use raw request body for signature calculation - Check HMAC implementation 3. **Timeouts**: - Optimize webhook processing speed - Implement asynchronous processing - Return response quickly, process in background 4. **Missing media files**: - Check media storage path configuration - Ensure sufficient disk space - Verify file permissions ### Debug Logging Enable debug mode to see webhook logs: ```bash ./whatsapp rest --debug=true --webhook="https://yourapp.com/webhook" ``` This will show detailed logs of webhook delivery attempts and errors.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/samihalawa/whatsapp-go-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server