← Назад к блогу
Почта на своем домене без почтового сервера: прием через Cloudflare, отправка через Resend, письма шлет AI-агент

Почта на своем домене без почтового сервера: прием через Cloudflare, отправка через Resend, письма шлет AI-агент

Почта на своем домене без почтового сервера: прием через Cloudflare, отправка через Resend, письма шлет AI-агент

Свой почтовый сервер давно стал занятием для мазохистов. Postfix с Dovecot, SPF, DKIM, DMARC, борьба за репутацию IP, серые списки, попадание в спам у Gmail просто потому, что ваш VPS живет в “плохом” диапазоне. Десятки часов, чтобы получить то, что у больших почтовиков работает из коробки.

Хорошая новость: для типичного сценария “хочу you@мойдомен, чтобы письма падали в мой Gmail, а отправлять можно было от своего домена” почтовый сервер не нужен вообще. Прием и отправку можно склеить из двух сервисов, которые делают свою половину работы лучше, чем вы когда-либо настроите руками — и почти бесплатно. А раз отправка сводится к одному HTTP-запросу, письма вам может слать даже терминальный AI-агент.

Главная идея: прием и отправка — это разные записи

Ключ, который экономит кучу нервов: получение и отправка писем живут на разных DNS-записях и не мешают друг другу.

  • Прием определяется MX-записями корня домена. Они говорят миру: “почту для @мойдомен неси сюда”.
  • Отправка определяется DKIM-подписью и тем, что прописано в конверте письма (envelope / MAIL FROM) — а это можно увести на отдельный поддомен.

Поэтому связка работает без конфликтов:

Что отвечаетГде живет в DNS
Прием (Cloudflare)MX → route1/2/3.mx.cloudflare.netкорень домена
Отправка (Resend)DKIM resend._domainkey, MX+SPF на поддомене sendподдомен, корневой MX не трогает

Прием забирает себе корневой MX, отправка сидит на поддомене send.мойдомен и корень не занимает. Можно включить и то, и другое одновременно — что мы и сделаем.

Прием: Cloudflare Email Routing

Cloudflare Email Routing — бесплатный сервис: вы получаете адреса вида you@мойдомен и задаете правила пересылки на любой существующий ящик (тот же Gmail). Никакого хранилища, никакого IMAP — чистая пересылка на уровне MX. Условие одно: домен должен обслуживаться на Cloudflare (его NS).

Что нужно сделать:

  1. Включить Email Routing. Dashboard → домен → Email Routing → Enable. Cloudflare сам добавит свои MX и SPF и “залочит” их под себя.
  2. Подтвердить адрес назначения. Вписываете you@gmail.com, Cloudflare шлет туда письмо со ссылкой — переходите по ней. Без этого пересылка не активируется.
  3. Создать правило. Либо точечное (you@мойдоменyou@gmail.com), либо catch-all (все входящие на домен → ваш Gmail).

Адреса назначения общие на весь аккаунт: подтвердили you@gmail.com один раз — он доступен для всех ваших доменов.

Что можно автоматизировать через API, а что нет

Тут первый честный подводный камень. Правила и адреса прекрасно заводятся через API:

# Правило: you@yourdomain.com -> you@gmail.com
curl -sS -X POST \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/email/routing/rules" \
  --data '{
    "name": "forward you@ -> gmail",
    "enabled": true,
    "matchers": [{ "type": "literal", "field": "to", "value": "you@yourdomain.com" }],
    "actions":  [{ "type": "forward", "value": ["you@gmail.com"] }]
  }'

Catch-all (переслать вообще все входящие):

curl -sS -X PUT \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/email/routing/rules/catch_all" \
  --data '{
    "enabled": true,
    "matchers": [{ "type": "all" }],
    "actions":  [{ "type": "forward", "value": ["you@gmail.com"] }]
  }'

А вот сам факт включения Email Routing через API-токен сделать нельзя. Эндпоинты /email/routing (settings) и /email/routing/enable отдают Authentication error даже на токене с максимально широким набором прав — Email Routing Rules, Email Routing Addresses, DNS, Zone, все в Edit. Этот первый рубильник гейтится ролью, которую обычному API-токену не выдать: жмем его в дашборде руками. Зато все остальное — правила, адреса, чистка DNS — спокойно автоматизируется.

Токену для остальной автоматизации достаточно: Zone:Read, DNS:Edit, Email Routing Rules:Edit (zone), Email Routing Addresses:Edit (account).

Если на домене уже была почта

Второй камень: если на корне домена уже висят MX (например, пересылка от регистратора), Cloudflare при включении честно скажет: “Existing non-Cloudflare MX records conflict with Email Routing”. Старые MX надо снести. У токена есть DNS:Edit — удаляем их запросом и заодно подчищаем чужой корневой SPF, чтобы не плодить дубли (валидной должна остаться одна SPF-запись на корне):

# получить id записи: GET .../dns_records?type=MX&name=yourdomain.com
curl -sS -X DELETE \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID"

После этого онбординг проходит, Cloudflare ставит свои MX, и пересылка оживает.

Отправка: Resend поверх Amazon SES

