Build a WhatsApp Bitcoin Currency Conversion Bot with Python and Twilio

June 18, 2020
Written by
Dotun Jolaoso
Contributor
Opinions expressed by Twilio contributors are their own

Build a WhatsApp Bitcoin Currency Conversion Bot with Python and Twilio

In this tutorial, we’ll be looking at how to build a simple WhatsApp chatbot that handles the conversion of any given number of Bitcoin units to the equivalent in a preferred currency. The bot will be built using Twilio API for WhatsApp and the Flask Framework for Python.

Technical requirements

To follow along, you’ll need the following:

  • A free Twilio Account. If you use this link to register, you will receive $10 credit when you upgrade to a paid account.
  • Python 3.6 or newer
  • Ngrok. This will make the development version of our application accessible over the Internet.
  • A smartphone with an active number and WhatsApp installed.

Creating a Python environment

Let’s create a directory where our project will reside. From the terminal, run the following command:

$ mkdir twilio_whatsapp_bot

Next, cd into the project directory and run the following command to create a virtual environment.

$ python -m venv venv

To activate the virtual environment, run the following command:

$ source venv/bin/activate

If you are using a Windows computer, then the activation command is different:

$ venv\Scripts\activate

Next, we’ll need to install all the dependencies our project will need:

  • Flask: a Python web framework.
  • Twilio: A Twilio helper library that will make it easy for us to create valid TwiML.
  • Requests: A Python library for making HTTP requests.

To install all the dependencies at once, run the following command:

$ pip install flask twilio requests

Creating the Bot

Before we get started with building the bot, let’s quickly go through how the bot will work. In order for the bot to work as expected, messages that require conversion need to be in a particular format. So for example, a user needs to send a message in the format “Convert 5 BTC to USD”, where 5 is the number of BTC units to convert and USD is the currency code of the currency you would like to get the equivalent number of BTC units in.

The Twilio API for WhatsApp makes use of webhooks to notify our application whenever our bot receives a message. Let’s create a simple function that will respond to this webhook.

At the root of your project’s directory, create a main.py and add the following code to the file:

from flask import Flask, request
from twilio.twiml.messaging_response import MessagingResponse
import requests

app= Flask(__name__)

@app.route('/incoming/twilio', methods=['POST'])
def incoming_twilio():
    incoming_message=request.form['Body'].lower()
    message= incoming_message.split()
    resp= MessagingResponse()
    msg=resp.message()

    if 'hello' in incoming_message:
        reply = standard_response_format()
        msg.body(reply)
        return str(resp)

    if len(message) < 4:
       reply = standard_response_format()
       msg.body(reply)
       return str(resp)
    
    btc_unit = message[1]
    currency_code = message[4].upper()
    r = requests.get("https://api.coinbase.com/v2/exchange-rates?currency=BTC")
    if r.status_code == 200:
        rates = r.json()['data']['rates']
        if currency_code in rates:
            unit_rate = rates[currency_code]
            unit_conversion = get_unit_conversion(btc_unit, unit_rate)
            reply=f"{btc_unit} BTC is {unit_conversion:,} {currency_code}"
        else:
           reply=f"{currency_code} is not a valid currency code"
    else:
        reply= "Something went wrong"
    msg.body(reply)
    return str(resp)

def standard_response_format():
    return ("Welcome to the Bitcoin Currency Converter bot!\n\n" 
            "Please use the following format to chat with the bot: \n" 
            "Convert 1 BTC to USD \n"
            "1 is the number of BTC unit you would like to convert \n"
            "USD is the currency code you would like to convert too \n")

def get_unit_conversion(unit, unit_rate):
    return round(round(float(unit_rate), 2) * float(unit), 2)

if __name__ == '__main__':
    app.run()

Let’s go over what’s happening in the incoming_twilio() function.

The first thing we did was to obtain the content of the message that was sent using Flask’s request object. This comes in the payload of the POST request with a key of Body. Since we’ll be doing some basic analysis on the message, the message is converted to lowercase to avoid any issue that might arise as a result of case variations.

