YesCoding

Go to English
search:

Nestjs EjsAdaptor email template ๋งŒ๋“ค๊ธฐ

thumbnail_nestjs_ejsadapter

ํšŒ์‚ฌ์—์„œ ์ธ์ฆ ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๋˜ ์ค‘, ํšŒ์›๊ฐ€์ž… ์ด๋ฉ”์ผ confirm ํ™•์ธ ๋ฉ”์ผ๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ ๋ณ€๊ฒฝ ํ™•์ธ ๋ฉ”์ผ ๋“ฑ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ฉ”์ผ๋“ค์„ ๋ณด๋‚ด์•ผ ํ•ด์„œ EjsAdapter + nestjs mailer module ์„ ์จ์„œ ํ…œํ”Œ๋ฆฟ์„ ๋งŒ๋“ค์–ด ๋†“๊ณ  mail service ํ•จ์ˆ˜๋ฅผ ์žฌ์‚ฌ์šฉํ•˜์˜€๋‹ค.

๊ธฐ์กด ์ฝ”๋“œ

import { MailerModule } from '@nestjs-modules/mailer'; import { EjsAdapter } from '@nestjs-modules/mailer/dist/adapters/ejs.adapter'; import { Module } from '@nestjs/common'; import { ConfigModule, ConfigService } from '@nestjs/config'; @Module({ imports: [ MailerModule.forRootAsync({ imports: [ConfigModule], inject: [ConfigService], useFactory: (configService: ConfigService) => ({ transport: { host: 'smtp.gmail.com', port: 587, secure: false, auth: { user: configService.get<string>('SMTP_AUTH_USER'), pass: configService.get<string>('SMTP_AUTH_PW'), }, }, defaults: { from: process.env.SUPPORT_EMAIL, }, template: { dir: `${path.resolve(__dirname, '../../templates')}`, adapter: new EjsAdapter(), options: { strict: true, }, }, }), }), ], }) export class MailModule {}

๋ฆฌํŒฉํ† ๋ง ์ „)

์ด๋ ‡๊ฒŒ mail Module ์„ ๋งŒ๋“ค์–ด๋†“๊ณ , ์ด๋ฉ”์ผ์„ ๋ณด๋‚ด์•ผ ํ•˜๋Š” ์„œ๋น„์Šค ํ•จ์ˆ˜์—์„œ ์•„๋ž˜์ฒ˜๋Ÿผ mailerService.sendMail ์„ ํ˜ธ์ถœํ–ˆ์—ˆ๋‹ค. (mailerService ๋Š” nestjs mailer ๋ชจ๋“ˆ์—์„œ ์ œ๊ณต)

await this.mailerService .sendMail({ to: email, from: this.configService.get<string>('SMTP_AUTH_USER'), subject: 'Sign Up', text: 'welcome', html: ` <div style="text-align: center; padding: 20px"> <h3>Email Verification</h3> <p> Please click the button below to confirm your email and finish setting up your account. This link is valid for <span style="color: red; font-weight: bold">24 hours</span></p> <a role="button" style=" border: 1px solid; border-radius: 17px; padding: 10px; color: black; text-decoration: none; display: inline-block; margin-bottom: 15px; " href="${signUpLink}" > Confirm </a> </div> `, })

์ดํ›„์— ๋น„๋ฐ€๋ฒˆํ˜ธ ์žฌ์„ค์ • ์ปจํŽŒ ์ด๋ฉ”์ผ ์ž‘์—…์„ ํ•˜๋ ค๋‹ค๋ณด๋‹ˆ ์ค‘๋ณต ์ฝ”๋“œ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒƒ ๊ฐ™์•„

๋ฆฌํŒฉํ† ๋งํ•ด์„œ sendMail ํ•จ์ˆ˜๋กœ ๋ฐ”๊ฟ”์„œ ์•ž์œผ๋กœ ๋ฉ”์ผ๋“ค์ด ์ถ”๊ฐ€๋˜์–ด๋„ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ๋‹ค.

์ตœ์ข… ์ฝ”๋“œ

