Skip to content
Snippets Groups Projects
email.service.ts 5.29 KiB
Newer Older
  • Learn to ignore specific revisions
  • import { Injectable, Logger, InternalServerErrorException } from '@nestjs/common';
    
    import * as amqp from 'amqplib';
    
    FORESTIER Fabien's avatar
    FORESTIER Fabien committed
    import { ContactForm, Email, EmailWithoutFrom, FeedbackForm } from './email';
    
    import { ConfigService } from '../configuration/config.service';
    import { buildContactAdminEmail, buildContactUserEmail } from '../email-templates/contact';
    
    FORESTIER Fabien's avatar
    FORESTIER Fabien committed
    import { buildFeedbackEmail } from '../email-templates/feedback';
    
    FORESTIER Fabien's avatar
    FORESTIER Fabien committed
    import * as useragent from 'useragent';
    
    import moment = require('moment-timezone');
    moment.tz.setDefault('Europe/Paris');
    
    
    @Injectable()
    export class EmailService {
    
      config: any = {};
    
      constructor(private configService: ConfigService) {
    
        this.logger = new Logger(EmailService.name);
    
        this.config = this.configService.config;
      }
    
    
      async sendContactEmails(contactForm: ContactForm) {
    
        this.logger.log('Entering function', `${EmailService.name} - ${this.sendContactEmails.name}`);
    
    
        const adminEmailBody = buildContactAdminEmail({
          subject: contactForm.subject,
          message: contactForm.text,
          firstName: contactForm.firstname,
          lastName: contactForm.lastname,
          email: contactForm.email,
    
          datetime: moment().format('DD/MM/YYYY à HH:mm'),
          imageHost: this.config.imageHost,
    
        });
        const userEmailBody = buildContactUserEmail({
          subject: contactForm.subject,
          message: contactForm.text,
    
          firstName: contactForm.firstname,
          datetime: moment().format('DD/MM/YYYY à HH:mm'),
          imageHost: this.config.imageHost,
    
        });
    
        const adminEmail = new EmailWithoutFrom();
    
        adminEmail.to = [this.config.userSupportMailbox];
    
        adminEmail.replyTo = contactForm.email;
    
        adminEmail.subject = contactForm.subject;
        adminEmail.html = adminEmailBody;
    
        const userEmail = new EmailWithoutFrom();
        userEmail.to = [contactForm.email];
    
        userEmail.replyTo = this.config.userSupportMailbox;
    
        userEmail.subject = contactForm.subject;
        userEmail.html = userEmailBody;
    
        await this.send(adminEmail);
        await this.send(userEmail);
    
    FORESTIER Fabien's avatar
    FORESTIER Fabien committed
      async sendFeedback(feedbackForm: FeedbackForm, userAgent) {
    
        this.logger.log('Entering function', `${EmailService.name} - ${this.sendFeedback.name}`);
    
    FORESTIER Fabien's avatar
    FORESTIER Fabien committed
    
        const userAgentParsed = useragent.parse(userAgent);
        let userAgentString = '';
    
        if (userAgentParsed) {
          userAgentString = `Family: ${userAgentParsed.family},`;
          userAgentString += `Version:${userAgentParsed.major}.${userAgentParsed.minor}.${userAgentParsed.patch},`;
          userAgentString += `Source: ${userAgentParsed.source}`;
        }
    
        const feedbackEmailBody = buildFeedbackEmail({
          url: feedbackForm.url,
          userAgent: userAgentString,
          version: feedbackForm.version,
          message: feedbackForm.message,
          datetime: moment().format('DD/MM/YYYY à HH:mm'),
          imageHost: this.config.imageHost,
        });
        const feedbackEmail = new EmailWithoutFrom();
    
        feedbackEmail.to = [this.config.userSupportMailbox];
    
    
        if (this.config.additionalFeedbackEmails) {
          feedbackEmail.to = feedbackEmail.to.concat(this.config.additionalFeedbackEmails.split(','));
        }
    
    
    FORESTIER Fabien's avatar
    FORESTIER Fabien committed
        feedbackEmail.subject = 'Feedback';
        feedbackEmail.html = feedbackEmailBody;
    
        await this.send(feedbackEmail);
    
        return;
      }
    
    
      async send(emailInfo: EmailWithoutFrom) {
    
        this.logger.log('Entering function', `${EmailService.name} - ${this.send.name}`);
    
    
    FORESTIER Fabien's avatar
    FORESTIER Fabien committed
        let conn, ch;
        // tslint:disable-next-line:max-line-length
        const rabbitmqUrl = `amqp://${this.config.rabbitMQ.user}:${this.config.rabbitMQ.password}@${this.config.rabbitMQ.host}:${this.config.rabbitMQ.port}`;
        const mailerQueue = this.config.mailerQueue;
    
    
    FORESTIER Fabien's avatar
    FORESTIER Fabien committed
        let email = new Email();
    
        email.from = this.config.noReplyMailAddress;
    
        email = Object.assign(email, emailInfo);
    
        if (this.config.mailSubjectPrefix) {
    
          email.subject = `[${this.config.mailSubjectPrefix}] ${email.subject}`;
        }
    
    
    FORESTIER Fabien's avatar
    FORESTIER Fabien committed
        // Connect to rabbitmq
        try {
          conn = await amqp.connect(rabbitmqUrl);
        } catch (error) {
    
          this.logger.error('Error connecting to RabbitMQ', error, `${EmailService.name} - ${this.send.name}`);
    
    FORESTIER Fabien's avatar
    FORESTIER Fabien committed
          throw new InternalServerErrorException('Could not connect to rabbitMQ.');
        }
    
        try {
    
          // Create a communication channel
          ch = await conn.createChannel();
        } catch (error) {
    
          this.logger.error('Error creating channel', error, `${EmailService.name} - ${this.send.name}`);
    
          throw new InternalServerErrorException('Could not create channel.');
        }
    
        // Stringify and bufferise message
        const buffer = Buffer.from(JSON.stringify(email));
    
        try {
          await ch.assertQueue(mailerQueue, { durable: true });
        } catch (error) {
    
          this.logger.error('Error asserting queue', error, `${EmailService.name} - ${this.send.name}`);
    
          throw new InternalServerErrorException('Could not assert queue.');
    
        }
    
        try {
          await ch.sendToQueue(mailerQueue, buffer, { persistent: true });
        } catch (error) {
    
          this.logger.error('Error sending to queue', error, `${EmailService.name} - ${this.send.name}`);
    
          throw new InternalServerErrorException('Could not send to queue.');
        }
    
    
        this.logger.log(
    
          `Sent to queue ${mailerQueue},{ from: ${email.from}, to: ${email.to}, subject: ${email.subject}}`, `${EmailService.name} - ${this.send.name}`,
        );
    
    
        setTimeout(() => { conn.close(); }, 500);
        return;