Webhooks Overview
Stream WhatsApp events to your server in real-time.
Best practices
Validate the incoming payload to ensure it comes from Wawp.
Use a tool like Hookdeck or Smee.io for local development testing.
Filter events in the dashboard to only receive what your application needs.
The Event Stream: Webhooks
Webhooks are the nervous system of your WhatsApp integration. They allow Wawp to push real-time events (messages, reactions, status updates, etc.) to your server, eliminating the need for constant polling.
🏗️ What is a Webhook?
A webhook is an HTTP POST request sent from Wawp to your server whenever an event occurs.
- Push-Based: You don't ask for updates; Wawp sends them automatically.
- Real-Time: Events arrive within milliseconds of occurring.
- Selective: You choose which event types to receive.
The Alternative (Polling)
Without webhooks, you would need to:
setInterval(async () => {
const messages = await api.getMessages();
// Process new messages
}, 5000); // Poll every 5 seconds
Problems:
- Wastes API quota.
- Introduces latency (up to 5 seconds delay).
- Misses events if your server is down during the poll.
Webhooks Solve This: Events are delivered instantly, and Wawp retries if your server is temporarily unavailable.
🚀 Setup Guide
Step 1: Create a Webhook Endpoint
Your server must expose a publicly accessible URL that accepts POST requests.
Example (Node.js/Express):
app.post('/webhook/whatsapp', (req, res) => {
const event = req.body;
console.log('Received event:', event.event);
// Acknowledge receipt immediately
res.status(200).send('OK');
// Process asynchronously
processEvent(event);
});
Critical: Always respond with 200 OK immediately. Process the event in the background. If you take too long to respond, Wawp will assume the delivery failed and retry.
Step 2: Configure in Wawp Dashboard
- Log into wawp.net/account/connect.
- Click Webhook on your instance card.
- Add your endpoint URL (e.g.,
https://yourdomain.com/webhook/whatsapp). - Select which events to receive (e.g.,
messages,reactions,status.update). - Set a retry policy (e.g., retry every 5 seconds, up to 10 times).
Step 3: Test with a Tool
Use Hookdeck, Smee.io, or ngrok to test locally:
ngrok http 3000
# Copy the HTTPS URL (e.g., https://abc123.ngrok.io) to Wawp dashboard
📦 Event Structure
All webhook events follow this schema:
{
"id": "evt_1234567890",
"timestamp": 1722170400000,
"session": "your_instance_id",
"engine": "WEBJS",
"event": "message",
"payload": {
"id": "msg_abc123",
"from": "1234567890@c.us",
"body": "Hello!",
"type": "text"
},
"me": {
"id": "your_number@c.us",
"pushName": "Your Bot"
},
"metadata": {
"user.id": "123",
"user.email": "you@example.com"
}
}
- id: Unique event ID (for deduplication).
- timestamp: Unix timestamp (milliseconds).
- event: Event type (e.g.,
message,message.reaction,group.participants.update). - payload: Event-specific data.
- me: Information about your WhatsApp account.
🆔 WhatsApp ID (JID) Reference
In the Wawp ecosystem, every entity (contact, group, channel) is identified by a unique string called a JID. Understanding the different suffixes is critical for routing messages and events correctly.
| Suffix | Identity Type | Description |
|---|---|---|
@c.us | Individual / Contact | The standard personal or business WhatsApp account. Used for 1-on-1 chats. |
@g.us | Group | Identifies a multi-user group conversation. |
@newsletter | Channel | Represents a public Broadcast Channel or Newsletter. |
@lid | Lookup ID | A privacy-preserving identifier used by modern WhatsApp features to mask real phone numbers. |
@broadcast | Broadcast List | Identifiers for legacy one-to-many broadcast lists (Status/List). |
Strategic Advice: When storing identities in your CRM, always store the full JID (e.g., 447441429009@c.us). This ensures your database remains compatible with Wawp's internal routing table and prevents collision between a phone number and a group ID that might accidentally share a similar prefix.
🔐 Security
1. Validate the Source
Wawp does not currently sign webhooks with HMAC. To secure your endpoint:
- IP Whitelist: Only accept requests from Wawp's server IPs.
- Secret Token: Add a query parameter to your webhook URL (e.g.,
?secret=abc123) and validate it.
2. Idempotency
Wawp may send the same event multiple times (e.g., if your server was slow to respond).
- Solution: Store the
event.idin a database. If you've seen it before, skip processing.
const processedEvents = new Set();
app.post('/webhook', (req, res) => {
const event = req.body;
if (processedEvents.has(event.id)) {
return res.status(200).send('Already processed');
}
processedEvents.add(event.id);
// Process event...
});
🛠️ Common Event Types
| Event | Description |
|---|---|
message | New message received (text, image, video, etc.) |
message.reaction | User reacted to a message (emoji) |
message.revoked | User deleted a message |
message.ack | Message delivery status changed (sent → delivered → read) |
group.participants.update | User joined/left a group |
presence.update | User's online status changed |
call.received | Incoming voice/video call |
status.update | User posted a WhatsApp Status (Story) |
🔄 Retry Logic
If your server returns a non-200 status code (or times out), Wawp will retry:
- Default: 5 retries, 5 seconds apart.
- Exponential Backoff: Optional. Retries at 5s, 10s, 20s, 40s, 80s.
- Dead Letter Queue: After max retries, the event is logged but not delivered.
Best Practice: Log failed events to a database so you can manually replay them later.
🎯 Use Cases
1. Auto-Reply Bot
webhook.on('message', async (event) => {
if (event.payload.body === 'hi') {
await api.sendText(event.payload.from, 'Hello! How can I help?');
}
});
2. CRM Sync
webhook.on('message', async (event) => {
await crm.createTicket({
from: event.payload.from,
message: event.payload.body,
timestamp: event.timestamp
});
});
3. Analytics Dashboard
webhook.on('message.ack', async (event) => {
if (event.payload.ack === 3) { // Read
await analytics.trackMessageRead(event.payload.id);
}
});
⚠️ Common Pitfalls
- Slow Processing: If your endpoint takes >5 seconds to respond, Wawp will retry. Always respond immediately and process async.
- No HTTPS: Webhook URLs must use HTTPS. HTTP is not supported.
- Localhost URLs:
http://localhost:3000won't work. Use ngrok or deploy to a public server. - Ignoring Duplicates: Always implement idempotency checks.
📊 Monitoring
Track webhook health:
let successCount = 0;
let errorCount = 0;
app.post('/webhook', (req, res) => {
try {
processEvent(req.body);
successCount++;
res.status(200).send('OK');
} catch (err) {
errorCount++;
res.status(500).send('Error');
}
});
setInterval(() => {
console.log(`Success: ${successCount}, Errors: ${errorCount}`);
}, 60000); // Log every minute
🎯 Best Practices
- Filter Events: Only subscribe to events you need to reduce traffic.
- Queue Processing: Use a message queue (Redis, RabbitMQ) to handle high-volume events.
- Logging: Log all incoming events for debugging and compliance.
- Graceful Degradation: If your server is down, Wawp will retry. Ensure you have a fallback plan.
Strategic Deep-Dive: Architecting for Scale and Resilience
The following sections provide a high-level strategic overview of webhook orchestration for enterprise-grade WhatsApp integrations.
🏗️ Architectural Philosophy: The Shift from Pull to Push
In the ecosystem of distributed messaging, time is the most valuable commodity. For a business to remain competitive, it must move beyond "Passive Polling" and embrace Active Synchronicity. Webhooks are the foundational nervous system of the Wawp platform, providing a real-time, push-based communication layer that informs your infrastructure of every critical event—message receipts, status changes, group modifications, and more—the moment they occur on the WhatsApp network.
1. Webhooks as High-Fidelity Signal Streams
A webhook is a Reactive Event Trigger. Instead of your system looking for data, the Wawp service pushes a structured HTTP POST payload to your endpoint the millisecond an event is processed. This transforms your application from a "Batch Processor" into a Real-Time Orchestrator.
- Zero Latency: Events move at the speed of the network. This is critical for customer support and security.
- Resource Stewardship: Your server only expends compute cycles when there is actual work to be done. This leads to higher horizontal scalability and lower operational costs.
2. The Idempotent Perimeter
In a distributed network, "At Least Once" is the practical reality. Webhooks are designed with Redundancy and Retries. This means your system must be architected for Idempotency—the ability to receive the same event multiple times without triggering duplicate business logic. By deduplicating events at your entry point using the unique Event ID, you ensure that your CRM doesn't create five tickets for the same message.
🚀 Strategic Use Cases: Powering the Real-Time Enterprise
1. The Autonomous Customer Advocate
When a customer sends a message, a webhook triggers background lookups to identify the customer, check tiers, and route messages to specialized agents instantly. By subscribing to message.ack events, your system can even detect if an agent's reply was "Read", triggering automated follow-ups if needed.
2. Perimeter Security and Governance Monitoring
For large communities, webhooks monitor group.participants.update events to detect unauthorized joins. The system can autonomously remove them and alert security, ensuring conversational perimeters remain secure without manual auditing.
3. Event-Driven Marketing and Conversion Funnels
In a sales funnel, timing is everything. If a user reacts to a marketing message with an emoji, a message.reaction webhook can instantly trigger a personalized discount code, capitalizing on the micro-moment of engagement.
🛡️ Administrative Mandate: Designing for Resilience and Scale
1. The "Acknowledge First, Process Later" Protocol
The most common failure is bottlenecking during event processing. The Strategic Rule: Your endpoint should be a "Thin Ingestion Layer." It receives the POST request, puts it into a high-speed message queue (like Redis or RabbitMQ), and immediately returns an HTTP 200. The actual business logic happens asynchronously, ensuring responsiveness during traffic bursts.
2. Source Verification and Tunnel Security
Verify that every incoming request originated from Wawp. Combine secret query parameters with IP Whitelisting and payload validation to prevent "Payload Injection" attacks and ensure your CRM logic is never triggered by malicious actors.
🛡️ Operational Best Practices: Maintaining Ecosystem Health
- Selective Subscription: Only subscribe to the event types your application actually requires to minimize bandwidth and processing overhead.
- The "Dead Letter Queue" (DLQ) Strategy: For events that fail all retries, use a DLQ to allow for manual replay once service is restored.
- Latency Monitoring: Track the "Delivery Gap"—the time between the event's timestamp and reaching your server—as an early warning sign of bottlenecks.
⚙️ Engineering Best Practices: The Validation Loop
- High-Availability Infrastructure: Host your webhook endpoint on an auto-scaling platform. It should be online 99.99% of the time.
- Schema Enforcement: Treat every incoming webhook as untrusted input and use a strict schema validator.
- Cross-Instance Coordination: Use the
sessionormefield in the payload to correctly silo data when managing multiple instances.
🎯 Conclusion: Beyond "Integration"—The Reactive Advantage
The Webhooks Ecosystem is the bridge between a static application and a "Living" conversational platform. By architecting around reactive principles, you move from "Asking for Data" to Automated Response, flowing in harmony with the global pulse of the WhatsApp network.
Command Palette
Search for a command to run...