Надійне приймання вебхуків GitHub
Цей гайд ставить Railhook між GitHub і вашим застосунком. GitHub надсилає вебхуки на джерело Railhook, яке перевіряє підпис, зберігає кожну доставку в тому вигляді, в якому вона надійшла, і пересилає її на ваш сервіс із повторами. Коли ваш сервіс недоступний, вебхуки чекають у Railhook, а не губляться.
Чому вебхукам GitHub потрібен буфер
Section titled “Чому вебхукам GitHub потрібен буфер”GitHub зазначає, що не доставляє невдалі вебхуки повторно автоматично. Їх можна доставити повторно вручну або через API, але лише доставки за останні 3 дні. (GitHub: Handling failed webhook deliveries, Redelivering webhooks) Також GitHub просить ваш сервер відповісти 2xx протягом 10 секунд. (Best practices for using webhooks)
Тож один деплой, одне падіння чи один повільний обробник у невдалий момент — і ця подія push, pull request чи issue зникла, якщо ніхто не помітив. З Railhook попереду:
- Railhook відповідає GitHub, щойно доставку збережено, з великим запасом до 10 секунд.
- Ваш сервіс отримує до 5 спроб на кожне пересилання, з очікуваннями від 1 хвилини до 1 години.
- Те, що все одно не вдалося, потрапляє в «Невдалі пересилання», а будь-яку збережену доставку можна відтворити, доки зберігаються події.
- Повторна доставка від GitHub має той самий ідентифікатор
X-GitHub-Delivery. Railhook його розпізнає, відповідає202зі збереженою копією й не пересилає її вдруге.
Підключення GitHub
Section titled “Підключення GitHub”Знадобляться проєкт Railhook і API-ключ. Усе нижче також можна зробити в розділі Вхідні панелі керування.
export RAILHOOK_URL=https://railhook.io # or your own instanceexport RAILHOOK_API_KEY=...export PROJECT_ID=...-
Оберіть секрет. Для GitHub секрет вебхука ви обираєте самі:
Terminal window export GITHUB_WEBHOOK_SECRET=$(openssl rand -hex 32) -
Створіть джерело з цим секретом:
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":"GitHub","providerType":"GITHUB","verificationMode":"PROVIDER","hmacSecret":"'"$GITHUB_WEBHOOK_SECRET"'"}'Збережіть
idіingressUrlіз відповіді. -
Зареєструйте вебхук у GitHub. У репозиторії чи організації відкрийте Settings → Webhooks → Add webhook. Вставте
ingressUrlяк Payload URL, задайте Content typeapplication/json, вставте той самий секрет у Secret і оберіть потрібні події. -
Додайте призначення — адресу вашого сервісу:
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/github","authType":"BEARER","authConfig":"{\"token\":\"...\"}","enabled":true}' -
Перевірте ping. Під час створення вебхука GitHub надсилає подію
ping. Вона з’явиться в розділі Вхідні → Отримані в Railhook.
Як перевіряється підпис
Section titled “Як перевіряється підпис”Railhook читає X-Hub-Signature-256 — це sha256=, за яким іде шістнадцятковий HMAC-SHA256 від сирого тіла, — і порівнює з власним обчисленням на секреті джерела. Запит, що не збігається, отримує 401 і не зберігається. Підпис, уже побачений у межах вікна повторів (типово 5 хвилин), теж відхиляється, якщо тільки запит не є повторною доставкою вже збереженої в Railhook доставки.
Що отримує ваш сервіс
Section titled “Що отримує ваш сервіс”Тіло точно таке, яким його надіслав GitHub, байт у байт. Оскільки push і issue не розрізнити за тілом, Railhook передає далі заголовки подій GitHub: X-GitHub-Event, X-GitHub-Delivery, X-GitHub-Hook-ID, X-GitHub-Hook-Installation-Target-Type і X-GitHub-Hook-Installation-Target-ID. X-Hub-Signature-256 не пересилається: ваш сервіс автентифікує Railhook за обліковими даними призначення, і секрет GitHub йому не потрібен. Див. Призначення.
Локальна розробка з CLI
Section titled “Локальна розробка з CLI”-
Встановіть CLI й увійдіть, як описано в CLI, а потім відкрийте тунель до порту вашого застосунку:
Terminal window railhook listen 3000 -
Додайте джерелу друге призначення з виведеною публічною адресою й вашим маршрутом у кінці, наприклад
https://<host>/tunnel/<slug>/webhooks/github. Запит потрапить наhttp://localhost:3000/webhooks/github. -
Зробіть push або відтворіть збережений
pingу Railhook (повторна доставка від GitHub має той самийX-GitHub-Delivery, тож Railhook відповідає на неї збереженою копією й не пересилає вдруге). Перевірений вебхук надійде у ваш локальний застосунок із заголовкомX-GitHub-Event. Вимкніть це призначення, коли закриєте тунель.
Повтор подій після збою
Section titled “Повтор подій після збою”Відтворіть те, що надійшло, поки ваш сервіс лежав. Кожна відтворена доставка йде на кожне призначення джерела як нове пересилання:
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}'На відміну від повторної доставки в самому GitHub, це не обмежено 3 днями: повтор сягає так далеко, як довго зберігаються події, — 7 днів у Railhook Cloud і скільки налаштуєте на власному сервері. Зробіть обробник ідемпотентним за X-GitHub-Delivery, бо повтор може надіслати доставки, які ваш сервіс уже обробив. Див. Повтор.