Chatwoot + Webhooks: Build Custom Chatbots and Integrate with Your CRM
Customer support platforms are usually closed boxes. Messages come in, agents respond, tickets get closed. But what if you need to sync conversations to your CRM? Or trigger automated responses based on customer data? Or route tickets based on custom business logic?
Chatwoot solves this with webhooks and a comprehensive API. Every conversation event can trigger external systems. Every message can be enriched with data from your existing tools.
How Chatwoot Webhooks Work
Chatwoot fires webhooks for key events: new conversations, incoming messages, conversation status changes, and more. Configure them in Settings → Integrations → Webhooks.
Each webhook receives a JSON payload with the event type and relevant data:
{
"event": "message_created",
"id": 1234,
"content": "I need help with my order",
"message_type": "incoming",
"conversation": {
"id": 567,
"status": "open",
"contact": {
"id": 89,
"email": "customer@example.com",
"name": "Jane Smith"
}
},
"account": {
"id": 1
}
}
Your endpoint receives this payload and can respond with actions, sync data, or trigger workflows.
Building a Simple Webhook Handler
Here's a Node.js endpoint that receives Chatwoot webhooks and logs them:
const express = require('express');
const app = express();
app.use(express.json());
app.post('/chatwoot-webhook', (req, res) => {
const { event, content, conversation } = req.body;
console.log(`Event: ${event}`);
console.log(`Message: ${content}`);
console.log(`Contact: ${conversation?.contact?.email}`);
// Acknowledge receipt
res.status(200).json({ received: true });
});
app.listen(3000);
In production, you'll want to verify the webhook signature. Chatwoot signs payloads with HMAC-SHA256 using your webhook secret:
const crypto = require('crypto');
function verifySignature(payload, signature, secret) {
const hmac = crypto.createHmac('sha256', secret);
const digest = hmac.update(JSON.stringify(payload)).digest('hex');
return signature === digest;
}
app.post('/chatwoot-webhook', (req, res) => {
const signature = req.headers['x-chatwoot-signature'];
if (!verifySignature(req.body, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Process the webhook...
});
Syncing Conversations to Your CRM
A common integration: push new conversations to your CRM as leads. When a conversation starts, create a contact record with the customer details:
app.post('/chatwoot-webhook', async (req, res) => {
const { event, conversation } = req.body;
if (event === 'conversation_created') {
const contact = conversation.contact;
// Create lead in your CRM
await fetch('https://your-crm.com/api/leads', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.CRM_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: contact.name,
email: contact.email,
phone: contact.phone_number,
source: 'Chatwoot',
conversation_url: `https://your-chatwoot.com/app/accounts/1/conversations/${conversation.id}`
})
});
}
res.status(200).json({ synced: true });
});
Now every new customer conversation automatically appears in your sales pipeline.
Building Automated Bot Responses
Chatwoot's API lets you send messages programmatically. Combine this with webhooks to build custom bots:
const CHATWOOT_API = 'https://your-chatwoot.com/api/v1';
const API_KEY = process.env.CHATWOOT_API_KEY;
async function sendMessage(accountId, conversationId, content) {
await fetch(
`${CHATWOOT_API}/accounts/${accountId}/conversations/${conversationId}/messages`,
{
method: 'POST',
headers: {
'api_access_token': API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
content,
message_type: 'outgoing',
private: false
})
}
);
}
app.post('/chatwoot-webhook', async (req, res) => {
const { event, content, conversation, account } = req.body;
if (event === 'message_created' && req.body.message_type === 'incoming') {
// Auto-respond to common questions
if (content.toLowerCase().includes('hours')) {
await sendMessage(
account.id,
conversation.id,
"We're open Monday-Friday, 9 AM - 6 PM EST. How can I help you today?"
);
}
if (content.toLowerCase().includes('pricing')) {
await sendMessage(
account.id,
conversation.id,
"You can find our pricing at https://yoursite.com/pricing. Would you like me to connect you with sales?"
);
}
}
res.status(200).json({ processed: true });
});
This simple bot handles FAQs instantly, reducing response time for common queries.
Routing Based on Custom Logic
Route conversations to specific teams or agents based on external data. Check your database, verify subscription status, or apply any business logic:
app.post('/chatwoot-webhook', async (req, res) => {
const { event, conversation } = req.body;
if (event === 'conversation_created') {
const customerEmail = conversation.contact.email;
// Check subscription tier in your database
const customer = await db.query(
'SELECT subscription_tier FROM customers WHERE email = $1',
[customerEmail]
);
// Assign to appropriate team
let teamId;
if (customer?.subscription_tier === 'enterprise') {
teamId = ENTERPRISE_TEAM_ID; // Priority support
} else {
teamId = STANDARD_TEAM_ID;
}
// Update conversation assignment via API
await fetch(
`${CHATWOOT_API}/accounts/${conversation.account_id}/conversations/${conversation.id}/assignments`,
{
method: 'POST',
headers: { 'api_access_token': API_KEY },
body: JSON.stringify({ team_id: teamId })
}
);
}
res.status(200).json({ routed: true });
});
Enterprise customers automatically get priority routing. No manual triage needed.
Available Webhook Events
Chatwoot triggers webhooks for these events:
conversation_created- New conversation startedconversation_status_changed- Status update (open, resolved, pending)conversation_updated- Any conversation changemessage_created- New message (incoming or outgoing)message_updated- Message editedwebwidget_triggered- Chat widget interaction
Subscribe to the events relevant to your integration. Less noise, more signal.
Deploy on Elestio
Running Chatwoot with proper webhook infrastructure means managing SSL, database backups, and keeping the application updated. Elestio handles this out of the box.
Deploy Chatwoot in minutes, configure your webhooks, and start building integrations. Your customer conversations become part of your broader system instead of sitting in a silo.
Ready to connect your support platform to everything else? Deploy Chatwoot on Elestio and start building.
Thanks for reading!