diff --git a/package.json b/package.json index 7186625..7277d5f 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "isomorphic-style-loader": "^1.1.0", "jsonwebtoken": "^7.2.1", "node-fetch": "^1.6.3", + "nodemailer": "^3.1.3", "normalize.css": "^5.0.0", "passport": "^0.3.2", "passport-facebook": "^2.1.1", diff --git a/src/core/emailer.js b/src/core/emailer.js new file mode 100644 index 0000000..059e970 --- /dev/null +++ b/src/core/emailer.js @@ -0,0 +1,62 @@ +import Nodemailer from 'nodemailer'; +import { email, starters, mains, getRsvpEnd } from '../config'; +import { handleError } from '../core/rollbar'; + +const transporter = Nodemailer.createTransport({ + service: 'gmail', + auth: { + user: email.senderAddress, + pass: email.password, + }, +}); + +// Debounce sending the email to avoid spamming +const emailTimers = {}; + +function getEmailText(person) { + return `Dear ${person.firstname}.\n\n +Thanks for your RSVP, ${person.attending ? 'we\'re delighted to hear you will be attending' : 'we\'re sorry to hear you will not be attending'}.\n +${person.attending ? `Your meal choices are ${starters[person.starter]} and ${mains[person.main]}.\n` : ''} +${person.attending && person.dietary.length > 0 ? `Your dietary requirements are: ${person.dietary}.\n` : ''} +You can modify your RSVP up until ${getRsvpEnd()} here: https://danielandhana.com/${person.password}.\n +${person.attending ? 'See you at our wedding,' : 'See you soon,'}\n +Daniel and Hana +`; +} + +function getEmailHTML(person) { + return `
Dear ${person.firstname}.
+Thanks for your RSVP, ${person.attending ? 'we\'re delighted to hear you will be attending' : 'we\'re sorry to hear you will not be attending'}.
+${person.attending ? `Your meal choices are ${starters[person.starter]} and ${mains[person.main]}.
` : ''} +${person.attending && person.dietary.length > 0 ? `Your dietary requirements are: ${person.dietary}.
` : ''} +You can modify your RSVP up until ${getRsvpEnd()} here.
+${person.attending ? 'See you at our wedding,' : 'See you soon,'}
+Daniel and Hana
+`; +} + +export const sendRSVPEmail = function sendRSVPEmail(person) { + const mailOptions = { + from: `"${email.senderName}" <${email.senderAddress}>`, + to: person.email, + subject: 'Thank you for your RSVP', + text: getEmailText(person), + html: getEmailHTML(person), + }; + // send mail with defined transport object + transporter.sendMail(mailOptions, (error) => { + if (error) { + handleError(error); + } + }); +}; + +export const sendRSVPEmailWithDebounce = function sendRSVPEmailWithDebounce(person) { + if (person.key) { + // Stop previous email + clearTimeout(emailTimers[person.key]); + emailTimers[person.key] = setTimeout(() => { + sendRSVPEmail(person); + }, 10000); + } +}; diff --git a/src/routes/rsvp/index.js b/src/routes/rsvp/index.js index 2db50c2..ea6baf8 100644 --- a/src/routes/rsvp/index.js +++ b/src/routes/rsvp/index.js @@ -3,40 +3,14 @@ import Layout from '../../components/Layout'; import fetchQL from '../../core/fetchQL'; import Rsvp from './Rsvp'; import NotFound from '../notFound/NotFound'; -import { rsvpEndDate } from '../../config'; +import { rsvpEndDate, getRsvpEnd } from '../../config'; let title = 'RSVP'; -const months = [ - 'January', - 'February', - 'March', - 'April', - 'May', - 'June', - 'July', - 'August', - 'September', - 'October', - 'November', - 'December', -]; - export default { path: '/rsvp/:password', - getRsvpEnd() { - const date = rsvpEndDate.getDate(); - let dateSuffix = 'th'; - if (date === 1 || date === 21 || date === 31) { dateSuffix = 'st'; } - if (date === 2 || date === 22) { dateSuffix = 'nd'; } - if (date === 3 || date === 23) { dateSuffix = 'rd'; } - const month = months[rsvpEndDate.getMonth()]; - const year = rsvpEndDate.getFullYear(); - return `${date}${dateSuffix} ${month} ${year}`; - }, - isEditable() { return new Date() < rsvpEndDate; }, @@ -68,7 +42,7 @@ export default {