Входящая почта для приложений

Принимайте входящие письма прямо в приложение

Направьте на fmailer MX-запись своего поддомена — письмо будет принято, разобрано на поля и отправлено в ваш вебхук. Без IMAP, без собственного почтового сервера, без промежуточной инфраструктуры.

MX вашего поддомена · Вебхук · Без IMAP · Приём доступен на платных тарифах

Путь письма от отправителя до вашего кода

┌─────────────────────────────────┐
│ client@partner.ru               │
└────────────────┬────────────────┘
                 │ письмо
                 ▼
┌─────────────────────────────────┐
│ support@inbound.example.ru      │
│ MX 10 mx.fmailer.ru             │
└────────────────┬────────────────┘
                 │
                 ▼
┌─────────────────────────────────┐
│ fmailer: разбор, DKIM, вложения │
└────────────────┬────────────────┘
                 │ inbound.received
                 ▼
┌─────────────────────────────────┐
│ POST /webhooks/inbound          │
└─────────────────────────────────┘

Если вы переходите с другого сервиса

Одна задача, три разные инфраструктуры

Mailgun, SendGrid и Amazon SES решают одно и то же: принять письмо на вашем домене и отдать его приложению. Различается только то, сколько компонентов стоит между письмом и кодом. Ниже — разбор каждого перехода на fmailer.

Как это работает

Email → вебхук, без лишней инфраструктуры

Обычно, чтобы принимать почту, приложению приходится опрашивать IMAP, держать собственный почтовый сервер или собирать конвейер из нескольких сервисов. Здесь три шага.

  1. 01Поддомен и MX-записьЗадайте хост приёма — например inbound.example.ru — и опубликуйте для него одну MX-запись. Это должен быть именно поддомен: MX основного домена и корпоративная почта остаются без изменений.
  2. 02МаршрутыУкажите, какие адреса принимаете: точный support, префикс ticket-* или * для всего остального. Выигрывает самый конкретный маршрут, а адрес, не подошедший ни под один, отклоняется прямо на SMTP.
  3. 03ВебхукКаждое принятое письмо приходит подписанным POST-запросом с событием inbound.received на эндпоинт, указанный в сработавшем маршруте.

Тело события inbound.received — то же, что в документации

json
{
  "event_id": "6f1d2c30-0004-4c7a-9b21-0c8e5a3d7f44",
  "event": "inbound.received",
  "inbound_id": "b41f9a70-2c55-4d1e-9a7f-1d3e5c9b2a08",
  "domain": "example.ru",
  "route": "support",
  "recipient": "support@inbound.example.ru",
  "mail_from": "client@partner.ru",
  "from": { "email": "client@partner.ru", "name": "Иван Петров" },
  "to": ["support@inbound.example.ru"],
  "cc": [],
  "subject": "Не пришёл счёт по заказу 4417",
  "text": "Добрый день! Заказ оплачен, счёта нет.",
  "html": "<p>Добрый день! Заказ оплачен, счёта нет.</p>",
  "headers": { "Reply-To": ["client@partner.ru"] },
  "message_id": "<CAF9x1@mail.partner.ru>",
  "auth": { "dkim": "pass", "dkim_aligned": true },
  "size": 24188,
  "raw_url": "https://api.fmailer.ru/api/inbound/messages/b41f9a70-.../raw/",
  "attachments": [
    {
      "id": "9c7e1b52-40a8-4f9d-8c31-6b2a4e0d1f77",
      "filename": "чек.pdf",
      "content_type": "application/pdf",
      "size": 18422,
      "inline": false,
      "url": "https://api.fmailer.ru/api/inbound/messages/b41f9a70-.../attachments/9c7e1b52-.../"
    }
  ],
  "timestamp": "2026-06-24T09:41:13.482921+00:00"
}

Ссылки на исходный .eml и вложения ведут на наш API, а не на хранилище: они постоянны, требуют токена аккаунта и в момент обращения перенаправляют на свежую подписанную ссылку. Поэтому повтор вебхука через сутки не приносит мёртвых ссылок.

Сравнение архитектур

Что стоит между письмом и вашим кодом

