import SendgridClient from '@sendgrid/client' import * as SendgridHelpers from '@sendgrid/helpers' import SendgridMail from '@sendgrid/mail' import moment from 'moment' import fetch from 'node-fetch' import Constants from '../../constants/general' import GeneralUtils from '../general' import { logger } from '../logger' import { TemplateNameTypes, SendInputType, TemplateDataType } from './types' SendgridMail.setApiKey(process.env.SENDGRID_API_KEY) SendgridMail.setSubstitutionWrappers('{{{', '}}}') SendgridClient.setApiKey(process.env.SENDGRID_API_KEY) // CAREFUL: The name of the template must be the same as in Sendgrid and our email service. // That's why at the end we do a replace all _ with - and put to lower case const getSendGridTemplateDataForTemplateName = (template: TemplateNameTypes): TemplateDataType => { if (!template) { return null } let sendGridTemplateId = '' switch (template) { case 'RESIDENT_WELCOME': sendGridTemplateId = 'd-136b71acf7054b2bb39e24ece7a6cab2' break case 'RESIDENT_WELCOME_FR': sendGridTemplateId = 'd-0612d8c2805a4a58973f1b7470bcd6e0' break case 'RESIDENT_FIRST_INVITE': sendGridTemplateId = 'd-ae34e8d5dc7a4dd0911b90fbd9f14ec1' break case 'RESIDENT_FIRST_INVITE_FR': sendGridTemplateId = 'd-453c1b9643324bd8a155d8db9a4e3e58' break case 'RESIDENT_SECOND_INVITE': sendGridTemplateId = 'd-ada26ab36b4344ff872c35698ecc87ce' break case 'RESIDENT_SECOND_INVITE_FR': sendGridTemplateId = 'd-ada26ab36b4344ff872c35698ecc87ce' break case 'RESIDENT_NEW_POST': sendGridTemplateId = 'd-3e477460982e419aa3fc9afa53f173c9' break case 'RESIDENT_NEW_POST_FR': sendGridTemplateId = 'd-1250fe02c7294b3d8b7fac09ff20f7ae' break case 'RESET_PASSWORD': sendGridTemplateId = 'd-85139475f7bb47f8a36c955312998fe5' break case 'RESET_PASSWORD_FR': sendGridTemplateId = 'd-779d629bcb104156beb58461cacd265f' break case 'ORDER_CONFIRMATION': sendGridTemplateId = 'd-2312c05f2c3d45ae8bfb1541945dc2cc' break case 'PARTNER_INVOICE': sendGridTemplateId = 'd-f6a68e8443ca4e138da079d369c3a33c' break case 'NEW_MESSAGE_TO_RESIDENT': sendGridTemplateId = 'd-68157f0e760347ed9315a3b27ce7e6b7' break case 'NEW_MESSAGE_TO_RESIDENT_FR': sendGridTemplateId = 'd-8fa41b4f467a44569f04dcfa3334cf8d' break case 'NEW_MESSAGE_TO_MANAGER': sendGridTemplateId = 'd-aeae5153836a49a6943c274afcf3c5c1' break case 'RESIDENT_GENERAL_NOTIFICATION_FR': sendGridTemplateId = 'd-c32fb9b53f3948f28cb1e062ae709a25' break case 'MANAGER_GENERAL_NOTIFICATION': sendGridTemplateId = 'd-764386bd5aad44c6ba76e9e5fafb969d' break case 'NEW_PROXY_FROM_MANAGER_FR': sendGridTemplateId = 'd-68753f7abfc740ae8580029282e74966' break case 'NEW_PROXY_FROM_MANAGER': sendGridTemplateId = 'd-22af4df2d9624299a1fa4235a72847dd' break case 'NEW_PROXY_COMPLETED_TO_RESIDENT': sendGridTemplateId = 'd-5af296b90ec5474ea8c3c34cc4eb8e1d' break case 'NEW_PROXY_COMPLETED_TO_RESIDENT_FR': sendGridTemplateId = 'd-5f65f6c829c64389ab56cde7e009cfd5' break case 'NEW_PROXY_COMPLETED_TO_MANAGER': sendGridTemplateId = 'd-11592d03f73644faa8377d5b8cf492b5' break case 'PRIVATE_CONVERSATION_MENTIONED': sendGridTemplateId = 'd-96291ec180b843e7888ceac7d9d3944f' break case 'PROVIDER_ORDER_REQUEST_SUMMARY': sendGridTemplateId = 'd-ecab6982b2a043c1b903ce41a74e775b' break case 'COVID19_NEW_SERVICES': sendGridTemplateId = 'd-8e3028ae871c469f9db4f8e2e7d17dc8' break case 'COVID19_NEW_SERVICES_FR': sendGridTemplateId = 'd-010b6061bb584e8b9253bed21e1e2e04' break case 'RESIDENT_GENERAL_NOTIFICATION': default: sendGridTemplateId = 'd-036928b286e2463298d71b66404a0b29' break } return { id: sendGridTemplateId, name: template.toLowerCase().replace(/_/g, '-'), } } export const send = async ({ to, from = { email: Constants.EMAIL_COMMUNICATION_WALTER_FROM_EMAIL, name: Constants.EMAIL_COMMUNICATION_WALTER_FROM_NAME, }, text, html, subject, template, attachments, customVariables, customArgs, }: SendInputType) => { const sendGridTemplateData: TemplateDataType = getSendGridTemplateDataForTemplateName(template) const mail = new SendgridHelpers.classes.Mail() // FROM mail.setFrom(from) // SUBJECT mail.setSubject(subject) // CUSTOM ARGS mail.setCustomArgs(customArgs) // CONTENT if (html) { mail.addHtmlContent(html) } else if (text) { mail.addTextContent(text) } else { mail.setTemplateId(sendGridTemplateData.id) mail.setPersonalizations([ { to, customArgs: { emailTemplate: template, }, dynamicTemplateData: { // Used in email service to view email online paramsEncodedAndStringify: GeneralUtils.serializeObjForQueryString( customVariables || {}, '' ), templateName: sendGridTemplateData.name, subject, // In email service, at some place we use it as variable also, ...customVariables, }, }, ]) } // ATTACHMENTS if (attachments?.length > 0) { const attachmentsWithData = await Promise.all( attachments.map((attachment) => fetch(attachment.url) .then((res) => res.buffer()) .then((data) => ({ data, ...attachment, })) ) ) mail.setAttachments( attachmentsWithData.map((attachment) => ({ filename: GeneralUtils.removeAccents(attachment.filename) || `attachment-${moment().unix()}`, content: attachment.data.toString('base64'), type: attachment.type, disposition: 'attachment', })) ) } // LOG FOR DEV if (process.env.NODE_ENV === 'development') { if (process.env.SEND_EMAIL !== 'true') { logger.info("✉️❌ Don't send because SEND_EMAIL is at false") return Promise.resolve() } } // @ts-ignore for now... return SendgridMail.send(mail.toJSON()) // TODO: To revise... not working well and maybe useless // Need to do this if we couldn't send because of x, y, z reason... // if (error?.response?.body?.errors) { // logger.error(error.response.body.errors) // // User can't receive email // if ( // error.response.body.errors.some( // error => error.message === 'Does not contain a valid address.' // ) // ) { // UserController.querySingleUser({ emails: emailTos }) // .then( // user => // user && // prisma.user.update({ // where: { id: user.id }, // data: { // cantDeliverEmail: true, // cantDeliverEmailReason: 'INVALID_EMAIL', // cantDeliverEmailFullReason: `Invalid email` // } // }) // ) // .catch(logger.error) // } // } }