Перейти к содержимому

Email Inbox (приём писем как уведомлений)

Email Inbox — это «почтовый ящик», у которого вместо вашего IMAP — каналы Notifly. Создав ящик, вы получаете уникальный email-адрес вида <alias>@in.notifly.ru. Всё, что на него приходит, разбирается по правилам маршрутизации: каждое правило по фильтру решает, в какой канал и с каким заголовком/текстом отправить уведомление.

Это удобно, когда внешняя система умеет только email и научить её ходить в HTTP — слишком дорого:

  • алёрты от хостингов, биллингов, RBL и регистраторов;
  • уведомления от CI/CD, системы бэкапов, сторонних SaaS;
  • transactional email от вашего же бекенда (заказы, регистрации) без отдельного канала push;
  • алёрты от старых железных мониторингов, которые умеют только SMTP.

Ящик сам по себе не привязан к каналу — он только принимает почту. Маршрутизация выполняется отдельными правилами. Поэтому настройка состоит из двух шагов:

  1. Создать ящик → получить адрес <alias>@in.notifly.ru и вписать его в настройки внешнего сервиса.
  2. Добавить правило (или несколько) → указать фильтр (для какого письма срабатывать) и канал-получатель.

Если у ящика нет ни одного правила, а письмо пришло — уведомлений оно не порождает (при включённой истории попадёт туда со статусом unmatched). Письмо проверяется включёнными правилами по возрастанию position; для каждого совпавшего правила создаётся уведомление в его канале.

SMTP-отправитель ──► <alias>@in.notifly.ru
│
▼
обработчик входящей почты Notifly
│ 1. достать alias из адреса
│ 2. найти ящик по alias
│ 3. прогнать письмо через правила ящика (по position)
│ 4. для каждого совпавшего правила — title/message по шаблону
▼
сообщение в канале правила + push (для каждого совпавшего правила)
│
▼
Все ваши клиенты получают уведомления
  • Маршрутизация — по alias в локальной части адреса.
  • Уведомление — обычное сообщение канала: push по WebSocket, лента GET /message, эскалация, тихие часы и окна обслуживания канала работают как для любого сообщения.
  • Каждое входящее письмо — одно событие дневной квоты, сколько бы правил ни сработало. Если квота исчерпана, письмо отбрасывается (в историю не попадает), а вам приходит уведомление о квоте.
  • Опционально входящие письма сохраняются в историю (см. saveEvents ниже).
  1. Откройте app.notifly.ru → Интеграции → Почтовые ящики.
  2. Нажмите «Создать почтовый ящик», заполните:
    • Название ящика — для отображения, например «Алёрты Reg.ru».
    • Сохранять письма в историю — складывать ли тексты писем в историю (saveEvents).
  3. В карточке появится сгенерированный email-адрес — это и есть аутентификация. Скопируйте его в настройки внешнего сервиса.

Тело запроса — EmailInboxParams: {name, saveEvents}. Поле appId у ящика нет — канал назначается правилами.

Окно терминала
curl -X POST "$NOTIFLY_URL/email-inbox" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <api-token>" \
-d '{
"name": "Алёрты Reg.ru",
"saveEvents": true
}'

В ответе придёт сам объект ящика с заполненным emailAddress:

{
"id": 17,
"name": "Алёрты Reg.ru",
"alias": "a3f9c21b8e04",
"emailAddress": "a3f9c21b8e04@in.notifly.ru",
"saveEvents": true,
"created": "2026-04-30T10:11:12Z",
"lastUsed": null
}

alias — 12 hex-символов, генерируется автоматически и неизменяем.

Правило (EmailInboxRule) описывает, какие письма ловить и куда их слать. У правила есть:

