import { Injectable, Logger } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { MailRecipient, NotificationMailer, } from '@task-stream/api/tracker/application'; import { NotificationReadModel } from '@task-stream/api/tracker/domain'; import { createTransport, Transporter } from 'nodemailer'; /** * E-mail copies through SMTP_URL (`smtps://user:pass@smtp.example.org`). * Without it nothing is sent and nobody is offered e-mail. */ @Injectable() export class SmtpNotificationMailer extends NotificationMailer { private readonly logger = new Logger(SmtpNotificationMailer.name); private readonly transport: Transporter | null; private readonly from: string; private readonly webUrl: string; constructor(config: ConfigService) { super(); const url = config.get('SMTP_URL'); this.transport = url ? createTransport(url) : null; this.from = config.get('MAIL_FROM') || 'TaskStream '; this.webUrl = (config.get('WEB_URL') || '').replace(/\/+$/, ''); if (this.transport) this.logger.log('E-mail notifications enabled'); } get enabled(): boolean { return this.transport !== null; } async send( to: MailRecipient, notification: NotificationReadModel, ): Promise { if (!this.transport) return; const link = this.linkTo(notification); const subject = notification.issueKey ? `[${notification.issueKey}] ${notification.summary}` : `[${notification.projectKey}] ${notification.summary}`; await this.transport.sendMail({ from: this.from, to: { name: to.name, address: to.email }, subject: subject.length > 160 ? `${subject.slice(0, 159)}…` : subject, text: [ `Hola ${to.name}:`, '', notification.summary, ...(link ? ['', link] : []), '', '— TaskStream. Puedes dejar de recibir estos correos desde las notificaciones de la app.', ].join('\n'), }); } private linkTo(notification: NotificationReadModel): string | null { if (!this.webUrl) return null; const project = encodeURIComponent(notification.projectKey); return notification.issueKey ? `${this.webUrl}/p/${project}/issues/${encodeURIComponent(notification.issueKey)}` : `${this.webUrl}/p/${project}`; } }