All files / mail/services send.service.ts

100% Statements 19/19
100% Branches 5/5
100% Functions 3/3
100% Lines 18/18

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 543x 3x 3x 3x       3x           3x 3x   3x   3x 3x 3x       29x 29x 24x         29x 29x 29x                           24x            
import { Inject, Injectable, Logger } from '@nestjs/common'
import { renderFile } from 'ejs'
import { Transporter, createTransport } from 'nodemailer'
import { join } from 'path'
import { MailData } from '../../db/entities/mail-event.entity'
import { MailModuleConfig } from '../interfaces/mail-module.interface'
import { MailTemplateContent } from '../interfaces/mail.interface'
import { MODULE_OPTIONS_TOKEN } from '../metadata/mail.module-definition'
 
/**
 * @description Service reliable for actually talking to the http server
 */
@Injectable()
export class MailSendService {
  private logger = new Logger(MailSendService.name)
  private transport: Transporter
  private readonly templateDir = join(__dirname, '..', 'templates')
  private defaultFrom: string
  constructor(@Inject(MODULE_OPTIONS_TOKEN) private options: MailModuleConfig) {
    this.transport = createTransport(options.transport, options.defaults)
    this.defaultFrom = options.defaultSender
  }
 
  async sendMail(mail: MailData): Promise<void> {
    let mailContent = mail.content.contentRaw
    if (mail.content.contentTemplate) {
      mailContent = await this.renderTemplate(
        mail.content.contentTemplate,
        mail.content.templateContent,
      )
    }
    const { recipient, cc, from } = mail.recipient
    this.logger.debug(`Sending mail to ${recipient}`)
    await this.transport.sendMail({
      to: recipient,
      cc: cc,
      from: from || this.defaultFrom,
      subject: mail.content.subject,
      // Assume always HTML...our emails SHOULD be styled anyways
      html: mailContent,
    })
  }
 
  private renderTemplate(
    templateName: string,
    content: MailTemplateContent,
  ): string {
    return renderFile(
      join(this.templateDir, `${templateName}.template.ejs`),
      content || {},
    )
  }
}