Перейти к содержимому
Последнее обновление

Каналы уведомлений

События описывают, что произошло в сети; каналы определяют, куда уйдёт оповещение. Подписка выбирает подходящую активность, ждёт выполнения условия отправки (trigger) и отправляет уведомление через привязанный к ней канал. Доступны два вида, и у них общий жизненный цикл.

Webhook + Telegram Подписанные доставки Единый жизненный цикл История уведомлений

Для создания, изменения и проверки каналов нужен ключ проекта с api:channel:write, для удаления - api:channel:delete, для чтения каналов и истории - api:channel:read. На каждое изменение сохраняйте отдельный Idempotency-Key и исходные входные данные; после потери ответа повторяйте их без изменений. См. Идемпотентность.

Выберите канал

Webhook - HTTP-уведомление: Vilna отправляет JSON на ваш обработчик для автоматической обработки; канал Telegram шлёт форматированное сообщение в чат для людей. В продакшене обычно работают оба - один действует, другой наблюдает.

webhookдля систем

HTTP POST с телом WebhookV2Payload и подписью для проверки подлинности.

Доставка

HTTP POST на ваш эндпоинт

Формат

JSON (WebhookV2Payload)

Для чего

Автоматические системы и бэкенды

Настройка

URL + опциональные заголовки

Пример доставки
POST/webhooks/vilna
X-Webhook-Signaturet=1793059200,v1=…
{ event_id, item, references }
200 OK 142 ms
telegramдля людей

Форматированное сообщение бота в группе, канале или личке - читается с одного взгляда.

Доставка

Сообщение бота в чат

Формат

Форматированный текст

Для чего

Мониторинг и оповещение людей

Настройка

Токен бота + chat_id

Пример уведомления
Vilnaбот
Депозит подтверждён: +1,500 USDT в 0x8ba1…c400
12:48

Webhook-каналы

Webhook-канал отправляет HTTP POST с JSON-телом на ваш эндпоинт, когда выполняется условие привязанной подписки. Создайте его через POST /channels.

В конфигурации выберите kind: webhook, задайте URL получателя и при необходимости отдельные заголовки. Явно выберите payload_version: v2 для структурированных событий; версия тела уведомления выбирается независимо от версии HTTP API. Схемы запроса, ответа и примеры на языках доступны на странице создания канала выше.

Заголовки хранятся и возвращаются без маскировки читателям канала с доступом. Если получателю нужна аутентификация, используйте отдельные учётные данные получателя и ограничьте чтение канала. Не помещайте туда API-ключ Vilna. Также проверяйте webhook-подпись.

Сохраните webhook-секрет

Сохраните webhook_secret из ответа создания в менеджере секретов. Повтор создания с тем же ключом и телом может восстановить его в течение 60 секунд после завершения, при текущем доступе и только пока секрет текущий. Повторы не продлевают окно; поздний GET возвращает метаданные, а не открытый секрет. При потере секрета восстановите или явно смените его. Им проверяют X-Webhook-Signature; учётные данные получателя и токен бота Telegram отличаются от API-ключа Vilna.

Перенаправляйте куда угодно

Webhook - это обычный HTTP POST, поэтому один канал может разветвиться куда нужно вашей архитектуре. Направьте URL на тонкий прокси и раздавайте оттуда:

Ваш вебхукPOST /webhooks/vilnaодно подписанное HTTP-уведомление
База данных

сохранение исходного тела уведомления

Очередь сообщений

SQS, RabbitMQ, Pub/Sub

Slack / Discord

оповещения для людей

PagerDuty

эскалация крупных событий

Свой бэкенд

любой HTTP-эндпоинт

По конкретной интеграции пишите на support@vilna.io.

Telegram-каналы

Telegram-канал шлёт форматированные сообщения в чат через Bot API. Сначала настройте бота, затем создайте канал:

Создайте бота через @BotFather и сохраните токен бота.

Добавьте бота в нужный чат - группу, канал или личные сообщения.

Получите chat ID через @userinfobot или Telegram API getUpdates.

Создайте канал через Создание канала с kind: telegram, токеном бота и chat_id. Выберите язык сообщений; для темы форума задайте thread_id, иначе оставьте 0. Схема конфигурации и примеры запросов находятся на странице операции.

Единый жизненный цикл для всех каналов

Оба вида проходят один и тот же цикл из пяти шагов. Отличается только config - эндпоинты одинаковы.

01Создать

Задайте имя и конфигурацию: Создание канала.

POST /channels
02Проверить

Отправьте тестовое уведомление: Проверка канала.

POST /channels/{id}/actions/test
03Использовать

С ключом, имеющим api:subscription:write, создайте подписку на этот канал. Она определяет, какие транзакции вызывают уведомления.

доставка
04Обновить

Переименуйте или смените конфигурацию: Изменение канала.

PATCH /channels/{id}
05Удалить

Удалите канал навсегда: Удаление канала.

DELETE /channels/{id}

Когда канал отключается сам

max_attempts (1-10) ограничивает автоматические попытки доставки одного уведомления, считая первую. Неудачные попытки повторяются по фиксированному расписанию с растущей задержкой; десять попыток растягиваются примерно на сутки. Когда бюджет исчерпан, канал отключается с disabled_reason: attempts_exhausted. Адресат, чью непригодность сервис подтвердил, отключает канал сразу с channel_error. Переключателя «держать канал включённым несмотря ни на что» нет; настройка - это бюджет попыток.

