Build and deploy a USSD application with Africa's Talking, Docker and Heroku [Python] - Part 1

Build and deploy a USSD application with Africa's Talking, Docker and Heroku [Python] - Part 1

Introduction

Hi, welcome to this series. We'll be covering how to build a simple USSD application that has some offline banking features and can send you a cute text if you want to. I shared this demo at the first Africa's Talking Freelance Developer Program, feel free to join our little community here.

Setting up

Make a simple directory in your project folder as follows:

mkdir myussdapp
cd myussdapp

Next up, we'll need to get our python virtual environment set up:

pip3 install virtualenv
virtualenv venv
source ./venv/bin/activate

You should see something switch up on your terminal and you should be in your virtual environment. You can now open the project folder in your favorite text editor. I use VS Code but I have found Atom to be quite sufficient especially for python when paired with the Kite engine.

We will then set up a requirements.txt file that will contain the python modules that we will need for this tutorial. Create a requirements.txt file in your directory and copy the following into the file:

flask
africastalking

Save the file and run the following command on your terminal:

pip install -r requirements.txt

This installs all the dependancies that we defined in the file. In this case we imported 2 packages:

  • flask - This is a small micro framework that allows us to build web servers with python
  • africastalking - This imports the Africa's Talking SDK and allows us to use all of it's services including SMS which we'll use here

Getting Started

Now that our project is ready to go, we'll create the file that we will be working from, app.py. I'll guide you on how we will design this USSD application.

This tutorial was designed as a code along. If you are more experienced you can proceed as you deem fit

First, we import the various packages that we will need:

from flask import Flask, request
import africastalking
import os

This gets the packages we defined in our requirements.txt file and adding in a new module named os which provides us with functions that interact with our OS.

Next up, we'll set up our flask app and initializing the africastalking module. For your username and api_key you will need to visit, our sandbox to grab them. On the sandbox, your username is sandbox by default but in production we would use our actual app username. To find out more, here's an article on our help center. We will also initialize the africastalking SMS service.

app = Flask(__name__)
username = ""
api_key = ""
africastalking.initialize(username, api_key)
sms = africastalking.SMS

Once this is done, we can start defining what we want our application to do. We'll define a route and add a function underneath it to run our USSD. Let's get the route setup:

@app.route('/', methods=['POST', 'GET'])

Designing the application

There are certain variables that are essential to running a USSD. Africa's Talking allows you to access these variables:

  • Session ID - this is a unique identifier for your USSD session
  • Service Code - This is the USSD code that is making the request
  • Phone Number - This is the phone number currently accessing
  • Text - This is the text input provided by the user

Next up our function. But just before that. Let's break down the menus that we want to build. First, we need a top level menu which will consist of:

  1. Check account details
  2. Check phone number
  3. Send me a nice message

Within the first menu,Check account details, we want someone to check their:

  1. Account balance - we'll create a variable to hold this value
  2. Account number - we'll also create a variable for that as well :)

The second menu:

  • We'll use the phone number variable we get back from the USSD API

For the third menu:

  • We'll send a user an SMS with a nice simple message

Let's actually write the code:

def ussd_callback():
    global response
    session_id = request.values.get("sessionId", None)
    service_code = request.values.get("serviceCode", None)
    phone_number = request.values.get("phoneNumber", None)
    text = request.values.get("text", "default")
    sms_phone_number = []
    sms_phone_number.append(phone_number)

    #ussd logic
    if text == "":
        #main menu
        response = "CON What would you like to do?\n"
        response += "1. Check account details\n"
        response += "2. Check phone number\n"
        response += "3. Send me a cool message"
    elif text == "1":
        #sub menu 1
        response = "CON What would you like to check on your account?\n"
        response += "1. Account number"
        response += "2. Account balance"
    elif text == "2":
        #sub menu 1
        response = "END Your phone number is {}".format(phone_number)
    elif text == "3":
        try:
            #sending the sms
            sms_response = sms.send("Thank you for going through this tutorial", sms_phone_number)
            print(sms_response)
        except Exception as e:
            #show us what went wrong
            print(f"Houston, we have a problem: {e}")
    elif text == "1*1":
        #ussd menus are split using *
        account_number = "1243324376742"
        response = "END Your account number is {}".format(account_number)
    elif text == "1*2":
        account_balance = "100,000"
        response = "END Your account balance is USD {}".format(account_balance)
    else:
        response = "END Invalid input. Try again."

    return response

Getting the server up and running

We need to see our app in action, so let's get to it.

We need to make sure that the python file running at the time, is the main file just to make sure there isn't any conflict. At the bottom of the app.pyfile, add in the following code:

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=os.environ.get("PORT"))

Next up, head to your terminal and run:

python app.py

Your application should run on localhost:5000 by default. If we try accessing the link, we'll get But we need to talking to the API on a live link but we only have it on our computers. We'll cover deploying our application with Docker and Heroku as well as how to register your USSD code on the Africa's Talking Sandbox environment.

Final words

This is the first article in a series describing how to deploy swift and scalable USSD applications. We'll try out several use cases in this series as well as try and do it in as many languages and frameworks as we can.

Check out my next article here.