Secret Santa with Node.js and Gmail

What is Secret Santa
an arrangement by which a group of friends or colleagues exchange Christmas presents anonymously, each member of the group being assigned another member for whom to provide a small gift, typically costing no more than a set amount.
We have an extra requirement in our family:
No person should get their partner in the random anonymous allocation of Secret Santa.
Other options
A quick google search shows that there are much easier ways to get a random Secret Santa emailing system going. I have listed the top two Google search results here. But what is the fun in that. Let’s learn something about sending email with Node.js
.
Forking a Git repository
I had assumed I wasn’t the first person to want to, or have the need to give this a try. My first step was to see what Git repositories already existed. I found one that did 90% of what I wanted (credit to Dmitri Kunin).
https://github.com/DKunin/secret-santa-module
So I forked the repository and started making changes.
Stop partners from getting each other
The repository I forked used another package called secret-santa-shuffler that was also created by Dmitri Kunin. I took the index.js
from this module and created it as a separate module in my forked repository so I could modify it.
I added a function (partner()
) to get the partner of a sender (s
). Then added to the already existing condition so that I had both of:
- (sender (
s
) is not equal to receiver (receivers[j]
)) - (receiver (
receivers[j]
) is not equal to sender’s partner (partner()
))
// If condition prior to change
if (s !== receivers[j]) {
...
}
// if condition after change
if (s !== receivers[j] && receivers[j] != partner()) {
...
}
Use Gmail as the email service
Converting to use Gmail was quite simple. I registered a new Gmail address for the purpose of sending these emails. The extra step is to allow Less secure apps.
Since I am using this once a year, and only using for a fleeting moment, I can turn this feature on https://myaccount.google.com/lesssecureapps, and then turn it off when I am finished.
// Using mailgun prior to change
var mg = require('nodemailer-mailgun-transport');
var transporter = nodemailer.createTransport(
mg({
from: 'secret@santa.com',
to: '',
subject: 'Secret Santa',
html: '',
}),
);
// Using gmail after change
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: useremail,
pass: userpassword,
},
});
Sending the emails
My modified fork of Dmitri Kunin’s repository is here https://github.com/mortie23/secret-santa-module.
Installation
git clone
npm install
Configure your environment variables
useremail=hollywoodsecretsanta@gmail.com
userpassword=qwerty1234
secretsantaname=Hollywood
Debug mode by default
By default both scripts confirmemail.js
and secretsanta.js
scripts have debug: true
. Suggest you run it in this mode first. In this mode no emails are sent, only results logged to console.
// Example
santaModule(list, {
debug: true,
template: `<div><h2>It's the ${secretsantaname} Secret Santa!</h2><div>You should prepare for <h3>{%=o.to%}</h3></div></div>`,
}).then(console.log);
When you are happy, turn this flag to false.
# Run this first if you want to confirm that the emails are reaching people
npm run confirmemail
# Then run this to send them out
npm run secretsanta
List Example
This program will not allow partners to have each other in the Secret Santa.
Name,email,partner
Brad Pitt,brad.pitt@email.com,angelina.jolie@email.com
Angelina Jolie,angelina.jolie@email.com,brad.pitt@email.com
Justin Beiber,justin.beiber@email.com,hailey.bieber@email.com
Hailey Bieber,hailey.bieber@email.com,justin.beiber@email.com
Jake Gyllenhaal,jake.gyllenhaal@email.com
confirmemail Sent message
It’s the Hollywood Secret Santa!
Please reply to confirm your email
secretsanta Sent message
It’s the Hollywood Secret Santa!
You should prepare a present for: Brad Pitt (brad.pitt@email.com)
Debug mode on output
[
{
"giver": "brad.pitt@email.com",
"string": "<div><h2>It's the Mortimer Secret Santa!</h2><div>You should prepare for <h3>undefined (hailey.bieber@email.com)</h3></div></div>"
},
{
"giver": "angelina.jolie@email.com",
"string": "<div><h2>It's the Mortimer Secret Santa!</h2><div>You should prepare for <h3>undefined (jake.gyllenhaal@email.com)</h3></div></div>"
},
{
"giver": "justin.beiber@email.com",
"string": "<div><h2>It's the Mortimer Secret Santa!</h2><div>You should prepare for <h3>undefined (brad.pitt@email.com)</h3></div></div>"
},
{
"giver": "hailey.bieber@email.com",
"string": "<div><h2>It's the Mortimer Secret Santa!</h2><div>You should prepare for <h3>undefined (angelina.jolie@email.com)</h3></div></div>"
},
{
"giver": "jake.gyllenhaal@email.com",
"string": "<div><h2>It's the Mortimer Secret Santa!</h2><div>You should prepare for <h3>undefined (justin.beiber@email.com)</h3></div></div>"
}
]