Як надійно отримувати вебхуки Twilio
Тут ідеться про інформаційні вебхуки Twilio, як-от status callbacks повідомлень. Twilio надсилає їх на джерело Railhook, а воно перевіряє підпис, зберігає кожен таким, яким той надійшов, і пересилає у ваш сервіс із повторними спробами.
Чому вебхукам Twilio потрібен буфер
Section titled “Чому вебхукам Twilio потрібен буфер”Типово Twilio чекає 5 секунд на з’єднання й 15 секунд на відповідь і повторює вебхук лише один раз, і тільки тоді, коли не вдалося встановити саме з’єднання. Після 5xx від вашого застосунку чи повільної відповіді повторної спроби не буде, якщо не додати до URL параметри connection overrides. (Twilio: Webhooks connection overrides)
Status callback, що надійшов під час перезапуску застосунку, зазвичай губиться, і ваші дані про доставку розходяться з даними Twilio. Коли попереду стоїть Railhook:
- Railhook відповідає Twilio, щойно збереже callback.
- Ваш сервіс отримує до 5 спроб на кожне пересилання з інтервалами від 1 хвилини до 1 години, а те, що так і не вдалося доставити, потрапляє в «Недоставлені пересилання».
- На callback з
I-Twilio-Idempotency-Token, який Railhook уже зберіг, він відповідає збереженою копією і вдруге його не пересилає.
Підключення Twilio
Section titled “Підключення Twilio”Знадобляться проєкт Railhook і API-ключ. Ті самі кроки є в панелі керування, у розділі «Вхідні».
export RAILHOOK_URL=https://railhook.io # or your own instanceexport RAILHOOK_API_KEY=...export PROJECT_ID=...-
Створіть джерело з вашим Auth Token із Twilio Console. Саме ним Twilio підписує свої запити:
Terminal window curl -X POST "$RAILHOOK_URL/api/v1/projects/$PROJECT_ID/incoming-sources" \-H "X-API-Key: $RAILHOOK_API_KEY" \-H "Content-Type: application/json" \-d '{"name":"Twilio","providerType":"TWILIO","verificationMode":"PROVIDER","hmacSecret":"'"$TWILIO_AUTH_TOKEN"'"}'Збережіть
idіingressUrlіз відповіді. -
Додайте призначення, URL вашого сервісу:
Terminal window curl -X POST "$RAILHOOK_URL/api/v1/projects/$PROJECT_ID/incoming-sources/$SOURCE_ID/destinations" \-H "X-API-Key: $RAILHOOK_API_KEY" \-H "Content-Type: application/json" \-d '{"url":"https://api.example.com/webhooks/twilio","authType":"BEARER","authConfig":"{\"token\":\"...\"}","enabled":true}' -
Передайте URL у Twilio. Указуйте
ingressUrlточно в тому вигляді, в якому його показує джерело, скрізь, де Twilio приймає URL для status callback, наприклад у параметріStatusCallbackпід час надсилання повідомлення. Метод залиштеPOST: інших ingress не приймає. -
Надішліть повідомлення. Його status callbacks з’являться в розділі «Вхідні» → «Отримані» з одним пересиланням на кожне призначення.
Як перевіряється підпис
Section titled “Як перевіряється підпис”X-Twilio-Signature є HMAC-SHA1 у Base64, обчисленим з Auth Token. Для запиту у форматі form-encoded підписано URL, а за ним усі параметри, відсортовані за назвою; для інших запитів лише URL, а параметр рядка запиту bodySHA256 має відповідати тілу. На запит, що не збігається, Railhook відповідає 401 і не зберігає його.
Що отримує ваш сервіс
Section titled “Що отримує ваш сервіс”Тіло точно таке, яким його надіслав Twilio, байт у байт, з оригінальним form-encoded Content-Type, тож ваш сервіс розбирає його так само, як callback напряму від Twilio. X-Twilio-Signature не пересилається (з вашим URL він однаково не пройшов би перевірку): натомість ваш сервіс автентифікує Railhook за обліковими даними призначення. Див. Призначення.
Локальна розробка з CLI
Section titled “Локальна розробка з CLI”-
Встановіть CLI й увійдіть, як описано в CLI, а потім відкрийте тунель до порту вашого застосунку:
Terminal window railhook listen 3000 -
Додайте джерелу друге призначення: публічну адресу, яку вивела команда, з вашим маршрутом у кінці, наприклад
https://<host>/tunnel/<slug>/webhooks/twilio. Запит потрапить наhttp://localhost:3000/webhooks/twilio. -
Надішліть тестове повідомлення, указавши ingress-адресу як status callback, і кожен callback надійде у ваш локальний застосунок. Коли закриєте тунель, вимкніть це призначення.
Відтворення після збою
Section titled “Відтворення після збою”Кожен відтворений callback піде на кожне призначення джерела як нове пересилання:
curl -X POST "$RAILHOOK_URL/api/v1/projects/$PROJECT_ID/incoming-events/bulk-replay" \ -H "X-API-Key: $RAILHOOK_API_KEY" \ -H "Content-Type: application/json" \ -d '{"sourceId":"'"$SOURCE_ID"'","from":"2026-09-18T10:00:00Z","to":"2026-09-18T14:00:00Z","verified":true}'Відтворити можна все, що ще зберігається: 7 днів у Railhook Cloud і скільки налаштуєте на власному сервері. Status callback описує стан, тож переконайтеся, що обробник може застосувати той самий callback двічі без шкоди. Див. Відтворення.