Принимать научились. Теперь — отправлять от своего домена, чтобы письма не летели в спам. Resend — это API для отправки почты поверх Amazon SES, с человеческим DX вместо голого SES. Сначала верификация домена, потом — один запрос на каждое письмо.

При добавлении домена Resend выдает три набора записей, и важно, куда они ложатся:

  • DKIM — TXT resend._domainkey.мойдомен с публичным ключом (p=MIGf...). Подпись идет от корня домена (d=мойдомен).
  • MAIL FROM — MX и SPF на поддомене send.мойдомен (feedback-smtp.<region>.amazonses.com и v=spf1 include:amazonses.com ~all). Это конверт письма.
  • DMARC — TXT _dmarc.мойдомен (v=DMARC1; p=none;), для начала в режиме мониторинга.

Заметьте: ни одна из этих записей не занимает корневой MX. Поэтому Resend-отправка и Cloudflare-прием уживаются на одном домене. Более того, DMARC проходит за счет выравнивания по DKIM: подпись стоит на корне (d=мойдомен совпадает с доменом в From), поэтому письмо остается валидным, даже если корневой SPF указывает на Cloudflare, а не на amazonses. Главное — при настройке приема не трогать send.*, resend._domainkey и _dmarc.

Сама отправка — один POST:

curl -sS https://api.resend.com/emails \
  -H "Authorization: Bearer $RESEND_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
    "from": "You <you@yourdomain.com>",
    "to": ["you@gmail.com"],
    "subject": "Привет от своего домена",
    "text": "Письмо ушло через Resend, прилетело через Cloudflare."
  }'

from обязан быть на верифицированном домене — local-part (you, noreply, billing, что угодно) выбираете сами. У Resend есть бесплатный тариф, которого с запасом хватает на личную и транзакционную почту (актуальные лимиты — на resend.com/pricing).

Бонус: письма шлет сам AI-агент

А вот ради чего все затевалось. Раз отправка — это просто HTTP-запрос с Bearer-токеном, отправлять может кто угодно, у кого есть ключ. В том числе ваш кодовый агент.

Сценарий, который реально экономит время: вы запускаете в Claude Code долгую задачу — миграцию, прогон тестов, сборку — уходите пить кофе, а агент по завершении сам шлет вам письмо с итогом. Никакого сидения над терминалом в ожидании.

Достаточно сказать агенту человеческим языком: “когда закончишь, отправь мне письмо на you@gmail.com через Resend API” — и он выполнит ровно тот же curl, что выше, подставив осмысленную тему и тело:

curl -sS https://api.resend.com/emails \
  -H "Authorization: Bearer $RESEND_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
    "from": "Claude Code <bot@yourdomain.com>",
    "to": ["you@gmail.com"],
    "subject": "Сборка готова: 142 теста зеленые",
    "text": "Миграция применена, прогон занял 8 минут, упавших нет. Лог в артефактах."
  }'

Можно пойти дальше и зашить отправку в Stop-хук Claude Code — тогда уведомление о завершении любой сессии будет приходить на почту автоматически, без единого слова в промпте. Получается простой, надежный канал нотификаций от агента к вам — без Telegram-ботов и вебхуков, обычным письмом.

Подводные камни (собрано на граблях)

  • Включение Email Routing — только дашборд. API-токен этого не может, даже с полным набором email-прав. Один клик руками на каждый домен.
  • Конфликтующие MX надо снести перед включением, иначе онбординг не пройдет.
  • Один корневой MX — один приемник. Нельзя одновременно отдать прием и Cloudflare, и Resend Inbound: оба хотят корневой MX. Resend Inbound, кстати, это вообще не “пересылка в ящик”, а доставка во вебхук — для программной обработки, а не для чтения в Gmail.
  • Адрес назначения подтверждается кликом из письма. Обойти нельзя — это защита от пересылки на чужой ящик.
  • Resend-отправку прием не ломает — но только если не трогать send.*, resend._domainkey и _dmarc. Включение приема добавляет лишь корневые MX и SPF.

Итог

За один вечер, без почтового сервера и почти бесплатно:

  • you@мойдомен принимает письма и пересылает их в Gmail (Cloudflare Email Routing);
  • от you@мойдомен можно слать письма с нормальной доставляемостью (Resend поверх SES);
  • прием и отправка не конфликтуют, потому что сидят на разных DNS-записях;
  • а ваш AI-агент умеет писать вам на почту сам, когда доделал работу.

Эпоха, когда “своя почта на домене” означала недели возни с Postfix, кончилась. Теперь это два сервиса, несколько DNS-записей и пара curl-запросов.


P.S. Это был самый простой конец спектра — входящие просто падают в Gmail. Если хочется наоборот, чтобы входящими занимался код — читал их, разбирал и сам писал ответы — посмотрите cloudflare/agentic-inbox: самохостируемый почтовый клиент с AI-агентом, целиком на Cloudflare Workers. Прием там тоже через Email Routing (catch-all в Worker), хранение — Durable Objects и R2, а сам агент работает на Workers AI и драфтит ответы. Тот же фундамент из этой статьи, только вместо пересылки в ящик — полноценный инбокс под управлением агента.