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.
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.
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))
Now I send the message by picking numbers from Google spreadsheet and then sending the messages through Africa's talking API.
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)
Finally, I create a simple web front-end using Python Flask framework which is pretty awesome.
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.