This article is for the development of a REST API for communication with other users with the help of a REST API called Twilio. Twilio’s APIs (Application Programming Interfaces) is a platform for communications with users globally. Behind these APIs is a software layer connecting and optimizing communications networks around the world to allow your users to call and message anyone anywhere.
You can use these REST APIs to communicate with other users or programmatically add capabilities like voice, video, and messaging to your applications.
Twilio’s APIs User registration
Twilio supports authentication for their REST APIs so for using any feature provided by Twilio user have to sign-up to their account and create a
https://www.twilio.com/try-twilio
Twilio will ask for a verified number from the registered user or the user can add a new verified number on the following link:
https://www.twilio.com/console/phone-numbers/verified
on the above link you can also see the verified number you used at the time of registration
Next step is to get a free trail number which is done by going to your Dashboard
https://www.twilio.com/console
Click on the Get a Trial Number Button
A block like this appear which will consist of your trial Number
Note *: Use only the trial number assigned by Twilio don’t go for a different number as it might not support all the feature you require for your API and also for verified number don’t use Jio India as per written date of this blog as
Get your API key
Next step to get your APIs key from a registered user account which you will find from the dashboard which will be later used for calling your respected API
https://www.twilio.com/console
Twilio Send SMS
Now we will begin with the first API which sending a message to a user by a python application with just a few lines of code.
To send your first SMS, you’ll need to have Python and the Twilio Python helper library installed.
Install Python
mac and Linux machine users probably have python installed.you can check this by opening up a terminal and running the following command:
python --version
You should see something like:
$ python --version Python 3.4 # Python 2.7+ is okay too
Windows users can follow this excellent tutorial for installing Python on Windows or follow the instructions from Python’s documentation
Install Twilio python helper library
The easiest way to install the library is using pip, a package manager for Python that makes it easier to install the libraries you need. Simply run this in the terminal:
pip install twilio
If you get anpip: command not found
error, you can also use easy_install
by running this in your terminal:
easy_install twilio
Send an SMS Using Twilio
For a simple implementation of sms function just see the code below
from twilio.rest import Client
account_sid = 'your Account sid from dashboard',
auth_token = 'your auth_token from dashboard'
client = Client(account_sid, auth_token)
message = client.message.create(
body="your message",
from_= 'your trial number' (example = +150331231231)
to='verified user number'
)
print(message.sid)
Next step Flask Installation
Go to your terminal and run the below command:
pip install flask
after installing flask install virtualenv
#for python 2.4 easy_install virtualenv
#for python 2.5-2.7 easy_install-2.7 virtualenv
Replace the 2.7 with 2.5 or 2.6 if you have that version installed.
To install virtualenv with Python 3.4+:
# If you get 'permission denied' errors try running "sudo python" instead of "python"
pip install virtualenv
For creating and activating virtual environment
virtualenv --no-site-packages.
# For activating environemt
source bin/activate
Now for sending the message with flask we import the required libraries and make the send message function under a particular route in a file of whatever name let’s say i name this main.py
from flask import Flask, jsonify, request
from config import ACCOUNT_SID, AUTH_TOKEN
from twilio.rest import Client
app = Flask(__name__)
@app.route('/send', methods=['POST'])
def send_msg():
account_sid = ACCOUNT_SID
auth_token = AUTH_TOKEN
message = request.json.get('message', None)
client = Client(account_sid, auth_token)
message = client.messages.create(
to='verified number',
from_='trial number',
body=message
)
return jsonify({
'message_sid': message.sid })
Now run this file by using the command in terminal
for Linux/Ubuntu users:
export FLASK_APP=main
flask run
For Windows user:
set FLASK_APP=main
flask run
Now after running the above code go to postman and enter your route where enter the message you want to send on the number
also, see how we have put out Twilio’s APIs key into a different file name config. It is one of the best practice to put away your keys to a different file so the code became cleaner and never to push those keys on git or elsewhere for security purposes.
congratulations you have successfully created a flask application which can send your message to a user on its mobile phone.
Twilio One Time password based User login system
Now let’s create something fun with the above API
what we will do next is create a user login system based on otp or One time password method where user will have to to enter a otp provided to him at the time of registration which he will confirm to login to his/her account
First let’s install the required imports and import them in the file:
#pymongo for database
pip install Flask-PyMongo
#jwt for authentication and access token
pip install flask-jwt-extended
#passlib for encrpting passwords
pip install passlib
# for creating of requirement files
pip freeze > requirements.txt
For Pymongo and jwt refers to the blogs below:
https://excellencetechnologies.in/blog/python-rest-api-authentication/
https://excellencetechnologies.in/blog/python-rest-api-database/
from flask import Flask, jsonify, request
from flask_pymongo import PyMongo
from config import ACCOUNT_SID, AUTH_TOKEN
from passlib.hash import pbkdf2_sha256
from twilio.rest import Client
from flask_jwt_extended import (
JWTManager, jwt_required, create_access_token,
get_current_user
)
from bson.objectid import ObjectId
import random
app = Flask(__name__)
app.config["MONGO_URI"] = "mongodb://localhost:27017/test_db"
mongo = PyMongo(app)
app.config['JWT_SECRET_KEY'] = 'xxxxxx' #change this
jwt = JWTManager(app)
First let’s make a route for registration of a user
@app.route('/register', methods=['POST'])
def register():
account_sid = ACCOUNT_SID
auth_token = AUTH_TOKEN
username = request.json.get('username', None)
password = request.json.get('password', None)
otp = random.randrange(100000, 999999)
client = Client(account_sid, auth_token)
if username and password is not None:
user = mongo.db.users.count({
"username": username
})
if user > 0:
return jsonify('username taken'), 500
id = mongo.db.users.insert_one({
'username': username,
'password': pbkdf2_sha256.hash(password),
'otp': otp
}).inserted_id
message = client.messages.create(
to='verified number',
from_='trail number',
body=otp
)
return jsonify({
'message_sid': message.sid, 'id': (str(id)), 'otp': otp
})
The above code will create a route and send a randomly generated otp to the verified number
Next create a route for confirming the otp entered by the user
@app.route('/confirm/<string:id>', methods=['PUT'])
def confirm(id):
otp = request.json.get("otp", None)
user = mongo.db.users.find_one({
"otp": otp
})
if user is not None and "_id" in user:
update_json = {}
if otp is not None:
update_json["otp"] = otp
otp = mongo.db.users.update({
"_id": ObjectId(id)
}, {
"$unset": update_json
}, upsert=False)
return jsonify(otp)
this will ask for a otp sent to you by api at the time of registration
Next let’s create a login route
@app.route('/login', methods=['POST'])
def login():
username = request.json.get('username', None)
password = request.json.get('password', None)
user = mongo.db.users.find_one({
"username": username,
"otp": None
})
if user is not None and "otp" is not None in user:
return jsonify({'error': 'invalid user'})
elif user is not None and "_id" in user:
if pbkdf2_sha256.verify(password, user["password"]):
access_token = create_access_token(identity=user)
return jsonify({'token': access_token, "otp": 'user confirmed'})
else:
return jsonify({'error': 'Invalid username and password'})
else:
jsonify({'result': 'No results find'})
Now in the above code if the user has not confirmed his/her otp form the confirm route he will be unable to log in
congratulations you have successfully created a flask application for user registration with
Full reference code is below
from flask import Flask, jsonify, request
from flask_pymongo import PyMongo
from config import ACCOUNT_SID, AUTH_TOKEN
from passlib.hash import pbkdf2_sha256
from twilio.rest import Client
from flask_jwt_extended import (
JWTManager, jwt_required, create_access_token,
get_current_user
)
from bson.objectid import ObjectId
import random
app = Flask(__name__)
app.config["MONGO_URI"] = "mongodb://localhost:27017/twilio"
mongo = PyMongo(app)
app.config['JWT_SECRET_KEY'] = 'qwerty'
jwt = JWTManager(app)
@app.route('/register', methods=['POST'])
def register():
account_sid = ACCOUNT_SID
auth_token = AUTH_TOKEN
username = request.json.get('username', None)
password = request.json.get('password', None)
otp = random.randrange(100000, 999999)
client = Client(account_sid, auth_token)
if username and password is not None:
user = mongo.db.users.count({
"username": username
})
if user > 0:
return jsonify('username taken'), 500
id = mongo.db.users.insert_one({
'username': username,
'password': pbkdf2_sha256.hash(password),
'otp': otp
}).inserted_id
message = client.messages.create(
to='verified number',
from_='trail number',
body=otp
)
return jsonify({
'message_sid': message.sid, 'id': (str(id)), 'otp': otp
})
@app.route('/confirm/<string:id>', methods=['PUT'])
def confirm(id):
otp = request.json.get("otp", None)
user = mongo.db.users.find_one({
"otp": otp
})
if user is not None and "_id" in user:
update_json = {}
if otp is not None:
update_json["otp"] = otp
otp = mongo.db.users.update({
"_id": ObjectId(id)
}, {
"$unset": update_json
}, upsert=False)
return jsonify(otp)
@jwt.user_identity_loader
def user_identity_lookup(user):
return str(user["_id"])
@app.route('/login', methods=['POST'])
def login():
username = request.json.get('username', None)
password = request.json.get('password', None)
user = mongo.db.users.find_one({
"username": username,
"otp": None
})
if user is not None and "otp" is not None in user:
return jsonify({'error': 'invalid user'})
elif user is not None and "_id" in user:
if pbkdf2_sha256.verify(password, user["password"]):
access_token = create_access_token(identity=user)
return jsonify({'token': access_token, "otp": 'user confirmed'})
else:
return jsonify({'error': 'Invalid username and password'})
else:
jsonify({'result': 'No results find'})
@jwt.user_loader_callback_loader
def user_loader_callback(identity):
user = mongo.db.users.find_one({
"_id": ObjectId(identity)
})
user["_id"] = str(user["_id"])
return user
@app.route('/profile', methods=['GET'])
@jwt_required
def profile():
current_user = get_current_user()
return jsonify(logged_in_as=current_user["username"]), 200