Gửi mai là chức năng mà hầu hết các trang web có sử dụng chứng năng đăng nhập bằng email hay các trang thương mại điện tử. Gửi mail giúp chúng ta có những thông báo một cách nhanh chóng, dễ dàng và hoàn toàn miễn phí. Đồng thời xây dựng các chức năng reset password hay verify email chẳng hạn.

Cùng nhau tiến hành tìm hiểu cách setup và gửi mail trong NestJS xem nó có khác nhiều so với NodeJS thông thường không nhé.

Theo dõi source code tại đâybranch dev nha

Link postman để test cho dễ.

Cấu hình gửi mail trong NestJS

Đầu tiên ta cần cài đặt package để gửi mail:

npm install @nest-modules/mailer hbs nodemailer
npm install @types/nodemailer -dev

Hbs là template dùng để tạo giao diện email, các bạn có thể dùng template khác như ejs cũng được nha.

Tiếp theo ta cần cấu hình email vào module, ở đây mình khai báo nó vào AppModule luôn:

import { ConfigModule, ConfigService } from '@nestjs/config';
import { join } from 'path';
import { HandlebarsAdapter, MailerModule } from '@nest-modules/mailer';
...

@Module({
  imports: [
    MailerModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: async (config: ConfigService) => ({
        // transport: config.get("MAIL_TRANSPORT"),
        // or
        transport: {
          host: config.get('MAIL_HOST'),
          secure: false,
          auth: {
            user: config.get('MAIL_USER'),
            pass: config.get('MAIL_PASSWORD'),
          },
        },
        defaults: {
          from: `"No Reply" <${config.get('MAIL_FROM')}>`,
        },
        template: {
          dir: join(__dirname, 'src/templates/email'),
          adapter: new HandlebarsAdapter(),
          options: {
            strict: true,
          },
        },
      }),
      inject: [ConfigService],
    }),
    ...
  ],
  ...
})
export class AppModule {}

Ở đây mình đang set folder để chứa những template email là folder /src/templates/email. Và mình lấy những thông số của email dùng trong việc gửi mail, những thứ đó được cấu hình bên trong file .env

# MAIL
MAIL_HOST=smtp.gmail.com
MAIL_USER=datnquit@gmail.com
MAIL_PASSWORD=...
MAIL_FROM=${MAIL_USER}
MAIL_TRANSPORT=smtp://${MAIL_USER}:${MAIL_PASSWORD}@${MAIL_HOST}

Phân cấu hình email này có thể tham khảo cách lấy “mật khẩu ứng dụng” tại đây.

Vì file chúng ta nằm trong folder src, nhưng nó chỉ có view nên khi build nó không tự “bê” qua thư mục disk được, ta phải cấu hình. Hoặc các bạn có thể để phần view này bên ngoài thư mục src thì khỏi phải làm phần này:

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src"
  "sourceRoot": "src",
  "compilerOptions": {
    "assets": [
      { "include": "templates/**/*", "outDir": "dist/src" }
    ]
  }
}

Khi khai báo như này, thì sau khi build, trong folder disk sẽ có phần templates ta đã khai báo.

Xây dựng chức năng gửi Mail

Chúng ta sẽ tiến hành gửi mail chào mừng khi 1 user mới đăng ký:

Tạo welcome template nhẹ nhẹ

<p>Hello {{ name }}</p>
<p>Welcome to my website</p>

Trong hàm xử lý đăng ký cập nhật thêm phần gửi mail:

...
import { MailerService } from '@nest-modules/mailer';

@Injectable()
export class UserService {
  constructor(
    private readonly userRepository: UserRepository,
    private mailerService: MailerService,
  ) {}

  async create(userDto: CreateUserDto) {
    userDto.password = await bcrypt.hash(userDto.password, 10);

    // check exists
    const userInDb = await this.userRepository.findByCondition({
      email: userDto.email,
    });
    if (userInDb) {
      throw new HttpException('User already exists', HttpStatus.BAD_REQUEST);
    }

    await this.mailerService.sendMail({
      to: userDto.email,
      subject: 'Welcome to my website',
      template: './welcome',
      context: {
        name: userDto.name,
      },
    });

    return await this.userRepository.create(userDto);
  }
}

Kết luận

Trên đây mình giới thiệu về cách gửi maii và config mail. Nội dung phía trên hiện tại chỉ là kiến thức của mình, các bạn hãy thực hành nhiều để nó trở thành kiến thức của các bạn nhé! Hy vọng bài viết sẽ giúp ích cho các bạn trong quá trình học tập và làm việc.
Nếu có sai sót gì mong các bạn đóng góp ý kiến ở phần bình luận hoặc trao đổi trực tiếp qua Facebook hoặc Email mình có gắn phía cuối trang web.

Rất mong được sự ủng hộ của mọi người để mình có động lực ra những bài viết tiếp theo.
{\__/}
( ~.~ )
/ > ♥️ I LOVE YOU 3000

JUST DO IT!