Frequently Asked Questions
Set up a NestJS controller to receive POST requests at a dedicated webhook endpoint (/webhook), validate the HMAC signature using a shared secret, and process the callback data asynchronously. Ensure your controller sends a 200 OK response to Sinch immediately after validation to acknowledge receipt and prevent retries. Background processing allows your application to handle callback data without impacting response time.
The Sinch Conversation API provides messaging capabilities and uses webhooks for real-time notifications. Instead of inefficient polling, webhooks deliver near real-time updates about message status and user replies, allowing for responsive communication flows. This guide focuses on MESSAGE_DELIVERY
and MESSAGE_INBOUND
callbacks.
Webhooks enable real-time communication from Sinch to your application, eliminating the need for continuous polling. This method is far more efficient and ensures your application receives timely updates on message deliveries, inbound messages, and other events, enabling you to build more responsive applications.
ngrok is essential during local development to create a publicly accessible URL for your webhook endpoint. Since Sinch needs to send callbacks to a public URL, ngrok acts as a tunnel, enabling local testing before deployment. In production, use your server's public HTTPS URL.
Yes, you can use the Sinch Webhook Management API to create or modify webhooks programmatically. This is an alternative to using the Sinch Portal UI, and requires using API credentials (like a Service Plan ID and API Token) to generate a valid access token. The specific API endpoint varies depending on your Sinch account region (e.g., eu, us, apse).
Retrieve the timestamp, nonce, algorithm, and signature from the x-sinch-webhook-signature-* headers. Combine the raw request body, nonce, and timestamp to create the signed data string. Calculate the HMAC-SHA256 signature of this string using your webhook secret and compare it with the received signature using a timing-safe comparison method like crypto.timingSafeEqual.
The SINCH_WEBHOOK_SECRET
is a shared secret between your application and Sinch, crucial for verifying the authenticity of incoming webhooks. It's used to generate and validate HMAC signatures, ensuring that callbacks originate from Sinch and haven't been tampered with. This secret should never be hardcoded and must be kept confidential.
Use a tool like ngrok to create a secure tunnel to your locally running NestJS server. Start your NestJS application and run 'ngrok http <port>', replacing <port> with the port your server is listening on (3000 by default). ngrok will provide a public HTTPS URL that Sinch can use to reach your webhook endpoint.
Sinch offers various webhook triggers including MESSAGE_DELIVERY
for delivery receipts, MESSAGE_INBOUND
for user replies, EVENT_INBOUND
for events like composing indicators or read receipts, and CONTACT_CREATE_NOTIFICATION
for new contact creations. You can select the triggers relevant to your application's needs in the Sinch portal or via the API.
After validating the signature, parse the raw request body as JSON. Inspect the payload structure to determine the callback type and route it to the appropriate handler function. Sinch uses different top-level keys for various events, like message_delivery_report, message, and event. Asynchronous processing is recommended for handling data without delaying the 200 OK response to Sinch.
Sinch requires a 200 OK response (or any 2xx code) promptly after receiving a webhook. This confirms successful delivery to your endpoint. Without a 200 OK, Sinch assumes failure and will retry the webhook according to its retry policy, potentially leading to duplicate processing of the same event.
Double-check the webhook URL in the Sinch portal, verify your server's firewall settings, inspect Sinch portal logs for delivery errors, and ensure you have selected the appropriate triggers in the Sinch configuration. Check your ngrok connection if developing locally and ensure the URL you provided is still active. Any misconfiguration in the URL, secret, or triggers can prevent callbacks from being received or processed correctly.
Content Loading Error
We encountered an error while processing this content.