email.service.ts 4.66 KB
Newer Older
1
import { Injectable, Logger, InternalServerErrorException } from '@nestjs/common';
2
import * as amqp from 'amqplib';
FORESTIER Fabien's avatar
FORESTIER Fabien committed
3
import { ContactForm, Email, EmailWithoutFrom, FeedbackForm } from './email';
4
5
import { ConfigService } from '../configuration/config.service';
import { buildContactAdminEmail, buildContactUserEmail } from '../email-templates/contact';
6
import moment = require('moment');
FORESTIER Fabien's avatar
FORESTIER Fabien committed
7
import { buildFeedbackEmail } from '../email-templates/feedback';
FORESTIER Fabien's avatar
FORESTIER Fabien committed
8
import * as useragent from 'useragent';
ncastejon's avatar
ncastejon committed
9
10
11

@Injectable()
export class EmailService {
12
  config: any = {};
ncastejon's avatar
ncastejon committed
13

14
15
16
17
  constructor(private configService: ConfigService) {
    this.config = this.configService.config;
  }

18
19
20
21
22
23
24
25
26
  async sendContactEmails(contactForm: ContactForm) {
    Logger.log('[-] sendContactEmails method');

    const adminEmailBody = buildContactAdminEmail({
      subject: contactForm.subject,
      message: contactForm.text,
      firstName: contactForm.firstname,
      lastName: contactForm.lastname,
      email: contactForm.email,
27
28
      datetime: moment().format('DD/MM/YYYY à HH:mm'),
      imageHost: this.config.imageHost,
29
30
31
32
    });
    const userEmailBody = buildContactUserEmail({
      subject: contactForm.subject,
      message: contactForm.text,
33
34
35
      firstName: contactForm.firstname,
      datetime: moment().format('DD/MM/YYYY à HH:mm'),
      imageHost: this.config.imageHost,
36
37
38
    });

    const adminEmail = new EmailWithoutFrom();
39
    adminEmail.to = [this.config.userSupportMailbox];
40
    adminEmail.replyTo = contactForm.email;
41
42
43
44
45
46
47
48
49
50
    adminEmail.subject = contactForm.subject;
    adminEmail.html = adminEmailBody;

    const userEmail = new EmailWithoutFrom();
    userEmail.to = [contactForm.email];
    userEmail.subject = contactForm.subject;
    userEmail.html = userEmailBody;

    await this.send(adminEmail);
    await this.send(userEmail);
FORESTIER Fabien's avatar
FORESTIER Fabien committed
51
52
53
54

    return;
  }

FORESTIER Fabien's avatar
FORESTIER Fabien committed
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
  async sendFeedback(feedbackForm: FeedbackForm, userAgent) {
    Logger.log('[-] sendFeedback method');

    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();
76
    feedbackEmail.to = [this.config.userSupportMailbox];
FORESTIER Fabien's avatar
FORESTIER Fabien committed
77
78
79
80
81
82
83
84
    feedbackEmail.subject = 'Feedback';
    feedbackEmail.html = feedbackEmailBody;

    await this.send(feedbackEmail);

    return;
  }

85
  async send(emailInfo: EmailWithoutFrom) {
FORESTIER Fabien's avatar
FORESTIER Fabien committed
86
87
88
89
90
    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
91
    let email = new Email();
92
    email.from = this.config.userSupportMailbox;
93
    email = Object.assign(email, emailInfo);
FORESTIER Fabien's avatar
FORESTIER Fabien committed
94

FORESTIER Fabien's avatar
FORESTIER Fabien committed
95
96
97
98
    if (this.config.emailSubjectPrefix) {
      email.subject = `[${this.config.mailSubjectPrefix}] ${email.subject}`;
    }

FORESTIER Fabien's avatar
FORESTIER Fabien committed
99
100
101
102
103
104
105
106
107
108
109
110
    Logger.log('[-] send method');
    Logger.log(email);

    // Connect to rabbitmq
    try {
      conn = await amqp.connect(rabbitmqUrl);
    } catch (error) {
      Logger.error('    [x] Error connecting to RabbitMQ: ', JSON.stringify(error));
      throw new InternalServerErrorException('Could not connect to rabbitMQ.');
    }

    try {
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
      // Create a communication channel
      ch = await conn.createChannel();
    } catch (error) {
      Logger.error('    [x] Error creating channel: ', JSON.stringify(error));
      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) {
      Logger.error('    [x] Error creating channel: ', JSON.stringify(error));
      throw new InternalServerErrorException('Could not assert channel.');
    }

    try {
      await ch.sendToQueue(mailerQueue, buffer, { persistent: true });
    } catch (error) {
      Logger.error('    [x] Error sending to queue: ', JSON.stringify(error));
      throw new InternalServerErrorException('Could not send to queue.');
    }

    Logger.log(`Sent to queue ${mailerQueue}: ${JSON.stringify(email)}`);

    setTimeout(() => { conn.close(); }, 500);

    return;
ncastejon's avatar
ncastejon committed
140
141
142
  }

}