-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[EN-6471] chore(newsletter): connect newsletter route to mailjet
- Loading branch information
Showing
5 changed files
with
253 additions
and
144 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,157 +1,150 @@ | ||
import { Injectable } from '@nestjs/common'; | ||
import _ from 'lodash'; | ||
import { connect, Email } from 'node-mailjet'; | ||
import { | ||
CustomContactParams, | ||
CustomMailParams, | ||
MailjetError, | ||
MailjetTemplates, | ||
MailjetContactList, | ||
MailjetContactTag, | ||
MailjetContactTagNames, | ||
MailjetCustomContact, | ||
MailjetCustomResponse, | ||
MailjetListActions, | ||
MailjetListIds, | ||
} from './mailjet.types'; | ||
import { createMail } from './mailjet.utils'; | ||
import SendParams = Email.SendParams; | ||
import SendParamsRecipient = Email.SendParamsRecipient; | ||
|
||
const useCampaigns = process.env.MAILJET_CAMPAIGNS_ACTIVATED === 'true'; | ||
|
||
@Injectable() | ||
export class MailjetService { | ||
private send: Email.PostResource; | ||
private contact: Email.PostResource; | ||
private mailjetTransactional: Email.Client; | ||
private mailjetNewsletter: Email.Client; | ||
|
||
constructor() { | ||
const mailjetTransactional = connect( | ||
this.mailjetTransactional = connect( | ||
`${process.env.MAILJET_PUB}`, | ||
`${process.env.MAILJET_SEC}` | ||
); | ||
|
||
this.send = mailjetTransactional.post('send', { | ||
version: 'v3.1', | ||
}); | ||
|
||
const mailjetNewsletter = connect( | ||
this.mailjetNewsletter = connect( | ||
`${process.env.MAILJET_NEWSLETTER_PUB}`, | ||
`${process.env.MAILJET_NEWSLETTER_SEC}` | ||
); | ||
|
||
this.contact = mailjetNewsletter.post('contact', { version: 'v3' }); | ||
} | ||
|
||
createMail({ | ||
toEmail, | ||
replyTo, | ||
subject, | ||
text, | ||
html, | ||
variables, | ||
templateId, | ||
}: CustomMailParams) { | ||
const recipients: SendParams['Messages'][number] = { | ||
To: [], | ||
Cc: [], | ||
From: { Email: '' }, | ||
}; | ||
if (typeof toEmail === 'string') { | ||
recipients.To = [{ Email: toEmail }]; | ||
} else if (Array.isArray(toEmail)) { | ||
recipients.To = toEmail.map((email) => { | ||
return { Email: email }; | ||
}); | ||
} else if (typeof toEmail === 'object') { | ||
const { to, cc, bcc } = toEmail; | ||
if (cc) { | ||
recipients.Cc = Array.isArray(cc) | ||
? cc.map((email) => { | ||
return { Email: email }; | ||
}) | ||
: [{ Email: cc }]; | ||
} | ||
if (to) { | ||
recipients.To = Array.isArray(to) | ||
? to.map((email) => { | ||
return { Email: email }; | ||
}) | ||
: [{ Email: to }]; | ||
} | ||
if (bcc) { | ||
recipients.Bcc = Array.isArray(bcc) | ||
? bcc.map((email) => { | ||
return { Email: email }; | ||
}) | ||
: [{ Email: bcc }]; | ||
} | ||
} | ||
|
||
const content = templateId | ||
? { | ||
Variables: { | ||
siteLink: process.env.FRONT_URL, | ||
...variables, | ||
}, | ||
TemplateID: templateId, | ||
CustomCampaign: useCampaigns | ||
? _.findKey(MailjetTemplates, (id) => { | ||
return id === templateId; | ||
}) | ||
: undefined, | ||
TemplateLanguage: true, | ||
TemplateErrorReporting: { | ||
Email: `${process.env.MAILJET_SUPPORT_EMAIL}`, | ||
Name: `${process.env.MAILJET_FROM_NAME}`, | ||
}, | ||
} | ||
: { | ||
'Text-part': text, | ||
'HTML-part': html, | ||
}; | ||
return { | ||
From: { | ||
Email: `${process.env.MAILJET_FROM_EMAIL}`, | ||
Name: `${process.env.MAILJET_FROM_NAME}`, | ||
}, | ||
Subject: subject, | ||
Headers: replyTo | ||
? { | ||
'Reply-To': replyTo, | ||
} | ||
: undefined, | ||
...recipients, | ||
...content, | ||
}; | ||
} | ||
|
||
async sendMail(params: CustomMailParams | CustomMailParams[]) { | ||
const mailjetParams: SendParams = { Messages: [] }; | ||
if (Array.isArray(params)) { | ||
mailjetParams.Messages = params.map((p) => { | ||
return this.createMail(p); | ||
return createMail(p); | ||
}); | ||
} else { | ||
mailjetParams.Messages = [this.createMail(params)]; | ||
mailjetParams.Messages = [createMail(params)]; | ||
} | ||
|
||
return this.send.request(mailjetParams); | ||
return this.mailjetTransactional | ||
.post('send', { | ||
version: 'v3.1', | ||
}) | ||
.request(mailjetParams); | ||
} | ||
|
||
createContact({ email /* status, zone */ }: CustomContactParams) { | ||
const contacts: SendParamsRecipient = { | ||
async findContact( | ||
email: CustomContactParams['email'] | ||
): Promise<MailjetCustomContact> { | ||
const contact: SendParamsRecipient = { | ||
Email: email.toLowerCase(), | ||
}; | ||
|
||
const { | ||
body: { Data: data }, | ||
} = (await this.mailjetNewsletter | ||
.get('contact', { version: 'v3' }) | ||
.request(contact)) as MailjetCustomResponse; | ||
|
||
return data[0]; | ||
} | ||
|
||
async createContact( | ||
email: CustomContactParams['email'] | ||
): Promise<MailjetCustomContact> { | ||
const contact: SendParamsRecipient = { | ||
Email: email, | ||
}; | ||
return contacts; | ||
const { | ||
body: { Data: data }, | ||
} = (await this.mailjetNewsletter | ||
.post('contact', { version: 'v3' }) | ||
.request(contact)) as MailjetCustomResponse; | ||
|
||
return data[0]; | ||
} | ||
|
||
async updateContactTags( | ||
id: string, | ||
{ zone, status }: Pick<CustomContactParams, 'zone' | 'status'> | ||
) { | ||
let dataToUpdate: { Data: MailjetContactTag[] } = { | ||
Data: [ | ||
{ | ||
Name: MailjetContactTagNames.NEWSLETTER, | ||
Value: true, | ||
}, | ||
], | ||
}; | ||
|
||
if (zone) { | ||
dataToUpdate = { | ||
Data: [ | ||
...dataToUpdate.Data, | ||
{ | ||
Name: MailjetContactTagNames.ZONE, | ||
Value: zone, | ||
}, | ||
], | ||
}; | ||
} | ||
if (status) { | ||
dataToUpdate = { | ||
Data: [ | ||
...dataToUpdate.Data, | ||
{ | ||
Name: MailjetContactTagNames.STATUS, | ||
Value: status, | ||
}, | ||
], | ||
}; | ||
} | ||
|
||
return this.mailjetNewsletter | ||
.put('contactdata', { version: 'v3' }) | ||
.id(id) | ||
.request(dataToUpdate); | ||
} | ||
|
||
async subscribeToNewsletterList(id: string) { | ||
const dataToUpdate: { ContactsLists: MailjetContactList[] } = { | ||
ContactsLists: [ | ||
{ | ||
Action: MailjetListActions.FORCE, | ||
ListID: MailjetListIds.NEWSLETTER, | ||
}, | ||
], | ||
}; | ||
|
||
return this.mailjetNewsletter | ||
.post('contact', { version: 'v3' }) | ||
.id(id) | ||
.action('managecontactslists') | ||
.request(dataToUpdate); | ||
} | ||
|
||
async sendContact(params: CustomContactParams) { | ||
const mailjetParams: SendParamsRecipient = this.createContact(params); | ||
|
||
try { | ||
await this.contact.request(mailjetParams); | ||
} catch (err) { | ||
console.error(err); | ||
// Check if not a duplicate value error, otherwise consider it as successful request | ||
if ( | ||
(err as MailjetError).statusCode !== 400 || | ||
!(err as MailjetError).ErrorMessage.includes('MJ18') | ||
) { | ||
throw err; | ||
} | ||
async sendContact({ email, zone, status }: CustomContactParams) { | ||
let contact = await this.findContact(email); | ||
if (!contact) { | ||
contact = await this.createContact(email); | ||
} | ||
await this.subscribeToNewsletterList(contact.ID); | ||
await this.updateContactTags(contact.ID, { zone, status }); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.