Мне понадобилось отправить сообщение по почте о подтверждении регистрации на сайте. На текущий момент проверенное, хорошо зарекомендовавшее себя решение это Nodemailer. В роли бек-сервера у меня NestJS. Для NestJS есть модуль Nest JS Mailer, вот с ним и решил работать. Сперва установим пакеты @nestjs-modules/mailer, nodemailer и в dev-зависимость будет не лишним поставить @types/nodemailer . В качестве сервера почты я решил воспользоваться услугами яндекс.
Установка модуля
После того, как получена учётная запись от яндекса, записал в файл .env такие переменные:
MAIL_TRANSPORT строка подключения к smtp-серверу для отправки почты (см. https://nodemailer.com/smtp/)
MAIL_FROM_NAME от чьего имени будет приходить почта.
Пример:
MAIL_TRANSPORT=smtps://useYandex@yandex.ru:password@smtp.yandex.ru
MAIL_FROM_NAME=WebWork
Написал в файле src/configs/mail.config.ts формирование настройки почтовой службы:
import { ConfigService } from '@nestjs/config';
import { EjsAdapter } from '@nestjs-modules/mailer/dist/adapters/ejs.adapter';
export const getMailConfig = async (
configService: ConfigService,
): Promise<any> => {
const transport = configService.get<string>('MAIL_TRANSPORT');
const mailFromName = configService.get<string>('MAIL_FROM_NAME');
const mailFromAddress = transport.split(':')[1].split('//')[1];
return {
transport,
defaults: {
from: `"${mailFromName}" <${mailFromAddress}>`,
},
template: {
adapter: new EjsAdapter(),
options: {
strict: false,
},
},
};
};
Что я здесь задаю: defaults.from - задаётся имя/адрес отправителя, template - у меня было больше практики с ejs, поэтому выбран такой формат для шаблонов писем.
Завершающий шаг установки - подключение модуля почты в приложение:
import { MailerModule } from '@nestjs-modules/mailer';
@Module({
imports: [
MailerModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: getMailConfig,
}),
],
})
Отправка почты
У меня уже есть шаблон почты в файле confirmReg.ejs:
<main>
Доброго дня, <%= locals.username %>!<br />
От Вас поступила регистрация на сайте post-life.<br />
Для окончания регистрации пройдите пожалуйста по
<a href="<%= urlConfirmAddress %><%= id %>">ссылке</a> .
</main>
Вот как он используется для отправки почты:
import { MailerService } from '@nestjs-modules/mailer';
@Injectable()
export class UserService {
constructor(
// помимо всего прочего подключение сервиса отправки
private readonly mailerService: MailerService,
) {}
///
}
async sendConfirmMail(user: UserEntity) {
const urlConfirmAddress = this.configService.get<string>(
'URL_CONFIRM_ADDRESS',
);
// Отправка почты
return await this.mailerService
.sendMail({
to: user.email,
subject: 'Подтверждение регистрации',
template: join(__dirname, '/../templates', 'confirmReg'),
context: {
id: user.id,
username: user.username,
urlConfirmAddress,
},
})
.catch((e) => {
throw new HttpException(
`Ошибка работы почты: ${JSON.stringify(e)}`,
HttpStatus.UNPROCESSABLE_ENTITY,
);
});
}
Публикация скриптов
Описываемый проект после публикации и проверки отправки почты выдал ошибку о том, что не может найти файл confirmReg.ejs . Почему шаблоны писем потерялись? - Компилятор из TS в JS "не заметил" файлы с раcширением ejs и после билда проекта каталог src/templates не оказался в папке назначения dist . Мои поиски решения привели меня вот на эту страницу . Суть того, что можно оттуда вынести: у NestJS есть свои опции настройки для typescript и в них можно указать файлы, которые ts должен скопировать "как есть" в каталог назначения. Теперь nest-cli.json стал таким:
{
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"assets": [
"**/*.ejs"
],
"watchAssets": true
}
}
Ссылка на проект : https://github.com/SLKarol/post-life
Top comments (2)
Привет! Сейчас как раз занимаюсь проектом, где нужно отправлять юзерам при регистрации письма. Делал как у вас, но столкнулся с проблемой, что Яндекс не даёт слать письма из приложения. Просит решить капчу, а у меня нет никакого интерфейса, где эта капча могла бы появиться.
Возникала ли у вас такая проблема? Если да, то как боролись?
Приветствую!
Что-то похожее было- мне бот яндекса написал, что имя отправителя должно совпадать с именем яндекс-учётки. То есть у меня там было "Бот address@yandex.ru" - пришлось изменить на соответствие рег. данным.
Второй отказ был такой: Яндекс-бот пишет мне, что почта довольно подозрительная, похоже на спам. Предлагает мне для снятия подозрений отправить письмо с этого адреса. Когда отправил, почта отправлялась без проблем, но не долго. Потом опять яндекс-бот пишет о подозрении на спам, опять нужно руками какое-то письмо отправить.
Поэтому я решил отойти от яндекса- может гугл или другой сервис попробовать.
Надеюсь мои два шага Вам помогут.