Документация
WebhookLens — платформа webhook-инфраструктуры с открытым исходным кодом. Принимайте, инспектируйте, воспроизводите и пересылайте вебхуки с полной видимостью. Разворачивайте самостоятельно бесплатно или используйте управляемое облако.
-
Запустите стек
docker compose up -d— запускает PostgreSQL, ClickHouse, Redis и WebhookLens. -
Откройте панель управления
Перейдите по адресуhttp://localhost:3000. Зарегистрируйтесь, чтобы создать тенант. -
Создайте эндпоинт и отправьте тестовый вебхук
Создайте эндпоинт в панели управления, затем:curl -X POST http://localhost:8080/wh/your-tenant/your-endpoint -H "Content-Type: application/json" -d '{"test": true}'
Требования
Docker (рекомендуется)
- Docker 20+ и Docker Compose v2+
- Минимум 1 CPU, 1 ГБ RAM (рекомендуется 2 CPU, 4 ГБ)
Единый бинарный файл
- Go 1.25+ (для сборки из исходников)
- PostgreSQL 16+
- ClickHouse 24+
- Redis 7+
- Минимум 1 CPU, 1 ГБ RAM (рекомендуется 2 CPU, 4 ГБ)
Установка — Docker Compose
Рекомендуемый способ запуска WebhookLens. Один файл поднимает весь стек: PostgreSQL, ClickHouse, Redis и сервер WebhookLens.
Загрузка и запуск
# Загрузить файл compose для сообщества
curl -fsSL https://raw.githubusercontent.com/webhooklens/webhooklens/main/deploy/docker-compose.community.yml \
-o docker-compose.yml
# Запустить стек
docker compose up -d
Панель управления доступна по адресу http://localhost:3000, прокси вебхуков — по адресу http://localhost:8080.
Полный файл docker-compose.community.yml
# WebhookLens Community Edition — Docker Compose
# Usage: docker compose -f docker-compose.community.yml up -d
# Dashboard: http://localhost:3000
# Proxy: http://localhost:8080
version: '3.8'
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: webhooklens
POSTGRES_PASSWORD: webhooklens
POSTGRES_DB: webhooklens
volumes:
- pg_data:/var/lib/postgresql/data
- ./migrations/postgres:/docker-entrypoint-initdb.d
healthcheck:
test: ["CMD-SHELL", "pg_isready -U webhooklens"]
interval: 5s
retries: 5
clickhouse:
image: clickhouse/clickhouse-server:24-alpine
volumes:
- ch_data:/var/lib/clickhouse
- ./migrations/clickhouse:/docker-entrypoint-initdb.d
healthcheck:
test: ["CMD", "clickhouse-client", "--query", "SELECT 1"]
interval: 5s
retries: 5
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
retries: 5
webhooklens:
image: webhooklens/webhooklens:latest
ports:
- "3000:3000"
- "8080:8080"
environment:
WHL_DATABASE__POSTGRES_URL: postgres://webhooklens:webhooklens@postgres:5432/webhooklens?sslmode=disable
WHL_DATABASE__CLICKHOUSE_URL: clickhouse://clickhouse:9000/webhooklens
WHL_DATABASE__REDIS_URL: redis://redis:6379
WHL_AUTH__JWT_SECRET: change-me-in-production-use-64-chars-minimum
depends_on:
postgres: { condition: service_healthy }
clickhouse: { condition: service_healthy }
redis: { condition: service_healthy }
restart: unless-stopped
volumes:
pg_data:
ch_data:
redis_data:
WHL_AUTH__JWT_SECRET случайной строкой длиной не менее 32 символов в production-среде.
Установка — Единый бинарный файл
Загрузите предсобранный бинарный файл или скомпилируйте из исходников. Требует отдельно запущенных PostgreSQL, ClickHouse и Redis.
Предсобранный бинарный файл
# Загрузить последний релиз
curl -fsSL https://github.com/webhooklens/webhooklens/releases/latest/download/webhooklens-linux-amd64 \
-o webhooklens
chmod +x webhooklens
# Запустить с файлом конфигурации
./webhooklens --config config.yaml
Сборка из исходников
git clone https://github.com/webhooklens/webhooklens.git
cd webhooklens
go build -o webhooklens ./cmd/server
./webhooklens --config config.yaml
Настройка
WebhookLens можно настроить через файл конфигурации YAML или переменные окружения. Переменные окружения используют префикс WHL_ с двойным подчёркиванием для вложенности.
Сервер
| Ключ конфигурации | Переменная окружения | По умолчанию | Описание |
|---|---|---|---|
server.proxy_port | WHL_SERVER__PROXY_PORT | 8080 | Порт для приёма вебхуков |
server.api_port | WHL_SERVER__API_PORT | 3000 | Порт для панели управления и API |
server.debug | WHL_SERVER__DEBUG | false | Включить отладочное логирование |
server.cloud_domain | WHL_SERVER__CLOUD_DOMAIN | "" | Домен облачного режима (мультитенантный SaaS) |
База данных
| Ключ конфигурации | Переменная окружения | По умолчанию | Описание |
|---|---|---|---|
database.postgres_url | WHL_DATABASE__POSTGRES_URL | — | Строка подключения PostgreSQL |
database.clickhouse_url | WHL_DATABASE__CLICKHOUSE_URL | — | Строка подключения ClickHouse |
database.redis_url | WHL_DATABASE__REDIS_URL | — | Строка подключения Redis |
Аутентификация
| Ключ конфигурации | Переменная окружения | По умолчанию | Описание |
|---|---|---|---|
auth.jwt_secret | WHL_AUTH__JWT_SECRET | — | Секретный ключ JWT (минимум 32 символа) |
auth.github_client_id | WHL_AUTH__GITHUB_CLIENT_ID | "" | Client ID GitHub OAuth |
auth.github_secret | WHL_AUTH__GITHUB_SECRET | "" | Секрет GitHub OAuth |
retention.events_days | WHL_RETENTION__EVENTS_DAYS | 30 | Автоудаление событий через N дней |
Ограничение запросов
| Ключ конфигурации | Переменная окружения | По умолчанию | Описание |
|---|---|---|---|
rate_limit.api_per_tenant | WHL_RATE_LIMIT__API_PER_TENANT | 100 | Запросов к API в минуту на тенант |
rate_limit.auth_per_ip | WHL_RATE_LIMIT__AUTH_PER_IP | 10 | Запросов аутентификации в минуту на IP |
Биллинг Stripe
Требуется только в облачном/SaaS-режиме с платными планами.
| Ключ конфигурации | Переменная окружения | По умолчанию | Описание |
|---|---|---|---|
stripe.api_key | WHL_STRIPE__API_KEY | "" | Секретный ключ Stripe |
stripe.price_id | WHL_STRIPE__PRICE_ID | "" | ID тарифа Stripe для подписки |
stripe.webhook_secret | WHL_STRIPE__WEBHOOK_SECRET | "" | Секрет подписи вебхука Stripe |
stripe.base_url | WHL_STRIPE__BASE_URL | "" | Базовый URL для редиректов Stripe Checkout |
Настройте отправку email для сброса пароля и уведомлений. Использует Resend.
| Ключ конфигурации | Переменная окружения | По умолчанию | Описание |
|---|---|---|---|
email.resend_api_key | WHL_EMAIL__RESEND_API_KEY | "" | API-ключ Resend |
email.from_address | WHL_EMAIL__FROM_ADDRESS | noreply@... | Адрес отправителя исходящих писем |
Пример config.yaml
server:
proxy_port: 8080
api_port: 3000
debug: false
database:
postgres_url: "postgres://user:pass@localhost:5432/webhooklens?sslmode=disable"
clickhouse_url: "clickhouse://localhost:9000/webhooklens"
redis_url: "redis://localhost:6379"
auth:
jwt_secret: "ваш-случайный-секрет-минимум-32-символа"
retention:
events_days: 30
rate_limit:
api_per_tenant: 100
auth_per_ip: 10
Прокси Webhook
WebhookLens работает как обратный прокси для ваших вебхуков. Настройте провайдеров на URL прокси — и WebhookLens будет принимать, логировать, валидировать и пересылать каждый запрос на ваш реальный эндпоинт.
Приём вебхуков
URL прокси соответствует шаблону:
POST https://ваш-домен:8080/wh/{tenant-slug}/{endpoint-slug}
При поступлении вебхука WebhookLens:
- Принимает полный HTTP-запрос (метод, заголовки, тело, параметры запроса)
- Сохраняет событие в ClickHouse для аналитики и в PostgreSQL для инспекции
- Проверяет подпись (если провайдер настроен для эндпоинта)
- Применяет трансформации (если настроены)
- Пересылает запрос на настроенный целевой URL
- Записывает код ответа, задержку и возможные ошибки
Политика повторных попыток
Неудавшиеся доставки (ответы 5xx или таймауты) повторяются с экспоненциальной задержкой:
| Попытка | Задержка |
|---|---|
| 1-я попытка | 1 секунда |
| 2-я попытка | 5 секунд |
| 3-я попытка | 30 секунд |
| 4-я попытка | 5 минут |
| 5-я попытка | 30 минут |
После 5 неудачных попыток событие помечается как failed. Вы можете воспроизвести его вручную из панели управления или через API в любое время.
Проверка подписи
Если для эндпоинта настроен провайдер, WebhookLens автоматически проверяет подпись вебхука с использованием алгоритма подписи провайдера. При неудаче проверки событие помечается флагом, но по-прежнему сохраняется и пересылается (если не включён строгий режим).
Пример: проверка подписи Stripe
# При создании эндпоинта укажите провайдера и секрет подписи
curl -X POST http://localhost:3000/api/endpoints \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"slug": "stripe-payments",
"target_url": "https://api.example.com/webhooks/stripe",
"provider": "stripe",
"signing_secret": "whsec_..."
}'
Поддерживаемые провайдеры
WebhookLens поддерживает автоматическую проверку подписи для следующих провайдеров:
| Провайдер | Заголовок подписи | Алгоритм |
|---|---|---|
| Stripe | Stripe-Signature | HMAC-SHA256 (timestamp + payload) |
| GitHub | X-Hub-Signature-256 | HMAC-SHA256 |
| Shopify | X-Shopify-Hmac-SHA256 | HMAC-SHA256 (Base64) |
| Slack | X-Slack-Signature | HMAC-SHA256 (timestamp + body) |
| Twilio | X-Twilio-Signature | HMAC-SHA1 |
| SendGrid | X-Twilio-Email-Event-Webhook-Signature | ECDSA |
| Paddle | Paddle-Signature | HMAC-SHA256 (timestamp + payload) |
| Linear | Linear-Signature | HMAC-SHA256 |
| Svix | svix-signature | HMAC-SHA256 (msg-id + timestamp + body) |
| Clerk | svix-signature | HMAC-SHA256 на основе Svix |
| Intercom | X-Hub-Signature | HMAC-SHA1 |
| Typeform | Typeform-Signature | HMAC-SHA256 |
| Универсальный HMAC | Настраиваемый | HMAC-SHA256 |
Панель управления
События & Инспектор
Страница событий отображает все входящие вебхуки в реальном времени с автообновлением. В каждой строке показано:
- Статус — переслано (зелёный), ошибка (красный), воспроизведено (синий), таймаут (жёлтый)
- Провайдер — определяется автоматически по заголовкам (Stripe, GitHub, Shopify и др.)
- Эндпоинт — какой эндпоинт принял вебхук
- Задержка — время кругового обхода для пересылки и получения ответа
- Временная метка — относительное время («2с назад») с полной ISO-меткой при наведении
Нажмите на событие, чтобы открыть инспектор:
- Вкладка Запрос: заголовки, тело (JSON/XML с подсветкой синтаксиса), параметры запроса
- Вкладка Ответ: статус ответа цели, заголовки, тело
- Вкладка Хронология: полная хронология доставки включая повторные попытки
- Кнопка Воспроизвести: повторно отправить точно тот же запрос на цель
Эндпоинты
Эндпоинты — основная абстракция. Каждый эндпоинт содержит:
- Уникальный slug, являющийся частью URL прокси
- Целевой URL, куда пересылаются вебхуки
- Необязательный провайдер для проверки подписи
- Необязательные трансформации для изменения payload
- Необязательные правила маршрутизации для доставки на несколько целей
Аналитика
Панель аналитики предоставляет метрики в реальном времени на базе ClickHouse:
- Объём — общее количество событий за период (1ч, 24ч, 7д, 30д)
- Процент успеха — доля ответов 2xx
- Задержка — персентили P50, P95, P99
- По провайдерам — объём и успешность по каждому провайдеру
- По эндпоинтам — объём и успешность по каждому эндпоинту
Оповещения
Настройте оповещения, чтобы быть в курсе проблем:
- Порог ошибок — оповещение при превышении частоты ошибок N% за временное окно
- Порог задержки — оповещение при превышении задержки P95 значения N мс
- Отсутствие событий — оповещение при отсутствии событий в течение N минут
Уведомления могут отправляться в Slack (через входящий вебхук) или на произвольный URL вебхука.
# Создать оповещение
curl -X POST http://localhost:3000/api/alerts \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "High failure rate",
"type": "failure_rate",
"threshold": 10,
"window_minutes": 5,
"channel": "slack",
"slack_webhook_url": "https://hooks.slack.com/services/..."
}'
Трансформации & Маршрутизация
Трансформации payload
Трансформации позволяют изменять payload вебхуков перед их пересылкой на цель. Это удобно для обогащения данных, удаления чувствительных полей или адаптации payload к формату вашего API.
Типы трансформаций
| Тип | Описание | Пример |
|---|---|---|
set_field | Установить или перезаписать JSON-поле | Добавить source: "stripe" в тело |
remove_field | Удалить JSON-поле | Удалить data.object.metadata |
rename_field | Переименовать JSON-поле | Переименовать id в external_id |
add_header | Добавить заголовок запроса | Добавить X-Source: webhooklens |
remove_header | Удалить заголовок запроса | Удалить X-Internal-Token |
Пример: добавить поле и заголовок
curl -X PATCH http://localhost:3000/api/endpoints/EP_ID \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"transforms": [
{"type": "set_field", "path": "meta.source", "value": "stripe"},
{"type": "add_header", "key": "X-Source", "value": "webhooklens"},
{"type": "remove_field", "path": "data.object.metadata.internal"}
]
}'
Тестирование без применения (dry-run)
Протестируйте трансформации без реальной пересылки:
curl -X POST http://localhost:3000/api/transforms/test \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"transforms": [
{"type": "set_field", "path": "enriched", "value": true}
],
"payload": {"event": "payment.completed", "amount": 4999}
}'
# Ответ:
# {"event": "payment.completed", "amount": 4999, "enriched": true}
Умная маршрутизация
Направляйте один вебхук на несколько целей по условиям. Это обеспечивает веерную рассылку, условную обработку и резервные цели.
Условия маршрутизации
| Условие | Описание |
|---|---|
all | Всегда пересылать на эту цель (веерная рассылка) |
on_success | Пересылать только если основная цель вернула 2xx |
on_failure | Пересылать только если основная цель вернула не-2xx или произошёл таймаут |
Пример: веерная рассылка на 3 цели
curl -X PATCH http://localhost:3000/api/endpoints/EP_ID \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"target_url": "https://primary.example.com/webhook",
"routes": [
{"url": "https://analytics.example.com/ingest", "condition": "all"},
{"url": "https://backup.example.com/webhook", "condition": "all"},
{"url": "https://alerts.example.com/failure", "condition": "on_failure"}
]
}'
Справочник API
Все API-эндпоинты обслуживаются на порту API (по умолчанию :3000). Для аутентифицированных эндпоинтов требуется Bearer-токен, полученный при входе.
Аутентификация
Создать новый аккаунт и тенант.
curl -X POST http://localhost:3000/api/auth/signup \
-H "Content-Type: application/json" \
-d '{
"email": "вы@пример.com",
"password": "надёжныйпароль",
"tenant_name": "мой-проект"
}'
# Ответ: {"token": "eyJhbG...", "tenant": {"id": "...", "slug": "мой-проект"}}
Аутентификация и получение JWT-токена.
curl -X POST http://localhost:3000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "вы@пример.com", "password": "надёжныйпароль"}'
# Ответ: {"token": "eyJhbG..."}
API Эндпоинтов
Получить список всех эндпоинтов текущего тенанта.
curl http://localhost:3000/api/endpoints \
-H "Authorization: Bearer YOUR_TOKEN"
# Ответ: [{"id": "...", "slug": "stripe-prod", "target_url": "https://...", ...}]
Создать новый эндпоинт.
curl -X POST http://localhost:3000/api/endpoints \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"slug": "stripe-prod",
"target_url": "https://api.example.com/webhooks/stripe",
"provider": "stripe",
"signing_secret": "whsec_..."
}'
Обновить эндпоинт (целевой URL, провайдер, трансформации, маршруты).
curl -X PATCH http://localhost:3000/api/endpoints/EP_ID \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"target_url": "https://новая-цель.example.com/hook"}'
API Событий
Список событий с необязательными фильтрами. Поддерживает пагинацию.
# Список последних событий
curl "http://localhost:3000/api/events?limit=50&status=failed" \
-H "Authorization: Bearer YOUR_TOKEN"
# Фильтр по эндпоинту
curl "http://localhost:3000/api/events?endpoint_id=EP_ID&limit=20" \
-H "Authorization: Bearer YOUR_TOKEN"
Воспроизвести событие — повторно отправить исходный запрос на цель.
curl -X POST http://localhost:3000/api/events/EVT_ID/replay \
-H "Authorization: Bearer YOUR_TOKEN"
# Ответ: {"status": "replayed", "response_code": 200, "latency_ms": 142}
API Аналитики
Получить агрегированную аналитику по тенанту.
curl "http://localhost:3000/api/analytics/overview?period=24h" \
-H "Authorization: Bearer YOUR_TOKEN"
# Ответ:
# {
# "total_events": 12847,
# "success_rate": 99.2,
# "p50_ms": 45,
# "p95_ms": 210,
# "p99_ms": 890,
# "by_provider": [{"provider": "stripe", "count": 8420}, ...],
# "by_status": {"forwarded": 12744, "failed": 62, "replayed": 41}
# }
API Биллинга
Доступен только в облачном режиме.
Получить текущее использование и квоту плана.
curl http://localhost:3000/api/billing/quota \
-H "Authorization: Bearer YOUR_TOKEN"
# Ответ: {"plan": "starter", "events_used": 12847, "events_limit": 50000, ...}
Создать сессию Stripe Checkout для обновления плана.
curl -X POST http://localhost:3000/api/billing/checkout \
-H "Authorization: Bearer YOUR_TOKEN"
# Ответ: {"checkout_url": "https://checkout.stripe.com/..."}
Создать сессию Stripe Billing Portal для управления подписками.
curl -X POST http://localhost:3000/api/billing/portal \
-H "Authorization: Bearer YOUR_TOKEN"
# Ответ: {"portal_url": "https://billing.stripe.com/..."}
Протестировать набор трансформаций без применения на примере payload.
Справочник CLI
Установка
go install github.com/webhooklens/webhooklens/cmd/webhooklens-cli@latest
Команды
Вход
# Аутентификация на сервере WebhookLens
webhooklens-cli login --server https://app.webhooklens.cloud
# Для самостоятельно развёрнутого сервера
webhooklens-cli login --server http://localhost:3000
Прослушивание (локальный туннель)
# Пересылка вебхуков на локальный сервер разработки
webhooklens-cli listen --port 4000
# Указать конкретный эндпоинт
webhooklens-cli listen --port 4000 --endpoint stripe-prod
События
# Список последних событий
webhooklens-cli events list
# Показать детали события
webhooklens-cli events show EVT_ID
# Воспроизвести событие на другой URL
webhooklens-cli events replay EVT_ID --to http://localhost:4000/webhook
| Команда | Описание |
|---|---|
webhooklens-cli login | Аутентификация на сервере |
webhooklens-cli listen | Пересылка вебхуков на локальный порт (туннель для разработки) |
webhooklens-cli events list | Список последних событий |
webhooklens-cli events show <id> | Полные детали события (заголовки, тело, ответ) |
webhooklens-cli events replay <id> | Воспроизвести событие, при необходимости на другой URL |
Руководство по самостоятельному хостингу
Развёртывание в production
Для production-среды мы рекомендуем использовать Caddy для автоматического HTTPS и production-файл Docker Compose.
- Установили надёжный
WHL_AUTH__JWT_SECRET(64+ случайных символа) - Используете выделенные экземпляры PostgreSQL, ClickHouse и Redis (или управляемые сервисы)
- Включили TLS через Caddy или балансировщик нагрузки
- Настроили автоматическое резервное копирование
- Настроили ограничение запросов в соответствии с вашим трафиком
TLS с Caddy
Caddy автоматически выдаёт и обновляет TLS-сертификаты Let's Encrypt.
Caddyfile
# /etc/caddy/Caddyfile
webhooks.example.com {
reverse_proxy localhost:3000
}
proxy.example.com {
reverse_proxy localhost:8080
}
# Запустить Caddy
sudo caddy run --config /etc/caddy/Caddyfile
Резервное копирование & Восстановление
Регулярно создавайте резервные копии PostgreSQL (основные данные). Данные ClickHouse при необходимости можно восстановить из событий.
Скрипт резервного копирования
#!/bin/bash
# backup-webhooklens.sh
BACKUP_DIR="/backups/webhooklens"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# Резервная копия PostgreSQL
docker exec webhooklens-postgres-1 \
pg_dump -U webhooklens webhooklens | \
gzip > "${BACKUP_DIR}/pg_${TIMESTAMP}.sql.gz"
# Хранить последние 30 резервных копий
ls -t "${BACKUP_DIR}"/pg_*.sql.gz | tail -n +31 | xargs rm -f
echo "Backup completed: pg_${TIMESTAMP}.sql.gz"
Расписание cron
# Запускать ежедневно в 2:00
0 2 * * * /opt/webhooklens/backup-webhooklens.sh >> /var/log/webhooklens-backup.log 2>&1
Восстановление
# Восстановить из резервной копии
gunzip -c "/backups/webhooklens/pg_20260411_020000.sql.gz" | \
docker exec -i webhooklens-postgres-1 \
psql -U webhooklens webhooklens
Мониторинг
WebhookLens предоставляет эндпоинт проверки работоспособности для мониторинга доступности:
curl http://localhost:3000/healthz
# Ответ (работает нормально):
# {"status": "ok", "postgres": "ok", "clickhouse": "ok", "redis": "ok"}
# Ответ (деградация):
# {"status": "degraded", "postgres": "ok", "clickhouse": "error", "redis": "ok"}
Используйте этот эндпоинт со своей системой мониторинга (UptimeRobot, Datadog, Prometheus blackbox exporter и др.), чтобы получать оповещения при неработоспособности компонентов.
/metrics на порту API. Используйте их для детального мониторинга пропускной способности, задержки и частоты ошибок в Grafana.
Нужна помощь? Откройте задачу на GitHub или напишите нам на support@webhooklens.cloud.