ПолеНазначение
appIdканал-получатель (обязателен; только ваш собственный канал)
nameимя правила для отображения
filterусловия срабатывания (см. ниже); пустой фильтр = «совпадает всегда»
titleTemplateшаблон заголовка уведомления; пусто → тема письма
messageTemplateшаблон текста уведомления; пусто → тело письма
priorityприоритет уведомления; 0 (по умолчанию) — приоритет канала
enabledвключено ли правило (по умолчанию true)
positionпорядок проверки (по возрастанию)

В шаблонах titleTemplate / messageTemplate доступны плейсхолдеры: {subject}, {body}, {from}, {to}, {date}, {alias} (одинарные фигурные скобки; {date} — момент приёма письма в UTC, RFC3339).

В админке приоритет правила не задаётся — уведомления приходят с приоритетом канала по умолчанию. Кнопка «Из шаблона…» в диалоге правила предзаполняет форму готовыми рецептами: «Алерты от cron» (тема содержит FAIL или ERROR), «Заказы интернет-магазина» и «Игнорировать рассылки» (пропускать только письма без заголовка List-Unsubscribe).

filter (EmailFilter) — это match плюс список conditions:

  • match: "all" — должны выполниться все условия (AND, по умолчанию);
  • match: "any" — достаточно одного условия (OR);
  • пустой conditions означает «совпадает всегда» (правило по умолчанию).

Каждое условие (EmailFilterCondition) — это field, op, value (и caseSensitive, по умолчанию false).

Поля (field):

fieldНа чём проверяет
fromзаголовок From (адрес или имя)
toзаголовок To (адрес)
subjectтема письма
bodyтекстовое тело письма
headerпроизвольный заголовок (имя — в headerName, регистр имени не важен; отсутствующий заголовок — пустая строка)

Операторы (op):

opСмысл
containsподстрока
not_containsотсутствие подстроки
equalsточное совпадение
not_equalsточное несовпадение
starts_withпрефикс
ends_withсуффикс
matchesRE2-регулярное выражение

Без caseSensitive: true сравнение (и regex) регистронезависимо.

Окно терминала
curl -X POST "$NOTIFLY_URL/email-inbox/17/rules" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <api-token>" \
-d '{
"appId": 12345,
"name": "Критичные алёрты бэкапа",
"filter": {
"match": "all",
"conditions": [
{"field": "from", "op": "contains", "value": "@reg.ru"},
{"field": "subject", "op": "starts_with", "value": "[ALERT]"}
]
},
"titleTemplate": "Reg.ru: {subject}",
"messageTemplate": "{body}",
"priority": 8,
"position": 0
}'

В ответе — полный объект правила с id, заполненным appName и значениями по умолчанию (enabled: true).

{
"field": "header",
"headerName": "X-Priority",
"op": "equals",
"value": "1"
}

Шаг 2 (быстрый). Правило из примера письма (AI)

Заголовок раздела «Шаг 2 (быстрый). Правило из примера письма (AI)»

Если вы уже включили saveEvents, не нужно вручную сочинять фильтр: пошлите тестовое письмо, найдите его в истории и попросите Notifly предложить правило по этому образцу — POST /email-inbox/rule/from-event/:eid.

Окно терминала
# Без prompt — эвристика: домен отправителя + ключевое слово из темы (без LLM).
curl -X POST "$NOTIFLY_URL/email-inbox/rule/from-event/981" \
-H "X-Notifly-Key: <api-token>"
# С prompt — подбор фильтра и шаблонов с помощью AI (1 запрос из квоты ИИ-помощников).
curl -X POST "$NOTIFLY_URL/email-inbox/rule/from-event/981" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <api-token>" \
-d '{"prompt": "лови только письма про сбой репликации, заголовок — кратко"}'

Ответ — черновик {filter, titleTemplate, messageTemplate}: его нужно дополнить полем appId и отправить в POST /email-inbox/:id/rules.

Если у ящика saveEvents: true, каждое входящее письмо сохраняется как EmailInboxEvent: from, to, subject, bodyRaw, заголовки (headers — имена в нижнем регистре, первое значение), а также status (matched / unmatched), matchedRuleIds и createdMessageIds. Это нужно для аудита («почему письмо не дошло?») и для подбора правил из примера. События хранятся 30 дней.

