Почта

Транзакционные письма (magic-link, приветствие, чек об оплате) — обычные функции, которые возвращают тему/текст/HTML и не зависят от способа доставки (src/lib/mail/templates.ts). Транспорт подключается отдельно и переключается переменной окружения — код писем не меняется.

Транспорт

EMAIL_FROM="LaunchKit <no-reply@localhost>"
SMTP_HOST=""
SMTP_PORT=""
SMTP_USER=""
SMTP_PASSWORD=""

Если SMTP_HOST не задан — активен лог-транспорт: письмо не отправляется по сети, а пишется в лог процесса. Это позволяет прогонять полный цикл регистрации/входа/оплаты локально без настроенного SMTP.

Как только SMTP_HOST задан, транспорт переключается на реальную отправку через nodemailer поверх SMTP.

Прод: Stalwart SMTP

Бизнес-инфраструктура LaunchKit использует самостоятельно хостящийся Stalwart Mail Server для исходящей почты (домен launch-kit.ru). Для собственного деплоя на своём сервере это не обязательно — подойдёт любой SMTP-провайдер (Stalwart, Postmark, свой почтовый сервер и т.д.), главное — заполнить SMTP_HOST/SMTP_PORT/SMTP_USER/SMTP_PASSWORD и EMAIL_FROM.

Если поднимаете свой Stalwart:

  1. Разверните Stalwart (Docker-образ stalwartlabs/stalwart) на отдельном (под)домене, например mail.your-domain.ru.
  2. Заведите отправляющий аккаунт и пароль приложения.
  3. Опубликуйте SPF, DKIM и DMARC записи в DNS для домена, с которого отправляете письма — без них почта массово улетает в спам у крупных провайдеров (Gmail, Яндекс, Mail.ru).
  4. Заполните SMTP_HOST=mail.your-domain.ru, SMTP_PORT=465 (SMTPS) или 587 (STARTTLS), SMTP_USER/SMTP_PASSWORD из шага 2, EMAIL_FROM="Ваш сервис <no-reply@your-domain.ru>".

Готовые шаблоны

| Функция | Когда отправляется | |---|---| | magicLinkEmail(url) | вход по magic-link (Auth.js Nodemailer провайдер) | | welcomeEmail(name) | после регистрации по email/паролю | | licenseReceiptEmail(plan, amountRubles) | после успешной оплаты — подтверждение и сумма |

Все шаблоны — на русском, с общим HTML-layout (layout() в templates.ts), возвращают текстовую и HTML-версии одновременно. Добавить новый шаблон — значит написать ещё одну чистую функцию, возвращающую { subject, text, html }, и вызвать транспорт (sendMail в src/lib/mail/index.ts) там, где нужно письмо.

Локальная проверка

При лог-транспорте письмо появляется в консоли процесса (pnpm dev или логах Docker-контейнера) в виде JSON с темой, текстом и HTML — этого достаточно, чтобы проверить содержимое письма и факт триггера отправки, не поднимая реальный SMTP.