From 1c8348d553988f5474c8d7896c2804dc1d62159a Mon Sep 17 00:00:00 2001 From: Raphael Kabo Date: Mon, 25 Apr 2022 19:03:24 +0100 Subject: feat: Add subscribe to group functionality --- models/EventGroup.js | 10 +++- routes.js | 118 +++++++++++++++++++++++++++++++++++++ views/emails/subscribed.handlebars | 9 +++ views/eventgroup.handlebars | 35 +++++++++++ 4 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 views/emails/subscribed.handlebars diff --git a/models/EventGroup.js b/models/EventGroup.js index 6d2893b..c70ef95 100755 --- a/models/EventGroup.js +++ b/models/EventGroup.js @@ -1,5 +1,12 @@ const mongoose = require('mongoose'); +const Subscriber = new mongoose.Schema({ + email: { + type: String, + trim: true + }, +}) + const EventGroupSchema = new mongoose.Schema({ id: { type: String, @@ -43,7 +50,8 @@ const EventGroupSchema = new mongoose.Schema({ trim: true, default: true }, - events: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Event' }] + events: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Event' }], + subscribers: [Subscriber], }); module.exports = mongoose.model('EventGroup', EventGroupSchema); diff --git a/routes.js b/routes.js index 00823cb..542cd65 100755 --- a/routes.js +++ b/routes.js @@ -741,6 +741,46 @@ router.post('/newevent', async (req, res) => { } }); } + // If the event was added to a group, send an email to any group + // subscribers + if (event.eventGroup && sendEmails) { + EventGroup.findOne({ _id: event.eventGroup._id }) + .then((eventGroup) => { + const subscribers = eventGroup.subscribers.reduce((acc, current) => { + if (acc.includes(current.email)) { + return acc; + } + return [ current.email, ...acc ]; + }, []); + subscribers.forEach(emailAddress => { + req.app.get('hbsInstance').renderView('./views/emails/eventgroupupdated.handlebars', { siteName, siteLogo, domain, eventID: req.params.eventID, eventGroupName: eventGroup.name, eventName: event.name, eventID: event.id, eventGroupID: eventGroup.id, emailAddress: encodeURIComponent(emailAddress), cache: true, layout: 'email.handlebars' }, function (err, html) { + const msg = { + to: emailAddress, + from: { + name: siteName, + email: contactEmail, + }, + subject: `${siteName}: New event in ${eventGroup.name}`, + html, + }; + switch (mailService) { + case 'sendgrid': + sgMail.send(msg).catch(e => { + console.error(e.toString()); + res.status(500).end(); + }); + break; + case 'nodemailer': + nodemailerTransporter.sendMail(msg).catch(e => { + console.error(e.toString()); + res.status(500).end(); + }); + break; + } + }); + }); + }); + } res.writeHead(302, { 'Location': '/' + eventID + '?e=' + editToken }); @@ -1533,6 +1573,84 @@ router.post('/removeattendee/:eventID/:attendeeID', (req, res) => { }); }); +/* + * Create an email subscription on an event group. + */ +router.post('/subscribe/:eventGroupID', (req, res) => { + const subscriber = { + email: req.body.emailAddress, + }; + if (!subscriber.email) { + return res.sendStatus(500); + } + + EventGroup.findOne(({ + id: req.params.eventGroupID, + })) + .then((eventGroup) => { + if (!eventGroup) { + return res.sendStatus(404); + } + eventGroup.subscribers.push(subscriber); + eventGroup.save(); + if (sendEmails) { + req.app.get('hbsInstance').renderView('./views/emails/subscribed.handlebars', { eventGroupName: eventGroup.name, eventGroupID: eventGroup.id, emailAddress: encodeURIComponent(subscriber.email), siteName, siteLogo, domain, cache: true, layout: 'email.handlebars' }, function (err, html) { + const msg = { + to: subscriber.email, + from: { + name: siteName, + email: contactEmail, + }, + subject: `${siteName}: You have subscribed to an event group`, + html, + }; + switch (mailService) { + case 'sendgrid': + sgMail.send(msg).catch(e => { + console.error(e.toString()); + res.status(500).end(); + }); + break; + case 'nodemailer': + nodemailerTransporter.sendMail(msg).catch(e => { + console.error(e.toString()); + res.status(500).end(); + }); + break; + } + }); + } + return res.redirect(`/group/${eventGroup.id}`) + }) + .catch((error) => { + addToLog("addSubscription", "error", "Attempt to subscribe " + req.body.emailAddress + " to event group " + req.params.eventGroupID + " failed with error: " + error); + return res.sendStatus(500); + }); +}); + +/* + * Delete an existing email subscription on an event group. + */ +router.get('/unsubscribe/:eventGroupID', (req, res) => { + const email = req.query.email; + console.log(email); + if (!email) { + return res.sendStatus(500); + } + + EventGroup.update( + { id: req.params.eventGroupID }, + { $pull: { subscribers: { email } } } + ) + .then(response => { + return res.redirect('/'); + }) + .catch((error) => { + addToLog("removeSubscription", "error", "Attempt to unsubscribe " + req.query.email + " from event group " + req.params.eventGroupID + " failed with error: " + error); + return res.sendStatus(500); + }); +}); + router.post('/post/comment/:eventID', (req, res) => { let commentID = nanoid(); const newComment = { diff --git a/views/emails/subscribed.handlebars b/views/emails/subscribed.handlebars new file mode 100644 index 0000000..3a3c4ad --- /dev/null +++ b/views/emails/subscribed.handlebars @@ -0,0 +1,9 @@ +

You have been subscribed to the event group '{{eventGroupName}}' on {{siteName}}.

+

You will receive emails when new events are added to +the group, and can unsubscribe at any time.

+

Love,

+

{{siteName}}

+
+

Hold up - I don't want to receive these emails any more!

+

If you didn't subscribe yourself to this event group on {{siteName}}, someone may have accidentally typed your email instead of theirs. Click here to unsubscribe.

diff --git a/views/eventgroup.handlebars b/views/eventgroup.handlebars index 25b29d0..9afee2c 100755 --- a/views/eventgroup.handlebars +++ b/views/eventgroup.handlebars @@ -76,6 +76,11 @@
+
+ + +
+ + + +