Доставка и эскалация
Push-уведомление доходит мгновенно — но только если телефон под рукой. Доставка (вкладка Доставка в настройках канала) решает вторую задачу: что делать, если сообщение никто не прочитал.
Для каждого канала можно включить дополнительные способы доставки. Работают они как эскалация: сообщение уходит по такому каналу, только если владелец не прочитал его за заданное время.
POST /message ──▶ push всем устройствам (мгновенно) │ └─ раз в минуту: воркер доставки ├─ сообщение прочитано? → ничего не делаем └─ прошло >= таймаута метода? → email / SMS / звонок / Slack / Telegram / webhookСпособы доставки
Заголовок раздела «Способы доставки»| Метод | Что настраивается | Приходит |
|---|---|---|
| адрес получателя, таймаут | письмо со ссылкой на сообщение и кнопками действий | |
| СМС | номер в формате +79001234567, таймаут | короткий текст с названием канала и заголовком |
| Звонок | номер, таймаут | голосовой звонок с уведомлением |
| Slack | incoming webhook URL, таймаут, мин. приоритет | сообщение в канал Slack |
| Telegram | bot token, chat ID, таймаут, мин. приоритет | сообщение от бота (с inline-кнопками) |
| Webhook | URL, необязательный секрет, таймаут, мин. приоритет | POST с JSON-телом |
Таймаут: когда именно сработает
Заголовок раздела «Таймаут: когда именно сработает»У каждого метода свой таймаут доставки (readTimeoutSec):
0— досылка на ближайшем прогоне воркера (то есть примерно в течение минуты);300— если сообщение не прочитано 5 минут;- максимум — 23 часа (
82800).
Отсчёт идёт от момента создания сообщения, а не от момента доставки push.
Сообщение считается прочитанным, когда вы открыли его в админке или мобильном
приложении, либо когда сработал один из endpoint-ов
POST /message/read / POST /application/{id}/message/read,
либо когда вы нажали кнопку ✓ Прочитано в письме или в Telegram.
Отсечка «до подключения»
Заголовок раздела «Отсечка «до подключения»»В момент включения метода сервер запоминает отметку времени. Сообщения, созданные раньше этого момента, по новому методу не досылаются — иначе включение email-а вечером обернулось бы письмом обо всём, что накопилось за сутки.
Минимальный приоритет
Заголовок раздела «Минимальный приоритет»У Slack, Telegram и webhook есть поле мин. приоритет: сообщения с приоритетом ниже указанного через этот адаптер не уходят. Удобно, чтобы в рабочий чат попадали только важные события, а вся мелочь оставалась в приложении.
У email, SMS и звонка фильтра по приоритету нет — они управляются только переключателем и таймаутом.
Группировка и дайджест
Заголовок раздела «Группировка и дайджест»Внутри одного прогона сообщения группируются по паре «владелец + адрес»:
- email — одно сообщение приходит обычным письмом, несколько — одним письмом-дайджестом со списком;
- СМС — одно СМС на номер: заголовок и краткий список каналов и тем;
- звонок — один звонок на номер, независимо от числа сообщений.
Slack, Telegram и webhook не группируются: одно сообщение — одна отправка.
Гарантии доставки
Заголовок раздела «Гарантии доставки»| Метод | Поведение при сбое |
|---|---|
| email, Slack, Telegram, webhook | Идемпотентны: отметка о доставке ставится после отправки, при сбое следующий прогон повторит |
| СМС, звонок | Отметка ставится до отправки (дубль недопустим), при ошибке снимается и попытка повторяется |
Каждое сообщение уходит по каждому методу ровно один раз: факт доставки фиксируется в журнале и повторно не срабатывает.
Кнопки действий в письме и Telegram
Заголовок раздела «Кнопки действий в письме и Telegram»В письмо и в сообщение Telegram-бота добавляются подписанные ссылки:
- ✓ Прочитано — отмечает сообщение прочитанным и останавливает досылку по остальным методам;
- варианты ответа — если сообщение содержит закрытый вопрос (Ask), кнопки соответствуют вариантам ответа.
Ссылки подписаны HMAC и действуют ограниченное время (для вопросов — до истечения срока ответа), поэтому авторизация в интерфейсе для них не нужна.
Формат webhook
Заголовок раздела «Формат webhook»Generic-webhook получает POST с JSON:
{ "title": "CPU high", "message": "load average 12.4", "priority": 8, "channel": "Prod", "appId": 12345, "ts": 1782561600000}Если задан секрет, тело подписывается HMAC-SHA256 и подпись передаётся в заголовке:
X-Notifly-Signature: sha256=<hex>Проверка на стороне получателя (Python):
import hmac, hashlib
def valid(raw_body: bytes, header: str, secret: str) -> bool: expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest() return hmac.compare_digest(expected, header)Настройка
Заголовок раздела «Настройка»Через админку
Заголовок раздела «Через админку»Настройки канала → вкладка Доставка. Включите нужный метод переключателем, укажите адрес и таймаут. Кнопка Проверить рядом с методом сохраняет настройки и сразу шлёт туда тестовое уведомление.
Подсказка по Telegram: создайте бота через @BotFather (/newbot) — он выдаст
bot token; узнайте Chat ID (для личных сообщений — у @userinfobot, для группы
это ID вида -100…); обязательно нажмите Start у своего бота или добавьте
его в группу, иначе Telegram запретит отправку.
Через REST API
Заголовок раздела «Через REST API»Настройки доставки — часть объекта канала, поле deliveryConfig в
POST /application и PUT /application/{id}:
curl -X PUT "$NOTIFLY_URL/application/12345" \ -H "Content-Type: application/json" \ -H "X-Notifly-Key: <client-token>" \ -d '{ "name": "Prod", "deliveryConfig": { "email": { "enabled": true, "to": "oncall@example.com", "readTimeoutSec": 300 }, "telegram": { "enabled": true, "botToken": "123:ABC", "chatId": "-1001234567890", "readTimeoutSec": 900, "minPriority": 7 }, "webhook": { "enabled": true, "url": "https://example.com/hook", "secret": "s3cret", "readTimeoutSec": 0, "minPriority": 5 } } }'Поля адаптеров:
| Поле | Кто использует | Значение |
|---|---|---|
enabled | все | включён ли метод |
to | email, sms, call | адрес или номер получателя (+79001234567) |
url | slack, webhook | incoming webhook URL / произвольный URL |
botToken, chatId | telegram | параметры бота |
secret | webhook | ключ подписи HMAC-SHA256 (опционально) |
readTimeoutSec | все | таймаут досылки, 0…82800 |
minPriority | slack, telegram, webhook | не слать сообщения с приоритетом ниже |
Тест доставки
Заголовок раздела «Тест доставки»curl -X POST "$NOTIFLY_URL/application/12345/delivery/test" \ -H "Content-Type: application/json" \ -H "X-Notifly-Key: <client-token>" \ -d '{"adapter": "telegram"}'Без тела проверяются все включённые методы канала. Ответ — результат по каждому:
{ "results": { "telegram": { "ok": false, "error": "telegram: 403 bot was blocked by the user" } } }Если ни один метод не включён (или указанный адаптер выключен), вернётся 400
no enabled adapter to test. Проверка идёт в обход эскалации: ждать таймаута
не нужно, уведомление уходит сразу.
Досылка не расходует дневную квоту: событие уже списано при создании
сообщения (message). Сколько бы методов доставки ни было включено, счётчик
событий от этого не растёт — см. Квоты и тарифы.
Безопасность
Заголовок раздела «Безопасность»- URL-адреса Slack и webhook проверяются защитой от SSRF: приватные, loopback и link-local адреса на момент отправки блокируются.
- Секреты (
botToken,secret) хранятся в настройках канала и доступны только владельцу канала: получателю делегированного доступа вкладка «Доставка» недоступна. - Управление доставкой требует client-токена владельца канала; app-токен канала сюда не подходит.
См. также
Заголовок раздела «См. также»- Отправка сообщений — приоритеты, заголовки и extras.
- Вопросы в каналах (Ask) — ответы прямо из письма и Telegram.
- WebSocket-протокол — мгновенный приём вместо эскалации.
- Публичные статус-страницы — уведомления не для команды, а для ваших пользователей.