Files
notifications-api/app/notifications/receive_notifications.py

123 lines
3.9 KiB
Python
Raw Normal View History

2017-05-22 11:26:47 +01:00
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
2017-05-22 11:26:47 +01:00
from app import statsd_client, firetext_client, mmg_client
2017-05-22 11:26:47 +01:00
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():
2017-05-22 11:26:47 +01:00
"""
{
'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()
2017-05-22 11:26:47 +01:00
potential_services = dao_fetch_services_by_sms_sender(post_data['Number'])
if len(potential_services) != 1:
current_app.logger.error('Inbound number "{}" not associated with exactly one service'.format(
post_data['Number']
))
statsd_client.incr('inbound.mmg.failed')
# since this is an issue with our service <-> number mapping, we should still tell MMG that we received
# succesfully
return 'RECEIVED', 200
2017-06-05 11:51:30 +01:00
statsd_client.incr('inbound.mmg.successful')
2017-05-22 11:26:47 +01:00
service = potential_services[0]
inbound = create_inbound_mmg_sms_object(service, post_data)
2017-05-22 11:26:47 +01:00
current_app.logger.info('{} received inbound SMS with reference {}'.format(service.id, inbound.provider_reference))
return 'RECEIVED', 200
def format_mmg_message(message):
2017-05-22 11:26:47 +01:00
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_mmg_sms_object(service, json):
message = format_mmg_message(json['Message'])
user_number = validate_and_format_phone_number(json['MSISDN'], international=True)
provider_date = json.get('DateRecieved')
if provider_date:
provider_date = format_mmg_datetime(provider_date)
2017-05-22 11:26:47 +01:00
inbound = InboundSms(
service=service,
notify_number=service.sms_sender,
user_number=user_number,
provider_date=provider_date,
provider_reference=json.get('ID'),
2017-05-22 11:26:47 +01:00
content=message,
provider=mmg_client.name
2017-05-22 11:26:47 +01:00
)
dao_create_inbound_sms(inbound)
return inbound
@receive_notifications_blueprint.route('/notifications/sms/receive/firetext', methods=['POST'])
def receive_firetext_sms():
post_data = request.form
potential_services = dao_fetch_services_by_sms_sender(post_data['destination'])
if len(potential_services) != 1:
current_app.logger.error('Inbound number "{}" not associated with exactly one service'.format(
post_data['destination']
))
statsd_client.incr('inbound.firetext.failed')
return jsonify({
"status": "ok"
}), 200
service = potential_services[0]
2017-06-05 11:51:30 +01:00
user_number = validate_and_format_phone_number(post_data['source'], international=True)
message = post_data['message']
timestamp = post_data['time']
dao_create_inbound_sms(
InboundSms(
service=service,
notify_number=service.sms_sender,
user_number=user_number,
provider_date=timestamp,
content=message,
provider=firetext_client.name
)
)
statsd_client.incr('inbound.firetext.successful')
return jsonify({
"status": "ok"
}), 200