Build an Emojidex with Python and the Twilio WhatsApp API

August 28, 2018
Written by

emojidex-whatsapp

If you've ever wondered about the story behind your favorite emoji, this app is for you. We'll build an interactive bot to give us more information about just what 💁 is doing. With the Twilio API for WhatsApp and Emojipedia 👌😍 we can easily query this information on demand.

🌅 Getting started

Before we can dig into some code, make sure that your Python and Flask development environment is setup. If you haven't done so already,

  1. Install Python 3
  2. Install Ngrok to make your Flask app visible from the internet so Twilio can send requests to it
  3. Set up your Python development environment 

If you're new to Python and Flask check out this handy guide for more information on getting started.

I've started the project off, so clone or download the repo from GitHub and checkout the getting-started branch.

git clone -b getting-started git@github.com:robinske/emojimon-whatsapp.git

💬 Setting Up Twilio API Sandbox for WhatsApp

At the moment, only approved business accounts can use Twilio's WhatsApp API so we need to use the Twilio API Sandbox for WhatsApp to play around. Let's head to the Sandbox in our Twilio console. To activate it we must choose a Sandbox number, agree to the terms of WhatsApp, and select Activate Sandbox.

To join a Sandbox, send “join <your sandbox keyword found in your console>” to your Sandbox number in WhatsApp and you should get a response confirming you’ve joined. You can follow these instructions to install the WhatsApp Sandbox Channel in your account and connect your WhatsApp account with the Sandbox.

Now run the following command from terminal in the directory you'll put your code in.

ngrok http 5000

You should see a screen similar to the one below:

That publicly-accessible ngrok URL to our Flask app needs to be used when a message is sent to our WhatsApp number which we will configure now. Keep ngrok running in a separate terminal window while you're developing the application. Heads up: if you need to restart ngrok you'll be assigned a new Forwarding URL.

We need the following modules:

  1. Twilio to respond to incoming HTTP requests with each message sent to your WhatsApp number
  2. Flask to respond to incoming web requests
  3. Requests-HTML to grab and parse HTML pages
  4. Python Dotenv to load environment variables

In the terminal, run the following command to install those modules:

pip3 install -r requirements.txt

Next, copy the .env.example file to .env. Open .env and fill in your Twilio account credentials found in the Console and your WhatsApp from number.

↩️ Responding to WhatsApp Messages with Python and Flask

We have a basic Flask application shell and our next step will be to add the /whatsapp route so Twilio can respond to incoming WhatsApp messages.

Head over to app.py and add the following:

app = Flask(__name__)

# Helper function to send WhatsApp messages
def send_message(to, body):
   # Initialize client
   client = Client(os.getenv('TWILIO_ACCOUNT_SID'), os.getenv('TWILIO_AUTH_TOKEN'))
   client.messages.create(
       body=body,
       from_=os.getenv('WHATSAPP_FROM_NUMBER'),
       to=to
   )

@app.route('/whatsapp', methods=['GET', 'POST'])
def receive_message():
   # Get the description for this character
   character = request.values.get('Body')
  
   send_message(to=request.values.get('From'), body="You sent {}".format(character))

   return ('', 204)

This code will echo back what we sent and that's a great way to validate that we have everything hooked up the right way. Send a message to your WhatsApp sandbox number and you should see it parroted back at you:

📚 Building Our Emojidex

Now we can build the query to Emojipedia to get some information about the emoji. The Emojipedia API is currently restricted, so we'll grab the info by doing some basic web scraping with Requests HTML. Add the following helper function to query for an emoji description and build a response.

# Helper function to get an emoji's description
def get_emojipedia_description(character):
   # Get the Emojipedia page for this emoji
   session = HTMLSession()
   response = session.get('https://emojipedia.org/' + character)

   # If we didn't find an emoji, say so
   if not response.ok:
       return "Hmm - I couldn't find that emoji. Try sending me a single emoji ☝️"

   # Extract the title and description using Requests-HTML and format it a bit
   title = response.html.find('h1', first=True).text
   description = response.html.find('.description', first=True)
   description = '\n\n'.join(description.text.splitlines()[:-1])

   # And template it
   return render_template(
       'response.txt',
       title=title,
       description=description,
       url=response.url
   )

Then update your receive_message function with the emoji description instead of the parroted response.

@app.route('/whatsapp', methods=['GET', 'POST'])
def receive_message():
   # Get the description for this character
   character = request.values.get('Body')
   
   description = get_emojipedia_description(character)
   send_message(to=request.values['From'], body=description)

   return ('', 204)

Restart the application and try sending another emoji. This time you should get some useful information back!

💯 Can you catch em all?

With Emojipedia and the Twilio API for WhatsApp we've just built a fun and informative emoji bot. To extend the application try adding a reverse emoji lookup ("genie" => 🧞‍). There are a lot of things you can do with WhatsApp and Emoji, like the emoji translator my colleague Phil built. Check out some of the other awesome things you can build with the WhatsApp API on our blog.

If you want to see the finished code for this application, check out the repo on GitHub. Special thanks to my colleague Andrew for crafting the original version of the Emojidex. If you have any questions, comments, or ideas, feel free to reach out to me on Twitter @kelleyrobinson.