Окно терминала
# Список писем; фильтры: q (тема, отправитель, текст), status, inbox_id,
# from, to (RFC3339), limit (по умолчанию 50, максимум 100), cursor (id последнего события).
curl "$NOTIFLY_URL/email-inbox/event?inbox_id=17&status=unmatched&limit=50" \
-H "X-Notifly-Key: <api-token>"
# Одно письмо целиком.
curl "$NOTIFLY_URL/email-inbox/event/981" -H "X-Notifly-Key: <api-token>"
# Удалить запись из истории.
curl -X DELETE "$NOTIFLY_URL/email-inbox/event/981" -H "X-Notifly-Key: <api-token>"

Любой SMTP-клиент шлёт письмо на полученный адрес — никаких заголовков авторизации не нужно (alias сам и есть секрет):

Окно терминала
# msmtp / mailx
echo "База за ночь не обновилась — проверьте репликацию." \
| mail -s "[ALERT] backups: lag > 24h" \
"a3f9c21b8e04@in.notifly.ru"

Из Python:

import smtplib
from email.message import EmailMessage
msg = EmailMessage()
msg["To"] = "a3f9c21b8e04@in.notifly.ru"
msg["From"] = "alerts@example.com"
msg["Subject"] = "[ALERT] backups: lag > 24h"
msg.set_content("База за ночь не обновилась — проверьте репликацию.")
with smtplib.SMTP("smtp.example.com", 587) as s:
s.starttls()
s.login("user", "pass")
s.send_message(msg)
Поле уведомленияОткуда берётся
titletitleTemplate правила; если пуст — тема письма (Subject:), без темы — (no subject)
messagemessageTemplate правила; если пуст — текстовое тело письма
prioritypriority правила; 0 — приоритет канала по умолчанию
каналappId правила

Текст уведомления помечается как Markdown (client::display). Вложения не сохраняются.

Метод и путьАвторизацияНазначение
GET /email-inboxAPI-токенсписок ящиков (с правилами)
POST /email-inboxAPI-токен (write)создать ящик {name, saveEvents}
PUT /email-inbox/:idAPI-токен (write)изменить {name, saveEvents}
DELETE /email-inbox/:idAPI-токен (write)удалить ящик
GET /email-inbox/:id/rulesAPI-токенсписок правил ящика
POST /email-inbox/:id/rulesAPI-токен (write)создать правило
PUT /email-inbox/:id/rules/:ridAPI-токен (write)изменить правило
DELETE /email-inbox/:id/rules/:ridAPI-токен (write)удалить правило
GET /email-inbox/eventAPI-токенистория входящих (с фильтрами)
GET /email-inbox/event/:eidAPI-токенодно письмо
DELETE /email-inbox/event/:eidAPI-токенудалить запись истории
POST /email-inbox/rule/from-event/:eidAPI-токенпредложить правило по образцу (AI)

Нужен API-токен (M…); для изменений — с правом записи. Токены канала (в том числе расшаренного) сюда не пускаются — 403.

POST /email-inbox всегда возвращает полный объект EmailInbox, включая публичный emailAddress (его удобно сразу копировать в настройки внешней системы). POST/PUT правил возвращают полный объект EmailInboxRule с appName.

  • В уведомление идёт текстовое тело письма; вложения не сохраняются.
  • Тело длиннее 1 МБ обрезается — и в уведомлении, и в истории (bodyTruncated: true).
  • Каждое письмо — одно событие дневной квоты; сверх квоты письма отбрасываются.
  • Без правил письма уведомлений не порождают — добавьте хотя бы одно правило с пустым фильтром, чтобы ловить всё.
  • AI-подбор правила с prompt списывает один запрос из дневной квоты ИИ-помощников.