Software Development

Secret Santa with Node.js and Gmail

Secret Santa with Node.js and Gmail

What is Secret Santa

secretsanta googledefinition

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

secretsanta fork

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.

secretsanta gmaillesssecure

// 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>"
  }
]