Virtual Secret Santa Organizer in Python

Puja Singh
4 min readSep 16, 2021

Two years ago, when I started my professional journey Secret Santa was one event that actually helped me to understand as well as appreciate my teammates. The same event now made me conscious of an often overlooked necessity of humans, “feeling like part of a community”.

Most of my Team Members were new to the firm/Team and had not met each other due to the pandemic, so they were on board with the idea of the Virtual Secret Santa celebration.

Celebrating virtually had some challenges, and in this story, I will be discussing that:

  1. How do we ensure everyone gets their gift while the sender remains a secret?
  2. How do we mimic the random draw to assign Secret Santa?

For the first challenge, we used a google doc. For each participant, they could mention their wishlist (e.g. links to wishlist on Amazon) or hate list (something they absolutely don’t want) and a clue column where their Santa could anonymously drop a message.

For the next challenge, nobody wanted to spoil their surprise by taking up the responsibility to assign the Secret Santa. So, I wrote a simple python script that would achieve this.

Overview of the python script:

  1. Read the participant details from an Excel sheet

The first step is to get the list of participants and their email ids. If you have a small team, you can directly hard code it but considering the code principles it is not recommended.I have made the code reusable by reading information from an excel file.

def GetList(path):
dflist=pd.read_csv(path)
return dflist
Path = input("Enter the full path of the csv file").strip()
DetailList = GetList(Path)

2. Connect to the organizer’s email account

Next, establish a connection to sender/organizer’s email account as soon as the username and password are provided through the terminal. There might be a need to update the server name and port number based on the sender’s email service provider.

Note: If you are using Gmail, make sure the “Allow less secure apps” option is ON for the sender/organizer’s email account.

def OpenConnection(ServerName,PortNumber,UserName,Password):
#establish a connection
server = smtplib.SMTP(‘smtp.gmail.com’, 587)
print(server.ehlo())
print(server.starttls())
print(server.verify(UserName))
try:
server.login(UserName, Password)
print(server.login(UserName, Password))
except:
print(“Invalid Credentials”)
return server
UserName=input("Enter your Email Id here").strip()
Password=input("Enter your Password").strip()
ServerName='smtp.gmail.com'
PortNumber=587
Server=OpenConnection(ServerName,PortNumber,UserName,Password)
#establish the connection

3. Randomly assign Secret Santa for each participant

The actual santa assignment function is rather simple. I have created two copies of the participants name list — receiver and selection. Every time a santa is assigned to a participant his/her name is removed from the receiver list and is added in the result set along with the name of the assigned santa. The AND operation on selection and receiver ensures that the person to be gifted by santa is not santa himself or someone who is already assigned to some other santa.

def Santa(Employees):
#determine santa for each participant
receiver = Employees.copy()
result= {}
for i in Employees:
Selection = Employees.copy()
Selection.pop(Selection.index(i))
options = list(set(Selection)&(set(receiver)))
#create a list of participants yet to receive a gift
choice = random.choice(options)
result[i] = choice
receiver.pop(receiver.index(choice))
return result

4. Construct an email message — Make sure to add unique subject

The UserDetails list contains the Email receiver’s name, his email id and name of the giftee, respectively. Construct the Email subject and body as per your requirements. Make sure the subject is uniquely identifiable as it will be used to delete the emails from the sent box.

def constructMessage(UserDetails):
# construct an email message
msg = MIMEMultipart()
msg[‘From’] =’North Pole’
msg[‘To’] = UserDetails[1]
msg[‘Subject’] = ‘Confidential!!!This is your secret’
body = “Hey “+str(UserDetails[0]+”,\n \n You are the secret santa (amigos secereto) for “+str(UserDetails[2] + “.\n \n This is an autogenerated email, we have no record of santa’s and their giftees. For any other query, contact Puja Singh. \n \n Merry Christmas and Happy Disconnect.”))
msg.attach(MIMEText(body, ‘plain’))
return msg

5. Send an Email to each participant

def sendemail(UserName,ReceiverID,server,Message):
#send email to each participant mentioned in the excel sheet
try:
server.sendmail(UserName,ReceiverID, Message.as_string())
except ( ConnectionRefusedError):
#report if your message was sent or there was an errors
print(‘Failed to connect to the server. Bad connection settings?’)
except smtplib.SMTPServerDisconnected:
print(‘Failed to connect to the server. Wrong user/password?’)
except smtplib.SMTPException as e:
print(‘SMTP error occurred: ‘ + str(e))
else:
print(‘Sent’)

6. Delete all the Emails based on the Subject.

In order to delete the email from the Sent mail folder, first search the emails based on the subject and move them to Trash and then delete all emails from Trash.

def DeleteEmail(UserName,Password):
mail = imaplib.IMAP4_SSL(‘imap.gmail.com’)
connection_message=mail.login(UserName, Password)
print(connection_message)
mail.select(‘“[Gmail]/Sent Mail”’)
result, data = mail.uid(‘search’, None, ‘SUBJECT “Hi Guys, This just a trial email for Secret Santa”’)
#Search sent Email box based on Subject of the constructed email
if result == ‘OK’:
for num in data[0].split():
result, data = mail.uid(‘fetch’, num, ‘(RFC822)’)
if result == ‘OK’:
email_message = email.message_from_bytes(data[0][1])
print(‘sender:’ + email_message[‘Subject’])
mail.uid(‘store’, num, ‘+X-GM-LABELS’, ‘\\Trash’)
#move the selected emails to Trash
mail.select(‘[Gmail]/Trash’) # select all trash
mail.store(“1:*”, ‘+FLAGS’, ‘\\Deleted’)
mail.expunge()
#delete the emails in Trash
print(‘Emails Deleted’)
mail.close()
mail.logout()
return

You can find the code from below mentioned link:

Merry Christmas!!!

--

--