Remote Secret Santa
By: Iegor Rudnytskyi
Tags: Secret Santa, Tidyverse, R, Data Science

To be absolutely honest with you, I stopped believing in Santa Claus when I was around six years old. But my trust was broken earlier than that, when he did not deliver a full-scale Caterpillar tractor. Jokes aside, I really like this time of the year not only because of the decoration, songs, and overall atmosphere, but rather because it unites people. Nothing does it better than X-mas parties or Secret Santa. In this little post, I want to show you how to quickly implement the Secret Santa in R.

Photo by Volodymyr Hryshchenko on Unsplash

If you are not familiar with the idea, Secret Santa is a sort of a game: each team member writes their name on a piece of paper and throws it into a bag. Then, each person draws a random name to whom they bring a gift. If one draws their own name, they draw it again. The key principle of this tradition is that no one knows who is going to buy a gift for whom, which makes it fun.

Obviously, because of the Covid-19 restrictions we could not organize a proper X-mas party with our team at the Extension School. But I was extremely enthusiastic about the Secret Santa. At the end of the day, random assignment does not require a physical presence, and we could do it completely remotely. Further, I did not participate in Secret Santa for a couple of years due to the small size of teams at my previous jobs, so this year was a good time to make up for that.

Once I got a green light from each member of the team, I started implementing a small R script. The idea is extremely simple: take a tibble with email addresses, randomly assign to each member a name of a person for whom the gift will be given, and send the emails with these names to respective email addresses.

During my university days, I knew a very cool package {blastula} that allows sending emails from R. These emails are not boring plain texts but rather HTML-rendered markdown files, that can include images and other gorgeous stuff. This package is basically an engine of my Christmas machine. To fully set up the {blastula} package is straightforward: install the package by install.packages("blastula") , load it by library(blastula) , and finally set the credentials (i.e., your username and password):

The id has nothing to do with your account, this id you will refer to when you will send emails with your script. In my case, I used my Gmail account ( provider = "gmail" ), which did not require me to fill in options that you might normally need when specifying an email account, like host , port , etc. But if you use a custom email provider, you can set all these options manually.

After executing this command, a small input will pop up and you will need to provide your password to your email. And voila, you can send emails from R now.

The next step is to build a tibble (list of nice/naughty boys and girls) that would contain all the emails and names of the team members. Further, we need to create a new column that would contain the name of the target person (i.e., the assigned person for whom the gift should be bought):

The code above suffers from one problem: the sample() function does not ensure that a person is not assigned to themself. To avoid this situation, we can perturbate in a loop until no one is assigned to themself (at this point, I can sense the suspicious looks from the {tidyverse} community for using while loops):

We are left with composing the email content, and this it is quite simple. The text of the email will end up with the name of the target person. I want to highlight this name in bold, and that’s why I defined a helper function bold() (I will use it a bit later). Finally, to make the email less formal, I want to add a nice image below the text. Below, I create these pieces like Lego bricks that I can then assemble later in my function that will compose and send emails:

Now, using these Lego bricks let’s build a beautiful function. I assume that the function consumes each row from my tibble as a list of arguments, and for simplicity I will coerce it into a tibble member . Again, for convenience, the function extracts the target and email from the one-row tibble. Then, I compose the email based on text , image , and the target name, and finally send it using smtp_send() .

The generated email should look as below:

All we now need to do is actually go over each row of the our “naughty/nice” tibble, and apply this function.

And that’s it! Each member of the team should receive their email with the target name, and… well, you know the rest of the deal.