Files
notifications-api/app/clients/sms/firetext.py

89 lines
3.3 KiB
Python
Raw Normal View History

import json
import logging
2021-03-10 13:55:06 +00:00
from requests import RequestException, request
from app.clients.sms import SmsClient, SmsClientResponseException
logger = logging.getLogger(__name__)
2016-04-05 14:39:59 +01:00
# Firetext will send a delivery receipt with three different status codes.
# The `firetext_response` maps these codes to the notification statistics status and notification status.
# If we get a pending (status = 2) delivery receipt followed by a declined (status = 1) delivery receipt we will set
# the notification status to temporary-failure rather than permanent failure.
# See the code in the notification_dao.update_notifications_status_by_id
firetext_responses = {
'0': 'delivered',
'1': 'permanent-failure',
'2': 'pending'
}
2016-04-05 14:39:59 +01:00
2020-04-09 17:50:05 +01:00
firetext_codes = {
# code '000' means 'No errors reported'
'000': {'status': 'temporary-failure', 'reason': 'No error reported'},
'101': {'status': 'permanent-failure', 'reason': 'Unknown Subscriber'},
'102': {'status': 'temporary-failure', 'reason': 'Absent Subscriber'},
'103': {'status': 'temporary-failure', 'reason': 'Subscriber Busy'},
'104': {'status': 'temporary-failure', 'reason': 'No Subscriber Memory'},
'201': {'status': 'permanent-failure', 'reason': 'Invalid Number'},
'301': {'status': 'permanent-failure', 'reason': 'SMS Not Supported'},
'302': {'status': 'temporary-failure', 'reason': 'SMS Not Supported'},
'401': {'status': 'permanent-failure', 'reason': 'Message Rejected'},
'900': {'status': 'temporary-failure', 'reason': 'Routing Error'},
2020-04-09 17:50:05 +01:00
}
def get_firetext_responses(status, detailed_status_code=None):
detailed_status = firetext_codes[detailed_status_code]['reason'] if firetext_codes.get(
detailed_status_code, None
) else None
return (firetext_responses[status], detailed_status)
def get_message_status_and_reason_from_firetext_code(detailed_status_code):
return firetext_codes[detailed_status_code]['status'], firetext_codes[detailed_status_code]['reason']
2020-04-09 17:50:05 +01:00
class FiretextClient(SmsClient):
'''
FireText sms client.
'''
def init_app(self, *args, **kwargs):
super().init_app(*args, **kwargs)
self.api_key = self.current_app.config.get('FIRETEXT_API_KEY')
self.international_api_key = self.current_app.config.get('FIRETEXT_INTERNATIONAL_API_KEY')
self.url = self.current_app.config.get('FIRETEXT_URL')
@property
def name(self):
return 'firetext'
def try_send_sms(self, to, content, reference, international, sender):
data = {
"apiKey": self.international_api_key if international else self.api_key,
"from": sender,
"to": to.replace('+', ''),
"message": content,
"reference": reference
}
try:
response = request(
"POST",
self.url,
2017-04-04 16:05:25 +01:00
data=data,
timeout=60
)
response.raise_for_status()
try:
json.loads(response.text)
if response.json()['code'] != 0:
raise ValueError("Expected 'code' to be '0'")
except (ValueError, AttributeError):
raise SmsClientResponseException("Invalid response JSON")
except RequestException:
raise SmsClientResponseException("Request failed")
return response