Отключение канала, автоматическое или ручное, отменяет все уведомления, которые его ещё ждали: они завершаются со status: canceled и reason: channel_disabled. Повторное включение принимает только новые транзакции, а не отменённый остаток. Ручная повторная отправка и тест в бюджет не входят.

Поднять бюджет можно через PATCH /channels/{channel_id}. Ни повышение бюджета, ни починка адресата сами по себе отключённый канал не включают; is_enabled задаётся явно, можно в том же запросе.

Чтобы обнаружить отключение канала, опрашивайте GET /channels и следите за is_enabled: false, либо запрашивайте GET /notifications со status=canceled и идентификатором канала, чтобы увидеть, что было отменено и почему.

Изменение URL или заголовков вебхука либо чата Telegram отменяет автоматические повторы доставок, у которых уже была хотя бы одна попытка; ротация секрета подписи вебхука на это не влияет.

Как защитить платёжный поток

Отключённый канал не теряет депозит. Транзакция, строки активности и баланс записываются независимо от того, ушло ли уведомление; отменяется только доставка. Три привычки сводят разрыв к минимуму:

Поставьте max_attempts: 10 на каналы мониторинга платежей. Это примерно сутки автоматических повторов, прежде чем канал сдастся.

Создайте вторую подписку с теми же фильтрами на второй канал, например чат Telegram или ещё один вебхук. Подписка привязана к одному каналу, поэтому отключение одного не мешает второму доставлять.

После включения сверьте отменённые уведомления и движения средств за время простоя.

Для сверки требуется api:activity:read:

  1. Получите chain_gid и txid отменённых уведомлений через GET /notifications?status=canceled&channel_id=…. Соберите все страницы GET /activity с date_from и date_to за время простоя.
  2. Повторите отправку уведомлений, чьё тело ещё хранится; см. ответы повторной отправки. При notification.payload_unavailable сверяйте саму транзакцию. При notification.send_in_progress дождитесь уже поставленной в очередь или выполняющейся попытки.
  3. Группируйте все строки активности по chain_gid, txid (hash при payload_version: v1), address и asset_gid и суммируйте знаковые delta.base, учитывая входящие и исходящие эффекты. Несколько выходов Bitcoin на один адрес относятся к одной группе. Затем примените собственные правила допустимости депозита и подтверждений; сумму всех входящих строк нельзя автоматически считать начислением. Сохраните ключ группы и результат учёта атомарно.

event_id определяет уведомление, а не перевод: другая подписка может сообщить о том же депозите с другим event_id. Используйте его для отсеивания повторных доставок одного уведомления, а общий ключ начисления - для сверки между подписками и опросом API.

Проверка канала

После создания используйте Проверка канала. Укажите только семейство транзакции, например evm; выбрать транзакцию, получателя или вид события нельзя. Схему запроса и примеры см. на странице операции.

Ответ - 202 с notification_id. Тест работает и на отключённом канале, состояние канала не меняет; он шлёт один встроенный пример для указанного семейства, без живых данных, за одну попытку без автоповторов. Тест, который не ушёл за пять минут, завершается с причиной test_expired. Проверьте уведомление, затем явно начните новый тест с новым ключом идемпотентности; повтор старого ключа лишь вернёт сохранённый ответ принятия.

История уведомлений

Каждое уведомление и каждая попытка его доставки сохраняются в истории. По ней можно убедиться, что тест дошёл, и разобрать сбои. Список уведомлений отдаёт GET /notifications, сначала самые свежие, а GET /notifications/{notification_id}/logs показывает все попытки по одному из них.

Начните с фильтров channel_id и status; отделяйте тесты через is_test, а период задавайте через date_from и date_to. Для поиска по txid также нужен chain_gid. Прочитайте все страницы результата. Полный набор фильтров, схемы ответов и примеры запросов приведены на странице списка уведомлений выше.

У каждой попытки в логе есть HTTP-статус и ошибка, которые вернул ваш эндпоинт. Когда оповещения перестали приходить, запросите status=failed и посмотрите последнюю попытку.

После исправления эндпоинта используйте POST /notifications/{notification_id}/actions/resend. Для новой ручной отправки задайте отдельный Idempotency-Key; при потере ответа повторяйте с ним же.

ОтветЧто делать
202Отправка поставлена в очередь с тем же телом и event_id; отсеивайте повторные доставки по event_id.
429 notification.resend_delayedДождитесь Retry-After для паузы между попытками доставки.
409 notification.send_in_progressДождитесь текущей попытки.
409 notification.payload_unavailableСверяйте саму транзакцию.

Повторная отправка использует текущего адресата, заголовки и данные подписи канала. Сохранённое тело не сохраняет старую конфигурацию и не обновляет факты о транзакции. Перечитайте счёт, прежде чем считать повторную отправку признаком завершения. Тело хранится 30 дней после завершения уведомления; затем повторная отправка недоступна.

Лучшие практики

Требования к получателю, включая проверку подписи, обработку повторов и время ответа, описаны в справочнике Webhooks. Используйте отдельные каналы для окружений и задач, чтобы критичные оповещения не смешивались с рутинными.