From e4d8f7bb3e7f679141ecf33c88180cb4bf81cc9b Mon Sep 17 00:00:00 2001 From: Josepablo C Date: Sun, 2 Mar 2025 22:33:48 -0600 Subject: [PATCH] feat(SendGrid): Disable SendGrid support and use Mail API instead --- v1/src/apps/public/account/services.js | 2 +- .../Handlers/MailClient/SendGrid.handler.js | 3 +- .../Handlers/MailClient/StandAlone.handler.js | 76 ++++++++++++++- .../MailClient/StandAlone/assets/eta_logo.png | Bin 0 -> 5974 bytes .../templates/accountVerifiedTemplate.js | 64 +++++++++++++ .../templates/accountVerifyTemplate.js | 81 ++++++++++++++++ .../templates/contactResponseTemplate.js | 54 +++++++++++ .../templates/recoveryPasswordTemplate.js | 73 +++++++++++++++ .../warehouseNotificationTemplate.js | 88 ++++++++++++++++++ v1/src/lib/Handlers/MailClient/index.js | 4 +- 10 files changed, 434 insertions(+), 11 deletions(-) create mode 100644 v1/src/lib/Handlers/MailClient/StandAlone/assets/eta_logo.png create mode 100644 v1/src/lib/Handlers/MailClient/StandAlone/templates/accountVerifiedTemplate.js create mode 100644 v1/src/lib/Handlers/MailClient/StandAlone/templates/accountVerifyTemplate.js create mode 100644 v1/src/lib/Handlers/MailClient/StandAlone/templates/contactResponseTemplate.js create mode 100644 v1/src/lib/Handlers/MailClient/StandAlone/templates/recoveryPasswordTemplate.js create mode 100644 v1/src/lib/Handlers/MailClient/StandAlone/templates/warehouseNotificationTemplate.js diff --git a/v1/src/apps/public/account/services.js b/v1/src/apps/public/account/services.js index d976c4f..8518f06 100644 --- a/v1/src/apps/public/account/services.js +++ b/v1/src/apps/public/account/services.js @@ -223,7 +223,7 @@ const RecoverPwd = async(req, res) => { otp }; const checksum = toSha256( JSON.stringify(checksum_entry)).substr(0, 32); - await emailEvent( EMAIL_EVENTS.ACCOUNT_VERIFY , receiver , content ); + await emailEvent( EMAIL_EVENTS.ACCOUNT_PWD_RESET , receiver , content ); console.log( content ); diff --git a/v1/src/lib/Handlers/MailClient/SendGrid.handler.js b/v1/src/lib/Handlers/MailClient/SendGrid.handler.js index 257e012..7bd693e 100644 --- a/v1/src/lib/Handlers/MailClient/SendGrid.handler.js +++ b/v1/src/lib/Handlers/MailClient/SendGrid.handler.js @@ -73,13 +73,12 @@ async function AccountPwdResetEmail( receiver, content ){ async function ContactEmail( receiver, content ){ const templateId = "d-1090dda1091442f3a75ee8ab39ad0f10"; const subject = "[ETA] Contact Email"; - const content_to_send = { + const content_to_send = { project_name: SiteName, user_name: content.name, user_email: receiver }; return await sendMailTemplate( templateId, receiver, subject, content_to_send ); } -//ContactEmail( "josepablo134@gmail.com", { email : "josepablo134@gmail.com", name:"Josepablo C.", message: "This is an example" } ).then().catch(); module.exports = { AccountVerifyEmail, AccountConfirmed, AccountPwdResetEmail, ContactEmail }; diff --git a/v1/src/lib/Handlers/MailClient/StandAlone.handler.js b/v1/src/lib/Handlers/MailClient/StandAlone.handler.js index 7bcd353..8e10e6c 100644 --- a/v1/src/lib/Handlers/MailClient/StandAlone.handler.js +++ b/v1/src/lib/Handlers/MailClient/StandAlone.handler.js @@ -1,15 +1,54 @@ 'user strict'; -const { ROOT_PATH, API_CONFIG } = process.env; const nodemailer = require("nodemailer"); +const apiConfig = require( '../../../config/apiConfig.json' ); -const apiConfig = require( `${ROOT_PATH}/${API_CONFIG}` ); +/** + * Load HTML templates + */ +const accountVerifiedTemplate = require('./StandAlone/templates/accountVerifiedTemplate'); +const accountVerifyTemplate = require('./StandAlone/templates/accountVerifyTemplate'); +const contactResponseTemplate = require('./StandAlone/templates/contactResponseTemplate'); +const recoveryPasswordTemplate = require('./StandAlone/templates/recoveryPasswordTemplate'); +const warehouseNotificationTemplate = require('./StandAlone/templates/warehouseNotificationTemplate'); const transporter = nodemailer.createTransport( apiConfig.email_standalone ); +const default_from = apiConfig.email_standalone.auth.user; + +function redirect_email( receiver ){ + /**TODO: Remove in production */ + const default_mail_list = [ + {pattern:"alex@etaviaporte.com",redirect:"alexandro.uc@etaviaporte.com"}, + {pattern:"testing@etaviaporte.com",redirect:"josepablo134@gmail.com"}, + {pattern:"pablo@etaviaporte.com",redirect:"josepablo134@gmail.com"} + ]; + for( let i=0; i< default_mail_list.length; i++ ){ + if( receiver.indexOf( default_mail_list[i].pattern ) >= 0 ){ + receiver = default_mail_list[i].redirect; + break;/** Set only the first match */ + } + } + return receiver +} + +async function sendMailTemplate( receiver, subject, html ){ + /**TODO: Remove in production */ + receiver = redirect_email( receiver ); + return await transporter.sendMail({ + from: `ETA Viaporte <${default_from}>`, + to: receiver, + subject, + html, + attachments:[{ + filename: 'eta_logo.png', + path: './StandAlone/assets/eta_logo.png', + cid: 'eta_logo' + }] + }); +} async function StandAloneContactEmail( content ){ - const default_from = apiConfig.email_standalone.auth.user; const receiver = "support@etaviaporte.com"; const {name, email, message } = content; return await transporter.sendMail({ @@ -19,6 +58,33 @@ async function StandAloneContactEmail( content ){ text: `\n\n The following is an email from : ${email}\n\n\n` + message }); } -//StandAloneContactEmail( { email : "josepablo134@gmail.com", name:"Josepablo C.", message: "This is an example" } ).then().catch(); -module.exports = { StandAloneContactEmail }; +async function AccountVerifyEmail( receiver, content ){ + const subject = "[ETA] Account Verification"; + const { user_name , OTP } = content; + const html = accountVerifyTemplate( user_name, OTP ); + return await sendMailTemplate( receiver, subject, html ); +} + +async function AccountConfirmed( receiver, content){ + const subject = "[ETA] Welcome to ETA"; + const { user_name } = content; + const html = accountVerifiedTemplate( user_name ); + return await sendMailTemplate( receiver, subject, html ); +} + +async function AccountPwdResetEmail( receiver, content ){ + const subject = "[ETA] Password Reset"; + const { user_name , OTP } = content; + const html = recoveryPasswordTemplate( user_name, OTP ); + return await sendMailTemplate( receiver, subject, html ); +} + +async function ContactEmail( receiver, content ){ + const subject = "[ETA] Contact Email"; + const { user_name } = content; + const html = contactResponseTemplate( user_name ); + return await sendMailTemplate( receiver, subject, html ); +} + +module.exports = { AccountVerifyEmail, AccountConfirmed, AccountPwdResetEmail, ContactEmail, StandAloneContactEmail }; diff --git a/v1/src/lib/Handlers/MailClient/StandAlone/assets/eta_logo.png b/v1/src/lib/Handlers/MailClient/StandAlone/assets/eta_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..22c1fbd267233042f68fddd96e0ba40c08f74be3 GIT binary patch literal 5974 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 literal 0 HcmV?d00001 diff --git a/v1/src/lib/Handlers/MailClient/StandAlone/templates/accountVerifiedTemplate.js b/v1/src/lib/Handlers/MailClient/StandAlone/templates/accountVerifiedTemplate.js new file mode 100644 index 0000000..9c802eb --- /dev/null +++ b/v1/src/lib/Handlers/MailClient/StandAlone/templates/accountVerifiedTemplate.js @@ -0,0 +1,64 @@ +'user strict'; + +module.exports = (name) => { + return ` +
+
+ Logo ETA Viaporte +

¡Bienvenido a ETA Viaporte!

+
+
+
+

Hola, ${name}!

+

+ Su cuenta se registro exitosamente, estas a solo unos pasos para completar tu perfil, da click en el siguiente botón y continua con el proceso. +

+ + Panel Eta Viaporte + +
+
+

+ Saludos cordiales,
+ Equipo de cuentas - ETA Viaporte +

+
+
+ `; +} diff --git a/v1/src/lib/Handlers/MailClient/StandAlone/templates/accountVerifyTemplate.js b/v1/src/lib/Handlers/MailClient/StandAlone/templates/accountVerifyTemplate.js new file mode 100644 index 0000000..2b8e102 --- /dev/null +++ b/v1/src/lib/Handlers/MailClient/StandAlone/templates/accountVerifyTemplate.js @@ -0,0 +1,81 @@ +'user strict'; + +module.exports = (name, otp) => { + return ` +
+
+ Logo ETA Viaporte +

¡Bienvenido a ETA Viaporte!

+
+
+
+

Hola, ${name}!

+

+ Verifica tu dirección de correo electrónico para completar tu registro en ETA Viaporte. +

+

Tu código de verificación:

+
+

+ ${otp} +

+
+

+ Este código es válido por 1 hora y solo se puede usar una vez. +

+
+
+

+ Hemos recibido una solicitud para crear una cuenta en ETA Viaporte utilizando tu correo electrónico. + Si no hiciste esta solicitud, puedes ignorar este mensaje. +

+

+ Saludos cordiales,
+ Equipo de cuentas - ETA Viaporte +

+
+
+ `; +} diff --git a/v1/src/lib/Handlers/MailClient/StandAlone/templates/contactResponseTemplate.js b/v1/src/lib/Handlers/MailClient/StandAlone/templates/contactResponseTemplate.js new file mode 100644 index 0000000..f4e943f --- /dev/null +++ b/v1/src/lib/Handlers/MailClient/StandAlone/templates/contactResponseTemplate.js @@ -0,0 +1,54 @@ +'user strict'; + +module.exports = (name) => { + return ` +
+
+ Logo ETA Viaporte +
+
+
+

Hola, ${name}!

+
+

¡Gracias por contactarnos!

+

Recibimos tu consulta y puede llevar algún tiempo responderla. Mientras tanto, puedes consultar nuestras preguntas frecuentes en: FAQS Eta Viaporte

+

Nuestro horario de atención es lunes a viernes de 09:00 a 18:00 (GMT-7)

+

¡Agradecemos tu paciencia y comprensión!

+ +
+
+
+

+ Saludos cordiales,
+ Equipo de cuentas - ETA Viaporte +

+
+
+ `; +} diff --git a/v1/src/lib/Handlers/MailClient/StandAlone/templates/recoveryPasswordTemplate.js b/v1/src/lib/Handlers/MailClient/StandAlone/templates/recoveryPasswordTemplate.js new file mode 100644 index 0000000..ae4b340 --- /dev/null +++ b/v1/src/lib/Handlers/MailClient/StandAlone/templates/recoveryPasswordTemplate.js @@ -0,0 +1,73 @@ +'user strict'; + +module.exports = (name, otp) => { + return ` +
+
+ Logo ETA Viaporte +
+
+
+

Hola, ${name}!

+

+ Hemos recibido una solicitud para restablecer su contraseña de ETA Viaporte utilizando tu correo electrónico. + Si no hiciste esta solicitud, puedes ignorar este mensaje. +

+

Tu código de verificación:

+
+

+ ${otp} +

+
+

+ Este código es válido por 1 hora y solo se puede usar una vez. +

+
+
+

+ Saludos cordiales,
+ Equipo de cuentas - ETA Viaporte +

+
+
+ `; +} diff --git a/v1/src/lib/Handlers/MailClient/StandAlone/templates/warehouseNotificationTemplate.js b/v1/src/lib/Handlers/MailClient/StandAlone/templates/warehouseNotificationTemplate.js new file mode 100644 index 0000000..7148dc9 --- /dev/null +++ b/v1/src/lib/Handlers/MailClient/StandAlone/templates/warehouseNotificationTemplate.js @@ -0,0 +1,88 @@ +'user strict'; + +module.exports = (code, date, company, product, plate, truck_type, driver, note) => { + return ` +
+
+ Logo ETA Viaporte +

¡Nueva carga asignada ${code}!

+
+
+
+

+ Se ha asignado nueva carga con código ${code} a la bodega +

+
+

Detalles de la carga

+
    +
  • Código de carga: ${code}
  • +
  • Fecha de carga: ${date}
  • +
  • Empresa: ${company}
  • +
  • Producto: ${product}
  • +
  • Placas tracto camión: ${plate}
  • +
  • Tipo de transporte: ${truck_type}
  • +
  • Operador: ${driver}
  • +
  • Nota: ${note}
  • +
+
+ + Panel ETA Viaporte + +
+
+

+ Este correo ha sido generado automáticamente. No es necesario responder, ya que no se monitorean las respuestas a este mensaje. +

+

+ Equipo ETA Viaporte +

+
+
+ `; +} diff --git a/v1/src/lib/Handlers/MailClient/index.js b/v1/src/lib/Handlers/MailClient/index.js index 8242b01..765f9e1 100644 --- a/v1/src/lib/Handlers/MailClient/index.js +++ b/v1/src/lib/Handlers/MailClient/index.js @@ -1,7 +1,5 @@ 'user strict'; -const { ROOT_PATH, HANDLERS_PATH, MODELS_PATH, API_CONFIG } = process.env; -const { StandAloneContactEmail } = require('./StandAlone.handler'); -const { AccountVerifyEmail, AccountConfirmed, AccountPwdResetEmail, ContactEmail } = require('./SendGrid.handler'); +const { AccountVerifyEmail, AccountConfirmed, AccountPwdResetEmail, ContactEmail, StandAloneContactEmail } = require('./StandAlone.handler'); const EMAIL_EVENTS={ ACCOUNT_VERIFY:1,