Webhooks Overview
Let us know how we can improve our documentation:
By using webhooks, you can tightly integrate your server application with Stream Chat. The platform supports three kinds of webhooks: Push, Before-Message-Send, and Custom Commands. All of them follow the common set of rules:
-
Webhook should be reachable from the public internet. Tunneling services like Ngrok are supported
-
Webhook should accept HTTP POST requests with JSON payload
-
Webhook should respond with response codes from 200 to 299
-
Webhook should respond as fast as possible. The exact time given for the response varies between webhook types
-
Webhook should be ready to accept the same call multiple times: in case of network or remote server failure Stream Chat could retry the request (behavior varies between webhook types)
All webhook requests contain these headers:
Name | Description | Example |
---|---|---|
X-Webhook-Id | Unique ID of the webhook call. This value in consistent between retries and could be used to deduplicate retry calls | 123e4567-e89b-12d3-a456-426614174000 |
X-Webhook-Attempt | Number of webhook request attempt starting from 1 | 1 |
X-Api-Key | Your application’s API key. Should be used to validate request signature | a1b23cdefgh4 |
X-Signature | HMAC signature of the request body. See Signature section | ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb |
Security and Performance
We highly recommend following common security guidelines to make you webhook integration safe and blazing fast:
-
Use HTTPS with a certificate from a trusted authority (eg. Let's Encrypt)
-
Verify the "X-Signature" header
-
Support HTTP Keep-Alive
-
Be highly available
-
Offload the processing of the message if possible (read, store, and forget)
Webhook types
Stream Chat supports several webhook types:
Type | Description |
---|---|
Push | Push webhook is useful when you want your server application to receive all important events happening in the Stream Chat |
Before Message Send | This webhook allows you to modify or moderate message content before sending it to the chat for everyone to see |
Custom Commands | This webhook reacts to custom /slash commands |
Signature
All HTTP requests can be verified as coming from Stream (and not tampered by a 3rd party) by analyzing the signature attached to the request. Every request includes an HTTP header called "X-Signature" containing a cryptographic signature of the message. Your webhook endpoint can validate that payload and signature match:
// first argument is the request body as a string, second the signature header
const valid = client.verifyWebhook(req.rawBody, req.headers['x-signature']);
import stream_chat
client = StreamChat(api_key="STREAM_KEY", api_secret="STREAM_SECRET")
# Django request
valid = client.verify_webhook(request.body, request.META['HTTP_X_SIGNATURE'])
# Flask request
valid = client.verify_webhook(request.data, request.headers['X-SIGNATURE'])
require 'stream-chat'
client = StreamChat::Client.new(api_key='STREAM_KEY', api_secret='STREAM_SECRET')
// signature comes from the HTTP header x-signature
valid = client.verify_webhook(request_body, signature)
$client = new GetStream\StreamChat\Client("STREAM_API_KEY", "STREAM_API_SECRET");
// signature comes from the HTTP header x-signature
$valid = $client->verifyWebhook($requestBody, $signature);
client, _ := stream.NewClient(APIKey, []byte(APISecret))
// signature comes from the HTTP header x-signature
isValid := client.VerifyWebhook(body, signature)
using StreamChat;
var client = new Client("API KEY", "API SECRET");
// signature comes from the HTTP header x-signature
client.VerifyWebhook(requestBody, signature);
Configuration
You can configure your webhook endpoints in the Stream Chat Dashboard or by using server-side SDK client:
// update webhook URLs
await client.updateAppSettings({
webhook_url: "https://example.com/webhooks/stream/push", // sets Push webhook address
before_message_send_hook_url: "https://example.com/webhooks/stream/before-message-send", // sets Before Message Send webhook address
custom_action_handler_url: "https://example.com/webhooks/stream/custom-commands?type={type}", // sets Custom Commands webhook address
});
Also, webhooks could be configured using our CLI client:
stream chat:webhook:push --url 'https://example.com/webhooks/stream/push'
stream chat:webhook:before-message-send --url 'https://example.com/webhooks/stream/before-message-send'
stream chat:webhook:custom-commands --url 'https://example.com/webhooks/stream/custom-commands?type={type}'