Serverless-обработка вебхуков на вашем домене
Проверяйте подписи вебхуков, подтверждайте в лимите провайдера и продолжайте тяжёлую работу в serverless-функциях, задачах или пайплайнах на своём домене. Стабильные URL, сырые тела для подписи, затем асинхронная передача.
Обновлено: 2026-04-20
Кратко
Суть ответа
Serverless-обработка вебхуков на вашем домене. Функция на провайдера (или тип события) — узкая логика проверки в serverless-хендлере. Не смешиваете cookie пользователя с машинными ключами.
Когда подходит и когда нет
- Нужен стабильный HTTPS-вход и serverless-процессор вебхуков на своём домене (шлюз и DNS под вашим контролем).
- Хочется развести трафик вебхуков и пользовательские API.
На что обратить внимание
- Один общий endpoint смешивает аутентификацию людей и машин — хуже наблюдаемость.
- Встроенные хендлеры в основном API смешивают масштабирование того, что хотелось развести.
Ситуация: нагрузка и где обычно ломается
Проблемы с хендлерами вебхуков
SaaS щедро повторяет доставку. Если хендлер тридцать секунд пишет в базу до ответа — таймауты, дубликаты и ночные звонки.
Пропуск проверки подписи «только на стейдже» или забытая идемпотентность хороши ровно до двух одинаковых событий с двумя списаниями.
Компромиссы
Почему ломается встроенная обработка вебхуков
Один общий endpoint смешивает аутентификацию людей и машин — хуже наблюдаемость.
Встроенные хендлеры в основном API смешивают масштабирование того, что хотелось развести.
Как Inquir помогает в этом сценарии
Serverless-обработка вебхуков в Inquir
Функция на провайдера (или тип события) — узкая логика проверки в serverless-хендлере. Не смешиваете cookie пользователя с машинными ключами.
Маршруты задаются явно: безопасность видит URL, ожидаемые ключи и отличие от публичных API.
Что вы получаете на платформе
Возможности обработки вебхуков
Изолированные маршруты вебхуков
Пути провайдера — на небольшие хендлеры с узкими правами.
Трассировка выполнения
Тела (при необходимости сокращённые) и время, когда провайдер ставит доставку на паузу.
Передача в пайплайны
Быстрый ответ 200, тяжёлое — в пайплайн или задачу, если окна HTTP не хватает.
Что сделать дальше, по шагам
Как обрабатывать вебхуки на своём домене
Проверка подписи в serverless-хендлерах, быстрое подтверждение в лимите провайдера, идемпотентные записи.
Проверить
Подпись и разбор события с защитой.
Подтвердить или отложить
Отвечайте быстро; тяжёлое — в очередь.
Применить
Пишите в хранилище идемпотентно по идентификатору события у провайдера.
Пример кода
Паттерны для конкретных провайдеров
Шлюз отдаёт событие в духе AWS API Gateway: body строкой, заголовки как пришли. Держите по одной функции на провайдера — так верификация подписи остаётся компактной.
export async function handler(event) { const rawBody = event.body ?? ''; // Stripe signs raw bytes — never parse before verifying if (!stripe.webhooks.verifySignature(rawBody, event.headers['stripe-signature'], process.env.STRIPE_WEBHOOK_SECRET)) { return { statusCode: 400, body: 'invalid signature' }; } const evt = JSON.parse(rawBody); // Store evt.id before side effects to guard against duplicate delivery await db.upsertWebhookEvent(evt.id, evt.type); await enqueueFulfillment(evt.id, evt.type, evt.data.object); return { statusCode: 200, body: 'ok' }; }
import { createHmac, timingSafeEqual } from 'node:crypto'; export async function handler(event) { const body = event.body ?? ''; const sigHeader = (event.headers['x-hub-signature-256'] ?? '').replace('sha256=', ''); const expected = createHmac('sha256', process.env.GITHUB_WEBHOOK_SECRET).update(body).digest('hex'); if (!timingSafeEqual(Buffer.from(sigHeader, 'hex'), Buffer.from(expected, 'hex'))) { return { statusCode: 401, body: 'invalid signature' }; } const eventType = event.headers['x-github-event']; const payload = JSON.parse(body); if (eventType === 'push') await enqueueIndexing(payload.repository.full_name, payload.after); else if (eventType === 'pull_request') await enqueuePrWork(payload); return { statusCode: 200, body: 'accepted' }; }
export async function handler(event) { const params = new URLSearchParams(event.body ?? ''); // Slack slash commands must respond within 3 seconds — // kick off the slow work in a pipeline job, return immediately await enqueueSlackWork({ command: params.get('command'), userId: params.get('user_id'), channelId: params.get('channel_id'), text: params.get('text'), responseUrl: params.get('response_url'), }); return { statusCode: 200, body: '' }; }
Когда подходит и когда нет
Когда свой HTTPS-домен и serverless-обработка вебхуков на Inquir — разумный выбор
Когда это уместно
- Нужен стабильный HTTPS-вход и serverless-процессор вебхуков на своём домене (шлюз и DNS под вашим контролем).
- Хочется развести трафик вебхуков и пользовательские API.
Когда лучше не трогать
- Вебхуки уходят только в чужую интеграционную платформу без своей среды выполнения.
Вопросы и ответы
Вопросы и ответы
Медленный downstream?
Быстрое подтверждение, затем продолжение в serverless-пайплайне или задаче — чтобы таймауты провайдера не блокировали эффекты.
Маршруты по клиенту?
См. мультитенантную маршрутизацию: сегментация путей или хостов.
Повторные запросы?
Подпись, метка времени где есть, идемпотентные записи по идентификатору провайдера.