Skip to main content
This script is an HTTP server that receives the deliveries of a webhook subscription. It verifies each request, skips the events it has already processed, and handles two message events. Use it as the starting point of your own endpoint. Webhooks describes the functions it uses.
The script processes the real events of your account. Message events carry the handles and the text of real messages.

The script

handle-webhooks.ts

Run it

Install the SDK, and typescript and @types/node as development dependencies. Set "type": "module" in the package.json of the project, then save the script as handle-webhooks.ts with the tsconfig.json of the overview.
1

Expose the server

The script listens on port 3000 over plain HTTP. A webhook subscription needs a public https:// URL: put a proxy that terminates TLS in front of the server. Webhooks overview lists what an endpoint must do.
2

Create a webhook subscription

Create a subscription for https://<your host>/webhooks/isnap with POST /v1/webhooks, or with client.webhooks.create. The response carries the signing secret: store it in ISNAP_WEBHOOK_SECRET. The API returns the secret at creation and at rotation only.
3

Start the server

Set ISNAP_WEBHOOK_SECRET in the environment, then start the script with one of the commands below.
To check the verification before you subscribe, run the tests of Test your verification. Do not send the test vector to this server: its timestamp is in the past, so the server refuses it with 400.

What it does

Ignore response fields, enum values and event types you do not know. The script acknowledges them with 200. Events do not announce every change: see What events do not announce, and reconcile from the resource operations.

Errors it handles

Never respond 410: it makes the subscription inactive. Retries gives the schedule of the attempts, and Suspension says what repeated failures do to a subscription.

Before production

  • Deduplication. Deduplicate on event_id. Replace the in-memory set with storage that your processes share and that survives a restart, with a unique constraint on the event id. See Duplicates.
  • Order. Delivery order is not guaranteed. Order events by the timestamps inside data, not by arrival.
  • Secret. Keep the signing secret in a secret manager. The script stops when ISNAP_WEBHOOK_SECRET is not set: keep that check.
  • Personal data. The script prints message ids and line ids only. Do not copy a handle or a message text into logs, tickets or other tools, and refer to a contact by an id of your own.