DEV Community

Cover image for Automating birthday wishes using Python
Swayam Singh
Swayam Singh

Posted on • Edited on

Automating birthday wishes using Python

Overview:

Remembering dates is kinda hard but we are programmers, making hard things easier is our only job so instead of we remember dates why not automate this task.
In this article we gonna automate the birthday wishes, yeah exactly our program will check if there's any birthday today and then mail your friend a beautiful wish 😁.

Note: I highly recommend you to remember dates because friends get offended if they got to know about it.

Prerequisites :

  • comfortable with Python
  • some basic knowledge about pandas module

Let's get going 🌱

1. Setup:

So first of all before heading to write code, we need to create a csv file to store the information about our dearest friends like their email address, name, birthdate. Name that file as birthdays.csv.

csv stands for " comma separated values " it's basically a type of file in which you store the data separated by commas and the first row denote the heading of each values.
Just like a spreadsheet first row denote headings then below each heading we write it's value separated by commas.

Here's an example of our csv file.

Screenshot 2021-04-24 at 4.03.40 PM.png

Now we have a file which contains all the required data of our friends, it's time to create some really creative wishes.
We are going to create .txt files which store the wishes for our friends.

Here's the example what we are doing...
Screenshot 2021-04-24 at 4.07.41 PM.png

Python code will replace [NAME] with the birthday boy's/girl's name.

I recommend you to create multiple files (at least 3) and write different good wishes on them.

rename each of your birthday letters as letter_1.txt,letter_2.txt, etc and save your files inside the folder letters.

Now we have a folder letters that contains our nice wishes and a csv file. It's time to write our Python code.

2. Real hustle begins

Now open your favourite code editor, create a main.py file and start coding...

as mentioned in prerequisites I'm assuming you worked with python in past and comfortable with the syntax.

