By using webhooks, you can receive all events within your application. When configured, every event happening on Stream Chat will propagate to your webhook endpoint via an HTTP POST request.
Webhooks can help you migrate from a different chat provider to Stream without disruption, or to support complex notification mechanisms (e.g. sending an SMS to an offline user when a direct message is sent, etc.).
In order to use webhooks, the endpoint responding to the webhook event must:
- Be reachable from public internet, tunneling services like Ngrok are supported
- Respond with a 200 HTTP code in less than 3 seconds
- Handle HTTP requests with POST body
- Able to parse JSON payloads
- Support HTTP/1.1
While not required, we recommend following these best-practices for production environments:
- Use HTTPS with a certificate from a trusted authority (eg. Let's Encrypt)
- Verify the "x-signature" header
- Support Keep-Alive
- Be highly available
- Offload the processing of the message (read, store, and forget)
Configuration via CLI
stream chat:push:webhook --url 'https://acme.com/my/awesome/webhook/handler/'
Verify Events via X-Signature and X-Api-Key
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 = stream_chat.connect('API_KEY', 'API_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);
// at the moment we don't have a Java client for server side usage
client, _ := stream.NewClient(APIKey, byte(APISecret)) // signature comes from the HTTP header x-signature isValid := client.VerifyWebhook(body, signature)
// at the moment we don't have a Swift client for server side usage
using StreamChat; var client = new Client("API KEY", "API SECRET"); // signature comes from the HTTP header x-signature client.VerifyWebhook(requestBody, signature);