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).

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, 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(
    from: '',
    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


git clone
npm install

Configure your environment variables

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>{}</h3></div></div>`,

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.

Brad Pitt,,
Angelina Jolie,,
Justin Beiber,,
Hailey Bieber,,
Jake Gyllenhaal,

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 (

Debug mode on output

    "giver": "",
    "string": "<div><h2>It's the Mortimer Secret Santa!</h2><div>You should prepare for <h3>undefined (</h3></div></div>"
    "giver": "",
    "string": "<div><h2>It's the Mortimer Secret Santa!</h2><div>You should prepare for <h3>undefined (</h3></div></div>"
    "giver": "",
    "string": "<div><h2>It's the Mortimer Secret Santa!</h2><div>You should prepare for <h3>undefined (</h3></div></div>"
    "giver": "",
    "string": "<div><h2>It's the Mortimer Secret Santa!</h2><div>You should prepare for <h3>undefined (</h3></div></div>"
    "giver": "",
    "string": "<div><h2>It's the Mortimer Secret Santa!</h2><div>You should prepare for <h3>undefined (</h3></div></div>"