diff --git a/functions/sendMail/index.js b/functions/sendMail/index.js index 8fc2f813a..bd55a3d8b 100644 --- a/functions/sendMail/index.js +++ b/functions/sendMail/index.js @@ -1,72 +1,71 @@ -const nodemailer = require("nodemailer"); +const formData = require('form-data'); +const Mailgun = require('mailgun.js'); /** - * Responds to any HTTP request. + * Responds to any HTTP request to send emails via Mailgun. * * @param {!express:Request} req HTTP request context. * @param {!express:Response} res HTTP response context. */ exports.sendMail = async (req, res) => { - if (process.env.HASURA_CLOUD_FUNCTION_SECRET == req.headers.secret) { - const subject = req.body.event.data.new.subject; - const text = req.body.event.data.new.content; - const to = req.body.event.data.new.to; - const replyTo = req.body.event.data.new.replyTo; - const from = process.env.HASURA_MAIL_USER; - const from_pw = process.env.HASURA_MAIL_PW; - const cc = req.body.event.data.new.cc; - const bcc = req.body.event.data.new.bcc; - - const emulated = process.env.EMULATE_EMAIL; + if (process.env.HASURA_CLOUD_FUNCTION_SECRET !== req.headers.secret) { + return res.status(401).json({ error: 'Unauthorized' }); + } - if (emulated == "1") { - console.log(` - Mail was requested to be sent: - From: ${from} - To: ${to} - CC: ${cc} - BCC: ${bcc} - replyTo: ${replyTo} - Subject: ${subject} - text: ${text} - `); + const { subject, content, to, replyTo, cc, bcc } = req.body.event.data.new; + const mailTag = req.headers.mailTag || 'eduhub'; // default if not provided - return res.json({ - message: "!!!!! E-Mail Emulated !!!!!", - }); - } else { - let transporter = nodemailer.createTransport({ - host: "sslout.df.eu", - port: 465, - secure: true, // true for 465, false for other ports - auth: { - user: from, - pass: from_pw, - }, - }); + // Base message configuration + const msg = { + from: `noreply@${process.env.MAILGUN_DOMAIN}`, + to, + subject: process.env.NODE_ENV === 'staging' ? '[STAGING] ' + subject : subject, + text: content, + html: content, + 'o:tag': [mailTag], + 'o:tracking': true + }; - let info = await transporter.sendMail({ - from: from, - to: to, - cc: cc, - bcc: "sent-mail@edu.opencampus.sh," + bcc, - replyTo: replyTo, - subject: subject, - text: text, - html: text, - dsn: { - id: to, - return: "headers", - notify: ["failure", "delay", "success"], - recipient: "sent-mail@edu.opencampus.sh", - }, - }); + if (replyTo) msg['h:Reply-To'] = replyTo; + if (cc) msg.cc = cc; + if (bcc) msg.bcc = bcc; - console.log("Message sent: " + to + " id:" + info.messageId); + try { + switch (process.env.NODE_ENV) { + case 'development': + // Development mode: Log all email attempts + console.log('Development email:', { + to: msg.to, + from: msg.from, + subject: msg.subject, + text: msg.text, + cc: msg.cc, + bcc: msg.bcc, + replyTo: msg['h:Reply-To'] + }); + break; + case 'staging': + case 'production': + // Staging: Using a test domain with restricted recipients + // Production: Using regular Mailgun domain + const productionMailgun = new Mailgun(formData); + await productionMailgun.client({ + username: 'api', + key: process.env.MAILGUN_API_KEY + }).messages.create(process.env.MAILGUN_DOMAIN, msg); + break; - return res.json({ - message: info.messageId, - }); + default: + throw new Error('Invalid environment'); } + + return res.json({ success: true }); + + } catch (error) { + console.error('Email error:', error); + return res.status(500).json({ + error: 'Failed to send email', + details: error.message + }); } }; diff --git a/infrastructure/application/00_variables.tf b/infrastructure/application/00_variables.tf index 1ed072ce5..f09c85e87 100644 --- a/infrastructure/application/00_variables.tf +++ b/infrastructure/application/00_variables.tf @@ -219,8 +219,12 @@ variable "environment" { type = string } -variable "emulate_email" { - description = "is true in staging so no mails are send out" +variable "mailgun_api_key" { + description = "API key for the Mailgun API" + type = string +} +variable "mailgun_domain" { + description = "Domain for the Mailgun API" type = string } diff --git a/infrastructure/application/06_cloud-functions.tf b/infrastructure/application/06_cloud-functions.tf index 93d15fd6a..ccc4fe498 100644 --- a/infrastructure/application/06_cloud-functions.tf +++ b/infrastructure/application/06_cloud-functions.tf @@ -184,7 +184,9 @@ resource "google_cloudfunctions2_function" "send_mail" { HASURA_CLOUD_FUNCTION_SECRET = var.hasura_cloud_function_secret HASURA_MAIL_PW = var.hasura_mail_pw HASURA_MAIL_USER = var.hasura_mail_user - EMULATE_EMAIL = var.emulate_email + MAILGUN_API_KEY = var.mailgun_api_key + MAILGUN_DOMAIN = var.mailgun_domain + NODE_ENV = var.environment } max_instance_count = 100 available_memory = "256M"