const signUplogic = async (signUpRequestDto: SignUpRequestDto): Promise<void> => { // do business logic... await this.mailerService .sendMail({ to: email, from: this.configService.get<string>('SMTP_AUTH_USER'), subject: 'Sign Up', template: 'sign-up-confirm' }) } const resetPassword = async (resetPasswordDto: ResetPasswordDto): Promise<void> => { // do business logic.. await this.mailerService .sendMail({ to: email, from: this.configService.get<string>('SMTP_AUTH_USER'), subject: 'Reset your password', template: 'reset-password-confirm' }) } // create root/templates/sign-up-confirm.ejs // create root/templates/reset-password-confirm.ejs

์„ค์ • ๋œฏ์–ด๋ณด๊ธฐ

// mailModule template: { dir: `${path.resolve(__dirname, '../../templates')}`, adapter: new EjsAdapter(), options: { strict: true, }, },

__dirname ์ด๋ž€ nestjs ๋Š” typescript ๋กœ ์ž‘์„ฑ๋œ ์ฝ”๋“œ๋ฅผ ํ•œ ๋ฒˆ compile ํ•ด javascript ๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค์Œ, dist ํด๋” ์•ˆ์— ์žˆ๋Š” Main.js ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค. __dirname ์€ ์‹คํ–‰ ์‹œ ํ˜„์žฌ ํŒŒ์ผ๋ช…๊ณผ ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ์˜๋ฏธํ•œ๋‹ค. file ๋ช…์„ ์ œ์™ธํ•œ ์ ˆ๋Œ€ ๊ฒฝ๋กœ์ด๋‹ค. ๊ทธ๋ž˜์„œ ์‹คํ–‰ ๋‹น์‹œ์—๋Š” src ๊ฐ€ ์•„๋‹ˆ๋ผ dist ์•ˆ์— ์žˆ๋Š” dist/templates ๋ฅผ ์ฐพ์„ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— src/templates ๋ฅผ dist ๋กœ ์˜ฎ๊ฒจ์ฃผ์–ด์•ผ ํ•œ๋‹ค.

nest-cli.json ์—๋Š” compiler option ์„ ์ค„ ์ˆ˜ ์žˆ๋‹ค.

"compilerOptions": { "assets": ["**/*.ejs"], "watchAssets": true },

nest-cli.json ์— ์œ„ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ , ๋กœ์ปฌ ์„œ๋ฒ„๋ฅผ ํ•œ ๋ฒˆ ๊ป๋‹ค๊ฐ€ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๋ฉด dist ํด๋”์— templates ํด๋”๊ฐ€ ์ž˜ ์ƒ์„ฑ๋จ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์ž˜ ์ƒ์„ฑ๋œ dist

์ž˜ ์ƒ์„ฑ๋œ dist

Q. yarn start:local ์„ ํ–ˆ๋Š”๋ฐ __dirname ์ด dist/src/mail/templates ๋กœ ๋˜์–ด ์žˆ์–ด ๋ชป ์ฐพ๊ณ  ์žˆ๋‹ค. ๋ฉ”์ผ ํ…œํ”Œ๋ฆฟ๋“ค์€ dist/templates ์— ์œ„์น˜ํ•œ๋‹ค. ์–ด๋–ป๊ฒŒ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์„๊นŒ?

์œ„ ์ฝ”๋“œ์—์„œ๋Š”

// MailModule template: { dir: `${path.resolve(__dirname, '../../templates')}`, adapter: new EjsAdapter(), options: { strict: true, }, },

์ด๋ ‡๊ฒŒ ๋˜์–ด ์žˆ์ง€๋งŒ ์›๋ž˜๋Š” dir: ${__dirname}/templates ๋กœ ๋˜์–ด ์žˆ์—ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ํ–ˆ์„ ๋•Œ __dirname ์ด dist/src/mail/templates ๋กœ ๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์–ด์„œ path module ์˜ resolve ๋ฉ”์†Œ๋“œ๋ฅผ ์จ์„œ ํ•ด๊ฒฐํ•˜์˜€๋‹ค.

Q. ejs ํŒŒ์ผ์— ๋ณ€์ˆ˜๋ฅผ ์–ด๋–ป๊ฒŒ ๋„˜๊ธฐ๋‚˜? mailer module ์˜ context ์˜ต์…˜ ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค. template options ์— strict ๋ชจ๋“œ๋ฅผ ๊บผ์ฃผ๊ฑฐ๋‚˜, ์ผœ์•ผ ํ•œ๋‹ค๋ฉด ๋ณ€์ˆ˜ ์•ž์— locals ๋ฅผ ๋ถ™์—ฌ์ค€๋‹ค.

template: { dir: `${__dirname}/templates`, adapter: new EjsAdapter(), options: { strict: true, }, },
href="<%=locals.signUpLink}"%>
Recommend Post
nestjs request dto and response dto
nestjs request dto and response dto
nestjs env variable troubleshooting
nestjs env variable troubleshooting
TypeORM soft delete on cascade
TypeORM soft delete on cascade
tyepORM entity์—์„œ ๋น„๋ฐ€๋ฒˆํ˜ธ hash ํ•˜๊ธฐ
tyepORM entity์—์„œ ๋น„๋ฐ€๋ฒˆํ˜ธ hash ํ•˜๊ธฐ
ยฉ Copyright 2022, YesCoding