parent
f817ce7b0d
commit
33de97d84f
@ -0,0 +1,132 @@
|
|||||||
|
import fs from 'fs';
|
||||||
|
import {Handler} from "@netlify/functions";
|
||||||
|
import formData from 'form-data';
|
||||||
|
import Mailgun from 'mailgun.js';
|
||||||
|
import Handlebars from 'handlebars';
|
||||||
|
import {i18n} from '../../next-i18next.config.js';
|
||||||
|
import i18next from 'i18next';
|
||||||
|
import {MailgunMessageData} from "mailgun.js/interfaces/Messages.js";
|
||||||
|
|
||||||
|
|
||||||
|
const {
|
||||||
|
MAILGUN_API_KEY,
|
||||||
|
MAILGUN_DOMAIN,
|
||||||
|
MAILGUN_URL,
|
||||||
|
FROM_EMAIL_ADDRESS,
|
||||||
|
REPLY_TO_EMAIL_ADDRESS,
|
||||||
|
} = process.env;
|
||||||
|
|
||||||
|
const mailgun = new Mailgun(formData);
|
||||||
|
const mg = mailgun.client({
|
||||||
|
username: 'api',
|
||||||
|
key: MAILGUN_API_KEY,
|
||||||
|
url: MAILGUN_URL
|
||||||
|
});
|
||||||
|
|
||||||
|
const txtStr = fs.readFileSync(__dirname + "/invite.txt").toString()
|
||||||
|
|
||||||
|
|
||||||
|
i18next.init({
|
||||||
|
fallbackLng: 'en',
|
||||||
|
ns: ['file1', 'file2'],
|
||||||
|
defaultNS: 'file1',
|
||||||
|
debug: true
|
||||||
|
}, (err, t) => {
|
||||||
|
if (err) return console.log('something went wrong loading', err);
|
||||||
|
t("foo");
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Handlebars.registerHelper('i18n',
|
||||||
|
(str: string): string => {
|
||||||
|
return (i18next != undefined ? i18next.t(str) : str);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
interface RequestPayload {
|
||||||
|
recipients: {[email: string]: {[key: string]: string}};
|
||||||
|
options: any;
|
||||||
|
locale: string;
|
||||||
|
action: "invite" | "admin";
|
||||||
|
}
|
||||||
|
|
||||||
|
const handler: Handler = async (event) => {
|
||||||
|
/**
|
||||||
|
* Send a mail using Mailgun
|
||||||
|
*/
|
||||||
|
if (event.httpMethod !== 'POST') {
|
||||||
|
return {
|
||||||
|
statusCode: 405,
|
||||||
|
body: 'Method Not Allowed',
|
||||||
|
headers: {Allow: 'POST'},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const {recipients, options, action, locale} = JSON.parse(event.body) as RequestPayload;
|
||||||
|
|
||||||
|
if (!recipients) {
|
||||||
|
return {
|
||||||
|
statusCode: 422,
|
||||||
|
body: 'The list of recipients is missing.',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!action || !["invite", "admin"].includes(action)) {
|
||||||
|
return {
|
||||||
|
statusCode: 422,
|
||||||
|
body: 'Unknown action.',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!locale || !["fr", "gb"].includes(locale)) {
|
||||||
|
return {
|
||||||
|
statusCode: 422,
|
||||||
|
body: 'Unknown locale.',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO setup locale
|
||||||
|
|
||||||
|
const htmlTemplate = "FOO"; //fs.readFileSync(`${__dirname}/${action}.txt`).toString();
|
||||||
|
const htmlContent = Handlebars.compile(htmlTemplate);
|
||||||
|
|
||||||
|
const payload: MailgunMessageData = {
|
||||||
|
// from: `${i18next.t("Mieux Voter")} <mailgun@mg.app.mieuxvoter.fr>`,
|
||||||
|
from: FROM_EMAIL_ADDRESS || '"Mieux Voter" <postmaster@mg.app.mieuxvoter.fr>',
|
||||||
|
to: Object.keys(recipients),
|
||||||
|
subject: i18next.t(`emails.subject-${action}`),
|
||||||
|
html: htmlContent({}),
|
||||||
|
'h:Reply-To': REPLY_TO_EMAIL_ADDRESS || 'app@mieuxvoter.fr',
|
||||||
|
'o:tag': action,
|
||||||
|
'o:require-tls': true,
|
||||||
|
'o:dkim': true,
|
||||||
|
'recipient-variables': JSON.stringify(recipients),
|
||||||
|
};
|
||||||
|
console.log(payload)
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await mg.messages.create(MAILGUN_DOMAIN, payload)
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
body: JSON.stringify(
|
||||||
|
{
|
||||||
|
...res,
|
||||||
|
"status": `${recipients.length} emails were sent.`,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
return {
|
||||||
|
statusCode: 422,
|
||||||
|
body: JSON.stringify(
|
||||||
|
{
|
||||||
|
"status": "can not send the message"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
export {handler};
|
@ -1,145 +0,0 @@
|
|||||||
import fs from 'fs';
|
|
||||||
// const Mailgun = require('mailgun.js');
|
|
||||||
// const formData = require('form-data');
|
|
||||||
import dotenv from 'dotenv';
|
|
||||||
// const Handlebars = require("handlebars");
|
|
||||||
|
|
||||||
dotenv.config();
|
|
||||||
// const {
|
|
||||||
// MAILGUN_API_KEY,
|
|
||||||
// MAILGUN_DOMAIN,
|
|
||||||
// MAILGUN_URL,
|
|
||||||
// FROM_EMAIL_ADDRESS,
|
|
||||||
// CONTACT_TO_EMAIL_ADDRESS,
|
|
||||||
// } = process.env;
|
|
||||||
|
|
||||||
// const mailgun = new Mailgun(formData);
|
|
||||||
// const mg = mailgun.client({
|
|
||||||
// username: 'api',
|
|
||||||
// key: MAILGUN_API_KEY,
|
|
||||||
// url: 'https://api.eu.mailgun.net',
|
|
||||||
// });
|
|
||||||
|
|
||||||
const success = {
|
|
||||||
statusCode: 200,
|
|
||||||
body: "Your message was sent successfully! We'll be in touch.",
|
|
||||||
};
|
|
||||||
const err = {
|
|
||||||
statusCode: 422,
|
|
||||||
body: "Can't send message",
|
|
||||||
};
|
|
||||||
|
|
||||||
// setup i18n
|
|
||||||
// i18next.use(Backend).init({
|
|
||||||
// lng: "fr",
|
|
||||||
// ns: ["emailInvite", "common"],
|
|
||||||
// defaultNS: "emailInvite",
|
|
||||||
// fallbackNS: "common",
|
|
||||||
// debug: false,
|
|
||||||
// fallbackLng: ["fr"],
|
|
||||||
// backend: {
|
|
||||||
// backends: [FSBackend, HttpApi],
|
|
||||||
// backendOptions: [{ loadPath: "/public/locales/{{lng}}/{{ns}}.json" }, {}],
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
|
|
||||||
// setup the template engine
|
|
||||||
// See https://github.com/UUDigitalHumanitieslab/handlebars-i18next
|
|
||||||
// function extend(target, ...sources) {
|
|
||||||
// sources.forEach((source) => {
|
|
||||||
// if (source)
|
|
||||||
// for (let key in source) {
|
|
||||||
// target[key] = source[key];
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// return target;
|
|
||||||
// }
|
|
||||||
// Handlebars.registerHelper("i18n", function (key, { hash, data, fn }) {
|
|
||||||
// let parsed = {};
|
|
||||||
// const jsonKeys = [
|
|
||||||
// "lngs",
|
|
||||||
// "fallbackLng",
|
|
||||||
// "ns",
|
|
||||||
// "postProcess",
|
|
||||||
// "interpolation",
|
|
||||||
// ];
|
|
||||||
// jsonKeys.forEach((key) => {
|
|
||||||
// if (hash[key]) {
|
|
||||||
// parsed[key] = JSON.parse(hash[key]);
|
|
||||||
// delete hash[key];
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// let options = extend({}, data.root.i18next, hash, parsed, {
|
|
||||||
// returnObjects: false,
|
|
||||||
// });
|
|
||||||
// let replace = (options.replace = extend({}, this, options.replace, hash));
|
|
||||||
// delete replace.i18next; // may creep in if this === data.root
|
|
||||||
// if (fn) options.defaultValue = fn(replace);
|
|
||||||
// return new Handlebars.SafeString(i18next.t(key, options));
|
|
||||||
// });
|
|
||||||
// const txtStr = fs.readFileSync(__dirname + "/invite.txt").toString();
|
|
||||||
const txtStr = {
|
|
||||||
en: fs.readFileSync(__dirname + '/invite-en.txt').toString(),
|
|
||||||
fr: fs.readFileSync(__dirname + '/invite-fr.txt').toString(),
|
|
||||||
};
|
|
||||||
const txtTemplate = {
|
|
||||||
en: '', // Handlebars.compile(txtStr.en),
|
|
||||||
fr: '', // Handlebars.compile(txtStr.fr),
|
|
||||||
};
|
|
||||||
const htmlStr = {
|
|
||||||
en: fs.readFileSync(__dirname + '/invite-en.html').toString(),
|
|
||||||
fr: fs.readFileSync(__dirname + '/invite-fr.html').toString(),
|
|
||||||
};
|
|
||||||
const htmlTemplate = {
|
|
||||||
en: '', // Handlebars.compile(htmlStr.en),
|
|
||||||
fr: '', // Handlebars.compile(htmlStr.fr),
|
|
||||||
};
|
|
||||||
|
|
||||||
const sendMail = async (event) => {
|
|
||||||
if (event.httpMethod !== 'POST') {
|
|
||||||
return {
|
|
||||||
statusCode: 405,
|
|
||||||
body: 'Method Not Allowed',
|
|
||||||
headers: { Allow: 'POST' },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = JSON.parse(event.body);
|
|
||||||
if (!data.recipientVariables || !data.title || !data.locale) {
|
|
||||||
return {
|
|
||||||
statusCode: 422,
|
|
||||||
body: 'Recipient variables and title are required.',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// i18next.changeLanguage(data.locale);
|
|
||||||
const templateData = {
|
|
||||||
title: data.title,
|
|
||||||
};
|
|
||||||
|
|
||||||
const mailgunData = {
|
|
||||||
// from: `${i18next.t("Mieux Voter")} <mailgun@mg.app.mieuxvoter.fr>`,
|
|
||||||
from: '"Mieux Voter" <postmaster@mg.app.mieuxvoter.fr>',
|
|
||||||
to: Object.keys(data.recipientVariables),
|
|
||||||
text: '', // txtTemplate.fr(templateData),
|
|
||||||
html: '', // htmlTemplate.fr(templateData),
|
|
||||||
subject: data.title,
|
|
||||||
'h:Reply-To': 'app@mieuxvoter.fr',
|
|
||||||
'recipient-variables': JSON.stringify(data.recipientVariables),
|
|
||||||
};
|
|
||||||
|
|
||||||
return true;
|
|
||||||
// const res = mg.messages
|
|
||||||
// .create('mg.app.mieuxvoter.fr', mailgunData)
|
|
||||||
// .then((msg) => {
|
|
||||||
// return success;
|
|
||||||
// }) // logs response data
|
|
||||||
// .catch((err) => {
|
|
||||||
// console.log(err);
|
|
||||||
// return success;
|
|
||||||
// }); // logs any error
|
|
||||||
//
|
|
||||||
// return res;
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.handler = sendMail;
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,19 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
# This file tests the netlify function for sending emails
|
||||||
|
|
||||||
|
# Check if the port is already used or not
|
||||||
|
is_using=$(lsof -i:9999 | awk -F ' ' '{ print $1 }')
|
||||||
|
if [ -z "$is_using" ]; then
|
||||||
|
echo "Starting a server on port 9999";
|
||||||
|
netlify functions:serve --port 9999 &
|
||||||
|
elif ! [[ "$is_using" =~ .*"node".* ]]; then
|
||||||
|
echo "$is_using"
|
||||||
|
echo "The port 9999 is already used and not by us :-("
|
||||||
|
exit 1;
|
||||||
|
else
|
||||||
|
echo "The server is running."
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
netlify functions:invoke --port 9999 send-emails --payload '{"recipients"
|
||||||
|
: {"pierrelouisguhur@gmail.com": {"title": "Test", "adminUrl": "foo"}}, "action": "invite", "locale": "gb"}'
|
Loading…
Reference in new issue