Django app to add support for Orange API SMS-MO, SMS-MT/DR
Project description
Django app to add support for Orange API SMS-MO and SMS-MT (with DR)
Install
pip install orangeapisms
Edit your settings.py file and add:
INSTALLED_APPS = list(INSTALLED_APPS) + ['orangeapisms', 'django_forms_bootstrap']
Configure your orangeapi.json file (place it next to your settings.py file):
{
"handler_module": "myapp.orange_handler",
"use_db": true,
"sender_address": "+22300000000",
"sender_name": "POTUS",
"client_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"client_secret": "xxxxxxxxxxxxxxxx",
"enable_tester": true,
"default_sender_name": "sender_address"
}
Setup Database with ./manage.py migrate
That’s it ! Test it by accessing /oapi/ and playing with the tester.
- client_id:
Your Client ID (mandatory)
- client_secret:
Your Client Secret (mandatory)
- handler_module:
python path to your module handling messages (mandatory)
- use_db:
whether to store SMS in DB (SMSMessage Model)
- smsmt_url:
URL of your API (might change depending on your plan)
- oauth_url:
OAuth URL for Orange API
- sender_address:
Your subscribed phone number
- sender_name:
Your custom sender name (can be number or string)
- enable_tester:
To enable tester & logs WebUI on /oapi/
- default_sender_name:
What to use as default sender name
- send_async:
whether to deffer SMS sending to celery
- celery_module:
python path to your celery tasks module
- country:
ISO 3166-1 code for your country (used for balance checking)
- fix_msisdn:
whether to fix SMS-MT destination without prefix
- country_prefix:
MSISDN numeric prefix for your country (to fix SMS-MT without prefix)
Usage
After installation (previous step), you are able to send & receive individual SMS. To automatically process incoming SMS, you will have to customise the handler module which you specified in ORANGE_API[‘handler_module’].
The module would call three different functions based on events:
smsmo(message) on an incoming SMS-MO
smsmt(message) on an outgoing (sent by you) SMS-MT
smsdr(message) on an incoming delivery-receipt notification. The passed message is the SMS-MT which received the DR.
Sample handler module:
import datetime
import logging
from orangeapisms.utils import send_sms
from myapp.models import UserModel
logger = logging.getLogger(__name__)
def handle_smsmo(message):
logger.info("Received an SMS-MO: {}".format(message))
def register_user(message, keyword, text):
# break-down the formatted SMS into variables
try:
name, sex, dob = text.split()
except:
return message.reply('Invalid format')
# valid user entries
if sex not in ['m', 'f']:
return message.reply('Unable to understand sex')
# reuse input into different data structure
try:
d = dob.split('-')
birthdate = datetime.datetime(d[3], d[2], d[1])
except:
return message.reply('Unable to understand date of birth')
# make use of the data including message metadata
user = UserModel.objects.create(
name=name, sex=sex, dob=birthdate,
phone=message.sender_address)
return message.reply("Congratulations, you're registered as #{}"
.format(user.id))
def broadcast_to_users(message, keyword, text):
# loop on all Users in DB
for user in UserModel.objects.all():
# send a custom message to that user
send_sms(user.phone, "Hey {u}, {c}".format(u=user.name, c=text))
keywords = {
'register': register_user,
'broadcast': broadcast_to_users,
}
# find the proper keyword
keyword, text = message.content.split(' ', 1)
if keyword in keywords.keys():
return keywords.get(keyword)(message, keyword, text.strip().lower())
# fallback on error
return message.reply('Unknown request')
def handle_smsmt(message):
logger.info("Sent an SMS-MT: {}".format(message))
def handle_smsdr(message):
logger.info("Received an SMS-DR: {}".format(message))
Using a broker to send SMS-MT
By default, SMS-MT are sent synchronously meaning your request is stalled until the API call is complete.
If you need to send multiple SMS-MT while not blocking the request thread, you will want to defer sending to a broker.
This library integrates easily with celery so you can do just that in a breeze.
To use Asynchronous SMS-MT sending, you will need to :
Install and configure celery onto your project (see instructions bellow if needed)
Edit your settings.py to include the following options
# wether to send asynchronously or not
'send_async': True,
# python path of your celery module containing the task
'celery_module': 'myproject.celery'
Add a custom task to your celery module
@app.task()
def submit_sms_mt_request_task(payload, message):
from orangeapisms.utils import do_submit_sms_mt_request
return do_submit_sms_mt_request(payload, message)
That’s it. Now every SMS-MT will be deferred to celery and processed by your broker.
Launch a celery worker to test it!
Basic celery configuration
If you are not familiar with celery and want to quickly test the async feature, follow this steps:
Install redis on your computer and start it
sudo apt-get install redis
service redis start
Install celery and redis with `pip install celery redis`
Add the celery configuration to your settings.py:
BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
Create a module in your project for celery:
import os
from celery import Celery
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
app = Celery('project')
app.config_from_object('django.conf:settings')
@app.task()
def submit_sms_mt_request_task(payload, message):
from orangeapisms.utils import do_submit_sms_mt_request
return do_submit_sms_mt_request(payload, message)
Launch a worker
celery -A project worker -l info
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file orangeapisms-0.28.tar.gz
.
File metadata
- Download URL: orangeapisms-0.28.tar.gz
- Upload date:
- Size: 17.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | c9aa5f4a117bbecaec2d0fd4a994556327ebe0e4dd6aa0b85b810cadc3b9ceb7 |
|
MD5 | 200a3f047c0a305762a5a7660d212553 |
|
BLAKE2b-256 | c45af3b7863dd50eb1042ae5899972146e3cefe6869d65f64ba85916d8e3b802 |