Webhook System - Documentation¶
Overview¶
The webhook system allows you to configure HTTP endpoints that will be called automatically when specific events occur in your ConnectGain system. This enables you to integrate with external systems, trigger automations, or build custom workflows.
Available Events (17 Total)¶
Contact Events (3)¶
- contact.created - Fired when a new contact is created
- contact.updated - Fired when a contact is updated
- contact.assigned - Fired when a contact is assigned to someone
Deal/Lead Events (4)¶
- deal.created - Fired when a new deal/lead is created
- deal.updated - Fired when a deal is updated
- deal.stage.changed - Fired when a deal moves to a different pipeline stage
- deal.assigned - Fired when a deal is assigned to someone
Conversation Events (3)¶
- conversation.created - Fired when a new conversation is created
- conversation.assigned - Fired when a conversation is assigned
- conversation.status.changed - Fired when conversation status changes (OPEN/CLOSED)
Message Events (5)¶
- message.received - Fired when a new message is received
- message.sent - Fired when a message is sent
- message.delivered - Fired when a sent message is delivered to the recipient
- message.read - Fired when a sent message is read by the recipient
- message.failed - Fired when a message fails to send
Broadcast Events (1)¶
- broadcast.response - Fired when a contact replies to a broadcast/campaign message
Meeting Events (1)¶
- zoom.recording.completed - Fired when a Zoom cloud recording finishes processing
HTTP Method: POST¶
All webhooks are sent as HTTP POST requests with JSON payload.
⚠️ Your endpoint must accept POST requests (not GET).
The webhook dispatcher sends: - Method: POST - Content-Type: application/json - Body: JSON payload with event data
Event Payload Format¶
All webhook calls follow this format:
{
"event": "contact.created",
"timestamp": "2024-01-15T10:30:00Z",
"data": {
"id": "uuid-here",
"first_name": "John",
"last_name": "Doe",
"organization_id": "org-uuid",
//... other fields specific to the event
}
}
Webhook Signature¶
If you provide a secret when configuring your webhook, requests will include an HMAC SHA-256 signature:
Headers:
- X-Webhook-Event: The event type
- X-Webhook-Timestamp: ISO timestamp
- X-Webhook-Signature: HMAC signature (if secret is set)
Verification:
1. Get the X-Webhook-Signature header
2. Compute HMAC SHA-256 of the request body using your secret
3. Compare the signatures (use constant-time comparison)
Configuration¶
Webhooks are configured via the Settings page or through the API.
Using the API¶
import { createWebhookConfig } from '@/lib/webhook';
await createWebhookConfig({
name: 'My Integration',
url: 'https://example.com/webhooks',
events: ['contact.created', 'deal.stage.changed'],
secret: 'your-hmac-secret', // Optional
is_active: true
});
Configuration Fields¶
- name: Human-readable name for the webhook
- url: Endpoint URL to receive webhook calls
- events: Array of event types to subscribe to
- secret: HMAC secret for signature verification (optional)
- is_active: Whether the webhook is active
Example Implementations¶
Node.js Example¶
const express = require('express');
const crypto = require('crypto');
const app = express;
app.use(express.json); // Parse JSON body
app.post('/webhooks', (req, res) => {
console.log('Received webhook:', req.method, req.headers);
const signature = req.headers['x-webhook-signature'];
const secret = 'your-secret-here';
// Verify signature
const hmac = crypto.createHmac('sha256', secret);
hmac.update(JSON.stringify(req.body));
const computedSignature = hmac.digest('hex');
if (signature !== computedSignature) {
return res.status(401).send('Invalid signature');
}
const { event, data } = req.body;
// Handle the event
switch (event) {
case 'contact.created':
console.log('New contact:', data);
break;
case 'deal.stage.changed':
console.log('Deal stage changed:', data);
break;
}
res.status(200).send('OK');
});
Python Example¶
import hmac
import hashlib
from flask import Flask, request
app = Flask(__name__)
@app.route('/webhooks', methods=['POST'])
def webhook:
signature = request.headers.get('X-Webhook-Signature')
secret = b'your-secret-here'
# Verify signature
computed = hmac.new(secret, request.data, hashlib.sha256).hexdigest
if not hmac.compare_digest(computed, signature):
return 'Invalid signature', 401
event = request.json['event']
data = request.json['data']
# Handle event
if event == 'contact.created':
print(f'New contact: {data}')
elif event == 'deal.stage.changed':
print(f'Deal stage changed: {data}')
return 'OK', 200
Webhook Logs¶
All webhook delivery attempts are logged in the webhook_logs table, including:
- Event type and payload
- Response status code
- Response body
- Error messages (if any)
View logs in Settings > Webhooks > Logs
Testing Webhooks¶
You can test your webhook configuration by sending a test event:
This sends a test event to your configured endpoint.
Best Practices¶
- Always verify signatures - Use the HMAC signature to verify webhook authenticity
- Use HTTPS - Never send webhooks over unencrypted connections
- Respond quickly - Your endpoint should respond within 5 seconds
- Idempotent handlers - Webhooks may be retried, handle duplicate events gracefully
- Log deliveries - Keep your own logs of webhook deliveries
- Handle failures - Webhooks are fire-and-forget, but logs show delivery status
Rate Limits¶
Currently, webhooks are sent synchronously. If you have high event volumes, consider: - Batch processing events - Using queueing system - Filtering events you actually need
Troubleshooting¶
Webhooks not being called:
1. Check that webhook is is_active: true
2. Verify the endpoint URL is correct and accessible
3. Check webhook logs for errors
Invalid signature: 1. Ensure you're using the same secret 2. Verify you're computing HMAC-SHA256 correctly 3. Check that request body matches what you're hashing
Events not firing: 1. Verify the event types are subscribed in your webhook config 2. Check that the action triggers the event (e.g., creates/updates records)
Next Steps¶
After deploying this system, you can: 1. Configure webhooks in Settings page 2. Monitor webhook delivery in logs 3. Test with sample events 4. Integrate with external systems
API Reference¶
See the Webhooks Feature guide and Enhanced Payload reference for the complete event catalogue and payload schemas.