But what am I to do if I don't have access to a computer or wi-fi? How will I get my fill of Simpson's humor? Enter Twilio, the API for text, VoIP, and voice in the cloud.
In this tutorial, we are going to use Twilio along with Frinkiac, the Simpons quote and screencap database, to create a Python app that will automatically send us a Simpson's screencap and quote every day via MMS. We are going to accomplish this in less than 40 lines of Python. Yup, no cron jobs, no servers, just pure Python.
If you don't want to follow along and just want to see the finished code, check out my Github repository..
Before we can jump into code, we need to get our environment set up.
Make sure you have Python and pip installed on your machine. Python comes pre-installed on many UNIX/Linux distributions, but if you don't have it you can download it from here. pip comes packaged with Python versions >=2.7.9 or >=3.4. You can test if Python and pip are both installed by running the following:
1$ python -V && pip -V
If you don't think you have pip on your system, download it here.
Next we need to install a few Python libraries. pip makes this really easy for us. Run the following command which will automatically download and install all the external libraries our script will need:
1$ pip install twilio requests schedule
Let's break down the command we just used.
It's time to start building our app. We only need one file, so navigate to a directory of your choosing and open a new file called
frinkiac.py in your preferred editor.
At the top of this file add the following lines:
1import schedule 2import requests 3from twilio.rest import TwilioRestClient 4from twilio import TwilioRestException 5 6account_sid = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' 7auth_token = 'YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY' 8client = TwilioRestClient(account_sid, auth_token)
The first four lines in the code above are simply importing all of the libraries we just installed. The three lines after our imports configure and create a
TwilioRestClient object that will let us make calls to the Twilio REST API. Make sure you replace the values for
auth_token with your actual account SID and auth token. You can find these values in your Twilio account dashboard.
Important note: Never push code with your API credentials to a public repository. See the "Optional Steps" section at the bottom of this post for an alternative approach to using your Twilio API keys.
Next add the following function to your app:
1def get_quote(): 2 r = requests.get("https://frinkiac.com/api/random") 3 if r.status_code == 200: 4 json = r.json() 5 # Extract the episode number and timestamp from the API response 6 # and convert them both to strings. 7 timestamp, episode, _ = map(str, json["Frame"].values()) 8 9 image_url = "https://frinkiac.com/meme/" + episode + "/" + timestamp 10 # Combine each line of subtitles into one string. 11 caption = "\n".join([subtitle["Content"] for subtitle in json["Subtitles"]]) 12 return image_url, caption
The function we just added uses
requests to send a GET request to Frinkiac and retreive data about a random Simpsons moment. Although Frinkiac isn't actually an API, the entire site is react-based and fetches resources via HTTP. As such, we can use the site in the same way that we would use an API. Next, we convert our retrieved data into JSON, extract the
episode code, and convert these two components into string format.
episode are used to create the URL that points to a screencap of the random Simpsons moment. Finally, we grab the contents from each line of subtitles in our JSON and join them together to form the
Now add the only other function that we need:
1def send_MMS(): 2 media, body = get_quote() 3 try: 4 message = client.messages.create( 5 body=body, 6 media_url=media, 7 to="+12345678901", # Replace with your phone number 8 from_="+12345678901") # Replace with your Twilio number 9 print("Message sent!") 10 # If an error occurs, print it out. 11 except TwilioRestException as e: 12 print(e)
This function starts by calling the
get_quote function we created in the previous step and by storing its return values. The
except block from above was adapted from Twilio's Python quickstart documentation. These lines are simply taking in a number of parameters and turning them into a call to the Twilio REST API.
from parameters with your phone real phone number and your Twilio phone number, respectively.
If an error occurs during the API call it will be printed to the terminal.
Now at the bottom of our file, below the two functions we just added, insert the following three lines:
1schedule.every().day.at("12:00").do(send_MMS) 2 3while True: 4 schedule.run_pending()
schedule allows you to set how often a function runs in a very readable way. The schedule will run inside a
while loop that will continue looping indefinitely. Our app will now behave according to the schedule, which means that
send_MMS will be called every day at 12:00 p.m. indefinitely or until you exit the app.
For the purpose of testing the application, it's a good idea to change the schedule we added above to run more frequently. For example,
schedule.every(30).seconds.do(send_MMS) would call the
send_MMS function every 30 seconds. (This way you won't need to wait until noon to know if your application is working.)
After you've changed that, make sure you save
frinkiac.py. Go back to your terminal and run the following command:
1$ python frinkiac.py
Your terminal will look like its frozen, but that's because your app is running. After 30 seconds, you should see a line printed to your terminal that says
Message sent!. See the "Optional Steps" section for instructions on running your program as a background process.
If your app crashes due to a
hostname doesn't match error, it's because of an issue between the
requests library and your Python version. Upgrade to Python >=2.7.9 or follow this StackOverflow answer to resolve this issue.
If you run into any errors with Twilio, you will see a number of helpful tips printed to the terminal about how to resolve your issue.
Otherwise, check your phone and you should expect to see an MMS with a random Simpsons screencap and caption! Here's an example:
Okay, so you say your son is towheaded, button nose, mischievous smile, and may be armed with a slingshot?
Congratulations! You've just built a Twilio-powered MMS Simpsons quote-bot using nothing more than a few lines of Python. The tools in this guide -- using the
schedule libraries, and more -- can be used in numerous ways to create applications with even more functionality. Try combining new APIs and libraries with some of Twilio's other features like Voice or IP Messaging, and see what you can come up with!
TwilioRestClientobject is to use environment variables. With environment variables you won't have to worry about making your API keys visible to the public. To do this, run the following commands in your terminal, replacing the values with your actual account SID and auth token:
1$ export TWILIO_ACCOUNT_SID='XXXXX' 2$ export TWILIO_AUTH_TOKEN='YYYYYY'
frinkiac.py and add
import os to the top of the file and replace
account_sid = 'XXXXXXX' and
auth_token = 'YYYYYYYY' with the lines below:
1account_sid = os.environ.get('TWILIO_ACCOUNT_SID') 2auth_token = os.environ.get('TWILIO_AUTH_TOKEN')
scheduleis very intuitive. Some alternative schedules you could use in your app are:
1schedule.every().hour.do(send_MMS) 2schedule.every().monday.do(send_MMS) 3schedule.every().wednesday.at("16:00").do(send_MMS)
&to the end of your
1$ python frinkiac.py & 2 1872
This command will return a process ID (PID) number (
1872 in this case) that you can append to the
kill command in order to terminate your program (e.g.
$ kill 1872).
Thank you for reading my tutorial on creating a Simpsons-based Quote-Bot using Twilio MMS, Frinkiac, and (some) Python.