Слева — путь письма в той инфраструктуре, с которой вы переходите. Справа — тот же путь здесь. Он одинаковый во всех трёх случаях, и в этом смысл.

Было

  1. Письмо
  2. MX → Mailgun
  3. Route: filter + action
  4. forward(url)
  5. Ваше приложение

Стало

  1. Письмо
  2. MX → fmailer
  3. Маршрут: support / ticket-* / *
  4. inbound.received
  5. Ваше приложение

Это сравнение одного сценария — «письмо → приложение», — а не функций целиком. У каждого из перечисленных сервисов есть возможности, которых у нас нет, и обещать полную замену было бы неправдой.

Миграция

Замена Mailgun Inbound Routes

Mailgun Routes принимает письмо и по заданным правилам либо передаёт его на HTTP-эндпоинт, либо пересылает на другой почтовый адрес. Если Routes нужен был ради первого — чтобы письмо попадало в код, — тот же сценарий на fmailer собирается из MX-записи и маршрутов.

Было
Mailgun Route → forward(https://example.ru/email)
Стало
Маршрут → inbound.received → https://example.ru/email

Что устроено иначе: маршрут здесь — это шаблон локальной части адреса (точный, префикс или catch-all), а не выражение с фильтрами по заголовкам и телу; действий forward на другой почтовый адрес и stop у нас нет — письмо всегда отдаётся вебхуком, а решение о том, что с ним делать, принимает ваш код.

Для каких сценариев подходит

  • приём ответов пользователей;
  • создание тикетов из писем;
  • обработка адресов вида reply-*;
  • приём заявок и документов;
  • передача писем в CRM;
  • автоматическая обработка входящей почты.

Миграция

Альтернатива SendGrid Inbound Parse

Inbound Parse принимает письма на заданном хосте, разбирает содержимое и отправляет данные POST-запросом на ваш URL. fmailer делает то же самое, но отдаёт разобранное письмо подписанным JSON, а не multipart-формой, и не кладёт вложения в тело запроса — вместо этого в событии приходят ссылки на них.

Никакого опроса IMAP

Не нужно подключаться к ящику по расписанию и проверять, не появилось ли новое письмо: приложение получает событие в момент, когда письмо принято.

Одно отличие стоит учесть заранее: локальная часть сравнивается дословно и теги после плюса не отрезаются. Для генерируемых адресов заводите префиксный маршрут — reply-* — и не рассчитывайте на то, что support+78392 попадёт в маршрут support.

Например: ответ попадает в нужный диалог

  1. Ваш сервис отправляет уведомление и ставит в Reply-To адрес reply-78392@inbound.example.ru.
  2. Пользователь нажимает «Ответить» в своём почтовом клиенте.
  3. Маршрут reply-* ловит адрес, и fmailer вызывает ваш вебхук.
  4. Приложение достаёт 78392 из поля recipient и добавляет ответ в нужную переписку.

Миграция

Альтернатива Amazon SES + Lambda для приёма писем

Amazon SES умеет принимать входящую почту, но обработка обычно строится вокруг инфраструктуры AWS: Receipt Rule кладёт письмо в S3, Lambda достаёт его оттуда и разбирает MIME, между шагами могут стоять SNS и права IAM. Событие, которое Lambda получает напрямую, содержит метаданные и заголовки, но не тело письма — поэтому письмо и попадает сначала в бакет.

Если задача ровно в том, чтобы получить входящее письмо в приложении, промежуточные компоненты можно убрать: fmailer принимает письмо, разбирает его сам и вызывает ваш вебхук с готовыми полями.

Если задача шире — держать исходники писем в собственном бакете, обрабатывать их внутри VPC, собирать произвольный конвейер, — SES остаётся гибче. Речь здесь только про сценарий «письмо → приложение».

Что перестаёт быть вашей заботой

  • Receipt Rules и порядок их применения;
  • бакет S3 для писем и его жизненный цикл;
  • функция Lambda, разбирающая MIME;
  • SNS между шагами;
  • права IAM между сервисами.

Что на этом строят

Входящее письмо как событие в вашем коде

Ответы по почте

Отправляйте письма с уникальным адресом для ответа — reply-12345@inbound.example.ru — и ответ пользователя попадёт в нужный диалог, а не в общий ящик.

Служба поддержки

Письмо на support@ превращается в тикет: отправитель, тема, текст, HTML и вложения приходят уже разобранными.

CRM

Письма на sales@ становятся лидами, активностями или сообщениями в карточке клиента.

Документы

Счета, акты и заявки приходят почтой, а ваш обработчик забирает вложения по ссылке из события и отправляет их в свой конвейер.

AI-агенты

Классифицировать обращение, вытащить номер заказа, определить клиента, подготовить черновик ответа — на входе готовый текст письма, а не MIME.

Автоматизация

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

Что это не такое

Не почтовый ящик, а API для вашего приложения

Письма не хранятся для чтения человеком в почтовом клиенте: нет ни IMAP, ни POP3, и отвечать с адреса приёма нельзя — ответ отправляется обычным способом, через SMTP или API. Приём нужен, чтобы письмо попадало в код.

Принятые письма при этом видны в панели, пока их не удалит срок хранения журнала по тарифу: тело, заголовки, вердикт DKIM, исходный .eml и вложения.

Было

SMTP → ящик → IMAP → опрос → парсер → приложение

Стало

SMTP → fmailer → вебхук → приложение

Что именно реализовано

Технические детали, а не общие слова

Здесь перечислено только то, что работает сегодня. Полное описание — в документации по приёму.

Подпись вебхука
Та же схема, что у событий доставки: заголовки X-Webhook-Event, X-Webhook-Delivery, X-Webhook-Timestamp и X-Webhook-Signature, HMAC-SHA256 по строке «метка времени.тело». Проверяется тем же кодом, что и остальные события.
Повторы
Всё, кроме 2xx, а также сетевая ошибка и молчание дольше 10 секунд считается неудачей. Расписание повторов: 60с → 5м → 30м → 2ч → 6ч → 24ч.
Письмо не теряется
Даже когда повторы закончились, письмо остаётся в панели и в GET /api/inbound/messages/ — с телом, заголовками, .eml и вложениями. Пропущенное за время простоя забирают оттуда, а не просят отправителей слать заново.
Идемпотентность
У повтора тот же event_id. Те же байты, присланные повторно тому же получателю, распознаются и вебхук второй раз не вызывают.
Вложения
До 25 вложений, каждое до 25 МБ. В событии — имя файла, тип, размер, признак inline и авторизованная ссылка на скачивание; исходный .eml доступен целиком.
Размер письма
До 30 МБ; текстовая и HTML-части сохраняются до 500 000 символов каждая. Письмо большего размера отклоняется ответом 552 — отправитель узнаёт об этом сразу.
Заголовки
В поле headers приходит фиксированный набор: Reply-To, In-Reply-To, References, Return-Path, Auto-Submitted, Precedence, List-Id, List-Unsubscribe и другие. Каждое значение — список. Всё остальное есть в .eml.
Проверка отправителя
Результат DKIM по RFC 8601 и признак выравнивания с доменом из From. Полей spf и dmarc намеренно нет: вычислить их из одного DKIM нельзя, а написать неправду хуже, чем не написать ничего.
Маршрутизация
Точный адрес, префикс и catch-all; выигрывает самый конкретный, затем самый длинный подходящий префикс. Адрес без включённого маршрута отклоняется ответом 550, а не принимается молча.
Лимит приёма
500 писем в час на домен. При превышении сервер отправителя получает 450 и повторяет попытку позже, то есть письмо не теряется.
В панели
Состояние MX-записи, список маршрутов с предупреждением о неподписанных эндпоинтах и журнал принятых писем с фильтрами по маршруту и результату DKIM.
API и white-label
Хост, маршруты и принятые письма доступны через /api/inbound/. Реселлеры управляют маршрутами своих клиентов через white-label API со скоупами inbound:read и inbound:write.

Частые вопросы

Вопросы о приёме писем

Начните принимать почту через вебхук

Подключите поддомен, опубликуйте MX-запись и получайте входящие письма прямо в своём приложении.