Package: orangeapisms
Django app to add support for Orange API SMS-MO and SMS-MT (with DR)Installpip install orangeapismsEdit yoursettings.pyfile and add:INSTALLED_APPS=list(INSTALLED_APPS)+['orangeapisms','django_forms_bootstrap']Configure yourorangeapi.jsonfile (place it next to yoursettings.pyfile):{"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 migrateThat’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 APIsender_address:Your subscribed phone numbersender_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 namesend_async:whether to deffer SMS sending to celerycelery_module:python path to your celery tasks modulecountry:ISO 3166-1 code for your country (used for balance checking)fix_msisdn:whether to fix SMS-MT destination without prefixcountry_prefix:MSISDN numeric prefix for your country (to fix SMS-MT without prefix)UsageAfter installation (previous step), you are able to send & receive individual SMS.
To automatically process incoming SMS, you will have to customise thehandler modulewhich you specified inORANGE_API[‘handler_module’].The module would call three different functions based on events:smsmo(message)on an incoming SMS-MOsmsmt(message)on an outgoing (sent by you) SMS-MTsmsdr(message)on an incoming delivery-receipt notification. The passed message is the SMS-MT which received the DR.Sample handler module:importdatetimeimportloggingfromorangeapisms.utilsimportsend_smsfrommyapp.modelsimportUserModellogger=logging.getLogger(__name__)defhandle_smsmo(message):logger.info("Received an SMS-MO:{}".format(message))defregister_user(message,keyword,text):# break-down the formatted SMS into variablestry:name,sex,dob=text.split()except:returnmessage.reply('Invalid format')# valid user entriesifsexnotin['m','f']:returnmessage.reply('Unable to understand sex')# reuse input into different data structuretry:d=dob.split('-')birthdate=datetime.datetime(d[3],d[2],d[1])except:returnmessage.reply('Unable to understand date of birth')# make use of the data including message metadatauser=UserModel.objects.create(name=name,sex=sex,dob=birthdate,phone=message.sender_address)returnmessage.reply("Congratulations, you're registered as #{}".format(user.id))defbroadcast_to_users(message,keyword,text):# loop on all Users in DBforuserinUserModel.objects.all():# send a custom message to that usersend_sms(user.phone,"Hey{u},{c}".format(u=user.name,c=text))keywords={'register':register_user,'broadcast':broadcast_to_users,}# find the proper keywordkeyword,text=message.content.split(' ',1)ifkeywordinkeywords.keys():returnkeywords.get(keyword)(message,keyword,text.strip().lower())# fallback on errorreturnmessage.reply('Unknown request')defhandle_smsmt(message):logger.info("Sent an SMS-MT:{}".format(message))defhandle_smsdr(message):logger.info("Received an SMS-DR:{}".format(message))Using a broker to send SMS-MTBy 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 withceleryso 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 yoursettings.pyto 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()defsubmit_sms_mt_request_task(payload,message):fromorangeapisms.utilsimportdo_submit_sms_mt_requestreturndo_submit_sms_mt_request(payload,message)That’s it. Now every SMS-MT will be deferred to celery and processed by your broker.Launch aceleryworker to test it!Basic celery configurationIf you are not familiar with celery and want to quickly test the async feature, follow this steps:Install redis on your computer and start itsudoapt-getinstallredisserviceredisstartInstall celery and redis with`pip install celery redis`Add the celery configuration to yoursettings.py:BROKER_URL='redis://localhost:6379/0'CELERY_RESULT_BACKEND='redis://localhost:6379/0'Create a module in your project forcelery:importosfromceleryimportCeleryos.environ.setdefault('DJANGO_SETTINGS_MODULE','project.settings')app=Celery('project')app.config_from_object('django.conf:settings')@app.task()defsubmit_sms_mt_request_task(payload,message):fromorangeapisms.utilsimportdo_submit_sms_mt_requestreturndo_submit_sms_mt_request(payload,message)Launch a workercelery-Aprojectworker-linfo