Never Forget A Friend’s Birthday with Python, Flask and Twilio
Time to read: 6 minutes
Have you ever forgotten a friend’s birthday? It happens to the best of us. After the frustration of checking Facebook every day for birthdays, I wanted a better push notification system with better filters.
I wrote an article, Building a Simple Birthday App with Flask-SQLAlchemy, showing a way to export your Facebook birthday calendar to an .ics file and import it into a DB with Flask and Flask-SQLAlchemy.
After talking to Twilio at PyCon we thought it would be cool to extend this app by adding SMS notifications and a possibility to send birthday messages via SMS, so I signed up for a Twilio account and got coding.
In this post we will build a simple birthday app with Python, Flask and Twilio’s Programmable SMS service API so you never miss a birthday again:
The complete code for this project on Github.
Setup instructions
Start by cloning the Git repository:
Next, make a virtual environment and install the dependencies:
Create a Twilio account, get a phone number and API key (sid) and token.
Copy the settings template in place:
Update the env.conf
environment variables file with the correct settings:
- flask – secret = set this to a hard to guess string (Flask docs)
- twilio_api – sid token = obtained in step 3
- phones – twilio = obtained in step 3
- phones – admin = your (verified) mobile phone number, where you want to receive notification messages
- login – user password = your login credentials for the Flask app
- server – url = unchanged if running locally, update to base URL if deployed elsewhere
NOTE: make sure you use E.164 number formatting for phone numbers (e.g. +34666555444, +442071838750). See Twilio’s support article: Formatting International Phone Numbers.
The app uses configparser to load these settings in.
Import your FB birthday calendar into the local SQLite database:
-
Export your birthday calendar from Facebook and save it as
cal.ics
in the app’s top level directory. - Run model.py to import the birthdays into the DB. Here I am using the -t option to strip out real names using Faker. For real use drop the -t:
How to run it
Make sure you have your virtualenv enabled. This app has two parts: a Flask front-end and a daily cron script on the backend.
The front-end is a Flask app which you can invoke with: python app.py
.
At this point go to 127.0.0.1:5000 and you can see your friend’s birthdays. As we’ll see in a bit you need to add a phone number for each friend you want to receive a notification for.
The notifier is a daily cron script that checks for active birthdays with a phone number set. It sends SMS notifications to the admin phone you configured in your settings. This needs to run in the background so use a tool like nohup:
How the Flask App Works
All Flask app code is in app.py
. As you probably want to host this in the cloud, authentication is there from the start.
This is done by adding the login_required decorator to all private routes. When you go to the app you first have to login. I am using ngrok here to test the local app:
Once logged in, you can see your imported friends and their birthdays. Some simple CSS emphasizes today’s birthday(s):
You can navigate friends by tabs and via the search box:
The app uses Flask-SQLAlchemy to interface with the database, with a single table to store the birthdays. The model is defined in model.py which we used before to load in the data. Here is the part that defines the table structure:
Adding Phone Numbers
To avoid numerous SMS messages, the cron job only looks at friends with a phone number only. Clicking the pencil button at the right you get a form to add a phone number:
NOTE: that to be able to send messages to your friends using the free Twilio version you need to verify their phone numbers first. You can lift this limitation by upgrading your account. You can find more info here.
Various validation rules are set up in the corresponding
/friends/
route. We cannot have the same phone number twice for example.
With the phone number added you will get an SMS when it’s their birthday.
Notifications
The cron job is coded in notify.py
using the schedule package to notify about birthdays occurring that day.
It queries the DB using Flask-SQLAlchemy getting the birthdays for the current day:
Then, it sends an SMS to your configured admin phone. Twilio makes this very easy as you can see in sms.py
:
Running the cron job manually:
As this will run on a remote server the current version of the app uses logging instead of stdout. As stated before you want to use nohup to run it in the background. The schedule module does the rest:
And here is the notification SMS for today’s birthday:
The link is the entry point into the Flask app to send a birthday message or SMS card which we will see in the next section.
Send Birthday Messages and Cards
This is the second part of the app. There are two ways to get to the send message feature: follow the link in the SMS, or click the phone icon at the left of your friend’s name from the homepage.
You are presented with the following form:
Some validation is in place to only be able to send a message to the person that has a birthday:
You can now send a text message and include an image link:
If you include an image link, the Pillow library is used to put the text on top of the image making a simple birthday card. The code for this is in the text_on_image.py module.
When you click verify you can check if you are happy with the result:
If so you can send the card via MMS:
Gary would receive an SMS like this:
This is on an iPhone. On Android it did not display the image inline. For this reason it sends the text alongside the image.
Conclusion and Learning
Having a birthday app managed by SMS is cool. Twilio’s API makes it very easy. The Pillow image integration was the hardest part of building this app.
Splitting the code into various modules helped and will help manage complexity. Moving forward it would be good to add a regression test suite and possibly automate end-to-end testing with a tool like Selenium.
And finally, nothing beats building practical apps when it comes to honing your programming skills. Apart from the Twilio API, building this app I learned more Flask and integration of various interesting modules.
Practice Yourself
Join our Twilio PyBites code challenge to build your own automated texting app and other awesome applications each week.
Feel free to reach out if you have any questions or comments:
Contact info
I am Bob Belderbos from PyBites, you can reach out to me by:
- Email: pybitesblog@gmail.com
- Twitter: https://twitter.com/pybites
- GitHub: https://github.com/pybites
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.