below is the list of modules that we are going to used in this project

  • datetime { for finding today's date and match it with the record }
  • pandas { for managing and filtering data from our csv file }
  • random { for selecting a random letter from letters }
  • smtplib { for sending mails to friends }

now let's import all the modules to our main.py file

from datetime import datetime # importing datetime class from datetime module
import pandas
import random
import smtplib

my_email = "email@gmail.com"
passw = "your_password"
Enter fullscreen mode Exit fullscreen mode

since our program will send mails to friends so it also needs mail address of sender.

use your email address, you don't want your friend to receive birthday wishes by someone else's mail.

So moving ahead now we need to get hold of today's date so that we can compare it with data stored in csv file.

today = datetime.now()

here we are calling now() method from datetime class, it'll return today's date time and we are storing it in today variable.

Now we are going to use pandas to read our csv file and convert it into dataframe.

# reading csv file and making it's dataframe

data = pandas.read_csv("birthdays.csv")

# filtering data to check if there's any record that birthdate matches with today's date

bday = data[(data.month == today.month) & (data.day == today.day)]

# storing our friend's name having birthday today and email to separate variables, stays empty otherwise

name = bday["name"].tolist()
email = bday["email"].tolist()

# making a list of all the friends having birthdays today

friends = []

for n in range(len(name)):
    friends.append(
        {
            "name": name[n],
            "email": email[n]
        }
    )
Enter fullscreen mode Exit fullscreen mode

Now it's time to select a random letter from the letters we created to send wishes.
First we gonna check if our friends list is not empty then we loop over each of its items and generate letters for them

# selecting a random integer as letter number from all letters, I assume you have 3.

if not friends:
    print("no birthday")
else:
    for friend in friends:
        num = random.randint(1, 3)
        with open(f"letters/letter_{num}.txt") as letter:
            lines = letter.readlines()
            lines[0].strip()
            lines[0] = lines[0].replace("[NAME]", friend["name"]) # replacing [NAME] with friend's name
            message = "".join(lines)
Enter fullscreen mode Exit fullscreen mode

Now the only part remain is to send a mail with the selected random wish to our friend.
Here's how we gonna do this, in that same loop

# connecting to gmail's service
with smtplib.SMTP("smtp.gmail.com") as connection:
    connection.starttls()

# login with our email and password
    connection.login(user=my_email, password=passw)

# sending mail to friend's email address
    connection.sendmail(from_addr=my_email, to_addrs=friend["email"], msg=f"Subject: HAPPY BIRTHDAY\n\n{message}")
    print(f"message sent to {friend['name']}")
Enter fullscreen mode Exit fullscreen mode

And that's it, if you followed well then in the end your code will look something like this:

import datetime as dt
import pandas
import random
import smtplib

my_email = "your_email@gmail.com"
passw = "your_password"

data = pandas.read_csv("birthdays.csv")
today = dt.datetime.now()
bday = data[(data.month == today.month) & (data.day == today.day)]
name = bday["name"].tolist()
email = bday["email"].tolist()

friends = []

for n in range(len(name)):
    friends.append(
        {
            "name": name[n],
            "email": email[n]
        }
    )

if not friends:
    print("no birthday")
else:
    for friend in friends:
        num = random.randint(1, 3)
        with open(f"letters/letter_{num}.txt") as letter:
            lines = letter.readlines()
            lines[0].strip()
            lines[0] = lines[0].replace("[NAME]", friend["name"])
            message = "".join(lines)

        with smtplib.SMTP("smtp.gmail.com") as connection:
            connection.starttls()
            connection.login(user=my_email, password=passw)
            connection.sendmail(from_addr=my_email, to_addrs=friend["email"], msg=f"Subject: HAPPY BIRTHDAY\n\n{message}")
            print(f"message sent to {friend['name']}")

Enter fullscreen mode Exit fullscreen mode

No not yet, It's time to check if it's working or not.

Screenshot 2021-04-28 at 8.48.30 AM.png

since in the csv there is no birthdays today so you can see the message in consoleno birthdays today

Now if I change the csv and set any birth date to today's date and save it then after running the program again

Screenshot 2021-04-28 at 8.51.26 AM.png

Now it states message sent to {whatever name} ,
you can also check the mail to confirm it.

1KtTySoI1.png

That's all, we did it, YAYYYY 🥳

What's next !

If you are still reading, make sure to follow me and subscribe to my newsletter for more as I have some exciting stuff coming up every weekend. See ya next time! 🌻

Top comments (8)

Collapse
 
_s_w_a_y_a_m_ profile image
Swayam Singh

*hey just a quick note: *

If you want to deploy your your app on online servers so that it can run everyday and check for birthdays, you are most welcome BUT
before that make sure you put your email address and passw into the environment variables

Don't expose it in the code

Happy Coding...

Collapse
 
ktownrocky profile image
ktownrocky

Nice Stuff.
How can i cc other friends when sending email to the friend with bday?.
I tried creating a variable and concatenate and it failed.
line of code:
data = pandas.read_csv("birthday.csv")
to_cc = data['Email'].tolist ### defining cc group
connection.sendmail(from_addr=my_email, to_addrs= [friend["email"]] + to_cc, msg=f"Subject: HAPPY BIRTHDAY Test\n\n{message}")

Thanks,
Ktown Rocky

Collapse
 
hernancopello profile image
Hernan Copello

awesome, is there any way you can use pandas to import specific excel rows?

lets say you have a clients database and import just "name" "phone/email" and "Dob" to check for birthday? (im really new into py, sry if its a really obvious question)

Collapse
 
_s_w_a_y_a_m_ profile image
Swayam Singh

sure buddy, since you already gone through my article so I'll suggest a very similar way:
open that excel file in google sheets and click on file menu then download it as .csv
Now open that .csv file with pandas and instead of comparing months and day separately you can compare DOB with today's date

DOB may contain the birth year so you have to ignore it during comparison. You can take DOB as string and the use .split() method to separate out the month, day and year

Collapse
 
hernancopello profile image
Hernan Copello

awesome gonna look into that. thank you!!

Collapse
 
_s_w_a_y_a_m_ profile image
Swayam Singh

In the response of a reddit comment, I changed few parts of the code:

  1. now it can handle multiple birthdays on the same day
  2. removed the exception handling part of code
Collapse
 
iamunderated profile image
iam-underated

How can I replace the service of Email to WhatsApp???

Collapse
 
kevo profile image
kevo

did you fine the solutions?thanks