Python flask app to send SMS using Africa's talking SMS gateway and Google spreadsheet

A friend of mine wanted to send bulk SMSes to a large number of phone numbers. So we scouted around for existing service providers, but I was never really satisfied until I landed on Africa's talking.

Africa's talking is a Kenyan-based startup that enables you to access Telco APIs as a Web Service via cool Restful APIs. You can send SMS, develop USSD apps and even voice-based apps using their very intuitive API.

However, Africa's talking is purely API-driven platform. They provide the infrastructure, so it wouldn't be of help to my friend. So I decided to develop a simple web interface where he can specify Google spreadsheet name that has his contacts and then a simple text box for the message input. I also chose Python flask because it's a very minimal MVC framework for developing python apps. Really simple stuff.

alt

Using google spreedsheet as backend db

So I start by writing a function that connects to Google spreadsheet and picks the contacts. You need majorly two libraries gspread and oauth2client which you can install using python pip;

pip install gspread oauth2client

Also I noticed you needed python requests >2.4. I had to upgrade to Python 3.x for it to work which again caused me issues with Africa's talking API which is designed to work with Python 2.7.

Also you need to setup API credentials in the Google cloud console and then enable the Google drive API. You can read the whole tutorial on Twilio.

This is spreasheet.py

import gspread  
from oauth2client.service_account import ServiceAccountCredentials  
#needs requests >2.4

def get_data(spreadsheet_name):  
    try:
        # use creds to create a client to interact with the Google Drive API
        scope = ['https://spreadsheets.google.com/feeds']
        creds = ServiceAccountCredentials.from_json_keyfile_name('client_secret.json', scope)
        client = gspread.authorize(creds)
        # Find a workbook by name and open the first sheet
        # Make sure you use the right name here.
        sheet = client.open(spreadsheet_name).sheet1
        # Extract and print all of the values
        list_of_hashes = sheet.get_all_records()
        return(list_of_hashes)
    except Exception as e:
        #embed()
        print(e)

Connecting to Africa's talking API

Next is creating a sandbox account on Africa's talking platform. I found it relatively easy to do and they have API across most popular language -- python, php, ruby and even support direct get requests so you can use things like curl.

I downloaded the python API to my app directory, but I had to tweak it to work with Python 3.x.

africas_talking_api.py

from AfricasTalkingGateway import AfricasTalkingGateway, AfricasTalkingGatewayException  
def send_the_sms(to, message):  
    username = "myusername"
    apikey   = "d306ac28d6c2d5fsfde68de8a0935955sfdf8107f9bdfa66d449acb38087we434ns16c4ewf"
    gateway = AfricasTalkingGateway(username, apikey, 'sandbox')
    try:
        results = gateway.sendMessage(to, message)
        for recipient in results:
            # status is either "Success" or "error message"
            print('number=%s;status=%s;messageId=%s;cost=%s' % (recipient['number'],
                                                                recipient['status'],
                                                                recipient['messageId'],
                                                                recipient['cost']))
    except AfricasTalkingGatewayException as e:
        print('Encountered an error while sending: %s' % str(e))

Sending SMS

Now I send the message by picking numbers from Google spreadsheet and then sending the messages through Africa's talking API.
send_message.py

from spreadsheet import get_data  
from africas_talking_api import send_the_sms

def send_the_message(google_sp, message):  
    data = get_data(google_sp)

    for row in data: 
        number = row['Mobile']
        int_num = '+256' + str(number)
        name = row['Name']
        send_the_sms(int_num, message)

if __name__ == '__main__':  
    google_sp = 'Sample google spreadsheet'
    message = 'test message'
    send_the_message(google_sp, message)
Web front-end

Finally, I create a simple web front-end using Python Flask framework which is pretty awesome.

routes.py

from flask import Flask, render_template, request, Response, session  
from send_message import send_the_message

app = Flask(__name__)  
app.secret_key = 'F12Zr47j\3yX R~X@H!jmM]Lwf/,?KT'

@app.route('/', methods=['GET', 'POST'])
def index():  
    if request.method == 'POST':
        gs_name = request.form['gs-name'].strip()
        sms_msg = request.form['sms-msg'].strip()
        print(gs_name)
        send_the_message(gs_name, sms_msg)
        return Response("message sent")
    else:
        return render_template('index.html')

if __name__ == '__main__':  
  app.run(host='127.0.0.1', debug=True, port=7020)

Summing it all up, there are number of things I've left out. But this is kind like how my app directory structure looks like;

➜  africas-talking git:(post) tree -L 2
├── africas_talking_api.py
├── AfricasTalkingGateway.py
├── client_secret.json
├── __pycache__
│   ├── AfricasTalkingGateway.cpython-34.pyc
│   ├── send_message.cpython-34.pyc
│   ├── send_sms.cpython-34.pyc
│   └── spreadsheet.cpython-34.pyc
├── routes.py
├── send_message.py
├── spreadsheet.py
├── static
│   ├── css
│   ├── fonts
│   ├── img
│   └── js
└── templates
    ├── index.html
    └── layout.html

Yeah that pretty much sums it up. I believe they charge Ugx 35 per SMS which I think is competitive price. If you know of any other very reliable SMS guys, drop me a comment below.

Image: marketingland.com

David Okwii

David Okwii is a Ugandan-based Technology writer and System's Engineer.

Kampala Uganda http://www.davidokwii.com

Subscribe to oquidave@geek:~ #

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!