Next, the message itself is converted into a list using the split() method. Based on the agreed messaging format, the default separator in this case will be any whitespace.

A further analysis is carried out to check if the keyword hello is contained in the message. If hello is found in the message, a generic response is sent to the back to the user informing them of how to make use of the bot.

Similarly, another check is carried out to ensure that after the message has been converted into a list, the number of items contained in the list is not less than 4. Again, this is due to the agreed messaging format with the bot.

The number of BTC units to convert and the currency code are contained at indexes 1 and 4 of the list` respectively. Next, a HTTP GET request is made to the Coinbase API to obtain the current exchange rates with BTC as the base currency. The returned rates will define the exchange rate for one unit of BTC. Here’s an example of the response received from the API.

{
  "data": {
    "currency": "BTC",
    "rates": {
      "AED": "36.73",
      "AFN": "589.50",
      "ALL": "1258.82",
      "AMD": "4769.49",
      "ANG": "17.88",
      "AOA": "1102.76",
      "ARS": "90.37",
      "AUD": "12.93",
      "AWG": "17.93",
      "AZN": "10.48",
      "BAM": "17.38",
      ...
    }
  }
}

Once the response from the API has been obtained, a check is carried out to ensure that the currency code obtained from the list earlier can be found as a key under the rates payload. If it exists, the get_unit_conversion() function, which does the actual conversion, is then called passing in the unit rate of the identified currency code as well as the number of BTC units to convert.

Once we’ve applied our logic to determine the bot’s response based on the body of the message received, we need to send back a reply. Twilio expects this reply to be in Twilio Markup Language (TwiML). This is an XML-based language but we’re not required to create XML directly. The MessagingResponse class from the Twilio Python helper library helps us to send the response in the right format.

Setting up Ngrok

Since our application is currently local, there’s no way for Twilio to be able to send POST requests to the endpoint we just created. We can use Ngrok to set up a temporary public URL so that our app is accessible over the web.

To start the application, run the following command from the terminal:

$ python main.py

With the application running, run the following command on a second terminal window to start ngrok:

$ ngrok http 5000

In this command, 5000 refers to the port your Flask application is currently listening on.

You should now be presented with a screen similar to the one below:

ngrok screenshot

Take note of the https:// “Forwarding” URL as we’ll be making use of it shortly.

Configure Twilio WhatsApp Sandbox

Before you’re able to send and receive messages using the Twilio API for WhatsApp in production, you’ll need to enable your Twilio number for WhatsApp. Since it can take a while before your number is approved, we can use the Sandbox environment Twilio provides for WhatsApp.

To get started, head over to the WhatsApp section on your Twilio dashboard. You should see the sandbox phone number assigned to your account as below:

WhatsApp Sandbox

Right next to the phone number, you will also see a code that starts with “join” followed by two random words. To enable the WhatsApp sandbox, send a WhatsApp message with this code to the number assigned to your account. After a moment, you should receive a reply from Twilio confirming your mobile number is connected. Once this is done, you can start sending and receiving messages.

Next, head over to the “Sandbox” section under “Programmable SMS / WhatsApp Beta” and paste the Ngrok URL we noted earlier on the “WHEN A MESSAGE COMES IN” field. Don’t forget to append /incoming/twilio at the end of the URL so that it points at our Flask endpoint. Click “Save” at the bottom of the page.

WhatsApp webhook configuration

Testing

You can try testing the functionality of the bot by sending messages to it from your smartphone using WhatsApp. Here’s an example of me chatting with the bot:

WhatsApp Bitcoin currency bot demo

Conclusion

In this tutorial, we have created a simple WhatsApp chatbot that returns the Bitcoin equivalent price in any supported currency. This was implemented using Flask and the Twilio API for WhatsApp. The Bitcoin exchange rate was obtained from the Coinbase API. The GitHub repository with the complete code for this project can be found here.

Dotun Jolaoso

Website: https://dotunj.dev/
Github: https://github.com/Dotunj
Twitter: https://twitter.com/Dotunj_