mirror of
https://github.com/GSA/notifications-api.git
synced 2025-12-17 10:42:25 -05:00
If the service has not set the url then nothing happens. If the request to the service url returns with 500 or greater the task is retries. The task is created when the SMS provider post the inbound SMS.
138 lines
4.8 KiB
Python
138 lines
4.8 KiB
Python
from urllib.parse import unquote
|
|
|
|
import iso8601
|
|
from flask import jsonify, Blueprint, current_app, request
|
|
from notifications_utils.recipients import validate_and_format_phone_number
|
|
|
|
from app import statsd_client, firetext_client, mmg_client
|
|
from app.celery import tasks
|
|
from app.config import QueueNames
|
|
from app.dao.services_dao import dao_fetch_services_by_sms_sender
|
|
from app.dao.inbound_sms_dao import dao_create_inbound_sms
|
|
from app.models import InboundSms
|
|
from app.errors import register_errors
|
|
from app.utils import convert_bst_to_utc
|
|
|
|
receive_notifications_blueprint = Blueprint('receive_notifications', __name__)
|
|
register_errors(receive_notifications_blueprint)
|
|
|
|
|
|
@receive_notifications_blueprint.route('/notifications/sms/receive/mmg', methods=['POST'])
|
|
def receive_mmg_sms():
|
|
"""
|
|
{
|
|
'MSISDN': '447123456789'
|
|
'Number': '40604',
|
|
'Message': 'some+uri+encoded+message%3A',
|
|
'ID': 'SOME-MMG-SPECIFIC-ID',
|
|
'DateRecieved': '2017-05-21+11%3A56%3A11'
|
|
}
|
|
"""
|
|
post_data = request.get_json()
|
|
|
|
inbound_number = strip_leading_forty_four(post_data['Number'])
|
|
|
|
potential_services = fetch_potential_services(inbound_number, 'mmg')
|
|
if not potential_services:
|
|
# since this is an issue with our service <-> number mapping, we should still tell MMG that we received
|
|
# successfully
|
|
return 'RECEIVED', 200
|
|
|
|
statsd_client.incr('inbound.mmg.successful')
|
|
|
|
service = potential_services[0]
|
|
|
|
inbound = create_inbound_sms_object(service,
|
|
content=format_mmg_message(post_data["Message"]),
|
|
from_number=post_data['MSISDN'],
|
|
provider_ref=post_data["ID"],
|
|
date_received=post_data.get('DateRecieved'),
|
|
provider_name="mmg")
|
|
|
|
tasks.send_inbound_sms_to_service.apply_async([str(inbound.id), str(service.id)], queue=QueueNames.NOTIFY)
|
|
current_app.logger.info('{} received inbound SMS with reference {}'.format(service.id, inbound.provider_reference))
|
|
|
|
return 'RECEIVED', 200
|
|
|
|
|
|
@receive_notifications_blueprint.route('/notifications/sms/receive/firetext', methods=['POST'])
|
|
def receive_firetext_sms():
|
|
post_data = request.form
|
|
|
|
inbound_number = strip_leading_forty_four(post_data['destination'])
|
|
|
|
potential_services = fetch_potential_services(inbound_number, 'firetext')
|
|
if not potential_services:
|
|
return jsonify({
|
|
"status": "ok"
|
|
}), 200
|
|
|
|
service = potential_services[0]
|
|
|
|
inbound = create_inbound_sms_object(service=service,
|
|
content=post_data["message"],
|
|
from_number=post_data['source'],
|
|
provider_ref=None,
|
|
date_received=post_data['time'],
|
|
provider_name="firetext")
|
|
|
|
statsd_client.incr('inbound.firetext.successful')
|
|
|
|
tasks.send_inbound_sms_to_service.apply_async([str(inbound.id), str(service.id)], queue=QueueNames.NOTIFY)
|
|
|
|
return jsonify({
|
|
"status": "ok"
|
|
}), 200
|
|
|
|
|
|
def format_mmg_message(message):
|
|
return unquote(message.replace('+', ' '))
|
|
|
|
|
|
def format_mmg_datetime(date):
|
|
"""
|
|
We expect datetimes in format 2017-05-21+11%3A56%3A11 - ie, spaces replaced with pluses, and URI encoded
|
|
(the same as UTC)
|
|
"""
|
|
orig_date = format_mmg_message(date)
|
|
parsed_datetime = iso8601.parse_date(orig_date).replace(tzinfo=None)
|
|
return convert_bst_to_utc(parsed_datetime)
|
|
|
|
|
|
def create_inbound_sms_object(service, content, from_number, provider_ref, date_received, provider_name):
|
|
user_number = validate_and_format_phone_number(from_number, international=True)
|
|
|
|
provider_date = date_received
|
|
if provider_date:
|
|
provider_date = format_mmg_datetime(provider_date)
|
|
|
|
inbound = InboundSms(
|
|
service=service,
|
|
notify_number=service.sms_sender,
|
|
user_number=user_number,
|
|
provider_date=provider_date,
|
|
provider_reference=provider_ref,
|
|
content=content,
|
|
provider=provider_name
|
|
)
|
|
dao_create_inbound_sms(inbound)
|
|
return inbound
|
|
|
|
|
|
def fetch_potential_services(inbound_number, provider_name):
|
|
potential_services = dao_fetch_services_by_sms_sender(inbound_number)
|
|
|
|
if len(potential_services) != 1:
|
|
current_app.logger.error('Inbound number "{}" from {} not associated with exactly one service'.format(
|
|
inbound_number, provider_name
|
|
))
|
|
statsd_client.incr('inbound.{}.failed'.format(provider_name))
|
|
return False
|
|
return potential_services
|
|
|
|
|
|
def strip_leading_forty_four(number):
|
|
if number.startswith('44'):
|
|
return number.replace('44', '0', 1)
|
|
return number
|