NestJS + Mailexam
Минимальный пример NestJS, который отправляет тестовое письмо через SMTP Mailexam с помощью Nodemailer и @nestjs-modules/mailer.
Основан на руководстве Mailexam для NestJS.
Что понадобится
- Аккаунт Mailexam и проект с SMTP-учётными данными.
- Node.js 18+ и npm.
Из приветственного письма или личного кабинета Mailexam:
| Переменная | Описание |
|---|---|
MAILEXAM_LOGIN |
SMTP-логин (например, xxxxx) |
MAILEXAM_PASSWORD |
SMTP-пароль (пара к логину) |
| Хост |
{MAILEXAM_LOGIN}.mailexam.ru (формируется автоматически в коде) |
Быстрый старт (на хосте)
- Установите зависимости:
npm install
- Скопируйте пример файла окружения и заполните учётные данные:
cp .env.example .env
- Отредактируйте
.env:
MAILEXAM_LOGIN=ВАШ_ЛОГИН
MAILEXAM_PASSWORD=ВАШ_ПАРОЛЬ
MAILEXAM_PORT=587
MAIL_FROM=noreply@example.test
- Соберите и запустите сервер:
npm run build
npm start
По умолчанию сервер слушает http://127.0.0.1:3000.
- Отправьте тестовое письмо:
curl -X POST http://127.0.0.1:3000/mail/test \
-H 'Content-Type: application/json' \
-d '{"to":"user@example.test","subject":"Тест","text":"Привет"}'
Письмо появится в личном кабинете Mailexam → ваш проект → входящие.
Переменные окружения
| Переменная | Обязательна | По умолчанию | Описание |
|---|---|---|---|
MAILEXAM_LOGIN |
да | — | SMTP-логин; также используется для формирования имени хоста |
MAILEXAM_PASSWORD |
да | — | SMTP-пароль |
MAILEXAM_PORT |
нет | 587 |
SMTP-порт (587, 2525 или 465) |
MAIL_FROM |
нет | noreply@example.test |
Адрес отправителя |
HTTP_HOST |
нет | 127.0.0.1 |
Адрес привязки HTTP |
HTTP_PORT |
нет | 3000 |
Порт HTTP |
Для порта 587 транспорт использует STARTTLS (secure: false). Для порта 465 — SMTPS (secure: true).
Структура проекта
.
├── package.json
├── tsconfig.json
├── src/
│ ├── main.ts # bootstrap и HTTP-сервер
│ ├── app.module.ts # конфигурация MailerModule
│ └── mail.controller.ts
├── .env.example
├── Dockerfile # только для локальной отладки
└── docker-compose.yml
Docker (отладка)
Docker предназначен для локальной отладки. Для повседневной разработки запускайте приложение на хосте через npm run build && npm start (см. выше).
cp .env.example .env
# отредактируйте .env с учётными данными Mailexam
docker compose up --build
Затем вызовите тот же endpoint на проброшенном порту:
curl -X POST http://127.0.0.1:3000/mail/test \
-H 'Content-Type: application/json' \
-d '{"to":"user@example.test","subject":"Тест","text":"Привет"}'
Внутри контейнера сервер слушает 0.0.0.0:3000, чтобы работало проброс портов.
CI
Задайте эти секреты в окружении CI:
variables:
MAILEXAM_LOGIN: $MAILEXAM_LOGIN
MAILEXAM_PASSWORD: $MAILEXAM_PASSWORD
MAILEXAM_PORT: "587"
MAIL_FROM: "noreply@example.test"
После отправки письма в тесте проверьте доставку через API Mailexam.
Для unit-тестов замокайте MailerService или используйте transport: { jsonTransport: true } в тестовом модуле.
Типичные проблемы
Таймаут соединения / ошибка аутентификации
- Хост должен быть
{логин}.mailexam.ru, где{логин}совпадает сMAILEXAM_LOGIN. - Логин и пароль должны быть из одного проекта Mailexam.
Порт 587 и TLS
- Для 587:
secure: false(STARTTLS). Для 465:secure: true.
Переменные undefined
- Добавьте файл
.envв корень проекта или экспортируйте переменные в shell/CI.
Письмо не в кабинете
- Откройте входящие того же проекта Mailexam.
- Проверьте логи Nest на ошибки SMTP при
sendMail.
Порт уже занят
- Измените
HTTP_PORTв.env.
См. также
- Руководство Mailexam для NestJS (wiki)
- Пример на Hapi — другой Node.js-фреймворк с Nodemailer
- Пример на Midway.js — другой Node.js-фреймворк с Nodemailer
- Пример на Next.js — App Router с Nodemailer
- Документация NestJS
- @nestjs-modules/mailer
- Документация Nodemailer
Лицензия
Apache 2.0