mirror of
https://github.com/GSA/notifications-api.git
synced 2026-07-11 17:05:00 -04:00
save reference on outgoing SMS to be connected to inbound replies
This commit is contained in:
@@ -42,31 +42,31 @@ class AwsSnsClient(SmsClient):
|
||||
"AWS.SNS.SMS.SMSType": {
|
||||
"DataType": "String",
|
||||
"StringValue": "Transactional",
|
||||
},
|
||||
"AWS.MM.SMS.OriginationNumber": {
|
||||
"DataType": "String",
|
||||
"StringValue": self.current_app.config["AWS_US_TOLL_FREE_NUMBER"],
|
||||
}
|
||||
}
|
||||
|
||||
# If sending with a long code number, we need to use another AWS region
|
||||
# and specify the phone number we want to use as the origination number
|
||||
# sender is managed in the UI in settings > Text message senders
|
||||
send_with_dedicated_phone_number = self._send_with_dedicated_phone_number(sender)
|
||||
|
||||
if send_with_dedicated_phone_number:
|
||||
client = self._long_codes_client
|
||||
attributes["AWS.MM.SMS.OriginationNumber"] = {
|
||||
"DataType": "String",
|
||||
"StringValue": sender,
|
||||
}
|
||||
|
||||
# If the number is US based, we must use a US Toll Free number to send the message
|
||||
|
||||
country = phonenumbers.region_code_for_number(match.number)
|
||||
if country == "US":
|
||||
client = self._long_codes_client
|
||||
attributes["AWS.MM.SMS.OriginationNumber"] = {
|
||||
"DataType": "String",
|
||||
"StringValue": self.current_app.config["AWS_US_TOLL_FREE_NUMBER"],
|
||||
}
|
||||
|
||||
try:
|
||||
start_time = monotonic()
|
||||
response = client.publish(PhoneNumber=to, Message=content, MessageAttributes=attributes)
|
||||
self.current_app.logger.info('RESPONSE FROM AWS SNS:')
|
||||
for k,v in response.items():
|
||||
self.current_app.logger.info(f'{k}: {v}')
|
||||
except botocore.exceptions.ClientError as e:
|
||||
self.statsd_client.incr("clients.sns.error")
|
||||
raise str(e)
|
||||
|
||||
@@ -207,6 +207,17 @@ def dao_fetch_service_by_inbound_number(number):
|
||||
Service.id == inbound_number.service_id
|
||||
).first()
|
||||
|
||||
def dao_fetch_service_by_reference(reference):
|
||||
previous_message = Notification.query.filter(
|
||||
Notification.reference == reference
|
||||
).first()
|
||||
|
||||
if not previous_message:
|
||||
return None
|
||||
|
||||
return Service.query.filter(
|
||||
Service.id == previous_message.service_id
|
||||
).first()
|
||||
|
||||
def dao_fetch_service_by_id_with_api_keys(service_id, only_active=False):
|
||||
query = Service.query.filter_by(
|
||||
|
||||
@@ -81,7 +81,11 @@ def send_sms_to_provider(notification):
|
||||
'international': notification.international,
|
||||
}
|
||||
db.session.close() # no commit needed as no changes to objects have been made above
|
||||
provider.send_sms(**send_sms_kwargs)
|
||||
ref = provider.send_sms(**send_sms_kwargs)
|
||||
notification.reference = ref
|
||||
dao_update_notification(notification)
|
||||
|
||||
|
||||
except Exception as e:
|
||||
notification.billable_units = template.fragment_count
|
||||
dao_update_notification(notification)
|
||||
|
||||
@@ -9,7 +9,7 @@ from notifications_utils.recipients import try_validate_and_format_phone_number
|
||||
from app.celery import tasks
|
||||
from app.config import QueueNames
|
||||
from app.dao.inbound_sms_dao import dao_create_inbound_sms
|
||||
from app.dao.services_dao import dao_fetch_service_by_inbound_number
|
||||
from app.dao.services_dao import dao_fetch_service_by_reference
|
||||
from app.errors import InvalidRequest, register_errors
|
||||
from app.models import INBOUND_SMS_TYPE, SMS_TYPE, InboundSms
|
||||
from app.notifications.sns_handlers import sns_notification_handler
|
||||
@@ -52,7 +52,7 @@ def receive_sns_sms():
|
||||
# TODO use standard formatting we use for all US numbers
|
||||
inbound_number = message['destinationNumber'].replace('+','')
|
||||
|
||||
service = fetch_potential_service(inbound_number, 'sns')
|
||||
service = fetch_potential_service(message['previousPublishedMessageId'], 'sns')
|
||||
if not service:
|
||||
# since this is an issue with our service <-> number mapping, or no inbound_sms service permission
|
||||
# we should still tell SNS that we received it successfully
|
||||
@@ -218,12 +218,13 @@ def create_inbound_sms_object(service, content, from_number, provider_ref, date_
|
||||
return inbound
|
||||
|
||||
|
||||
def fetch_potential_service(inbound_number, provider_name):
|
||||
service = dao_fetch_service_by_inbound_number(inbound_number)
|
||||
def fetch_potential_service(reference, provider_name):
|
||||
service = dao_fetch_service_by_reference(reference)
|
||||
# service = dao_fetch_service_by_inbound_number(inbound_number)
|
||||
|
||||
if not service:
|
||||
current_app.logger.warning('Inbound number "{}" from {} not associated with a service'.format(
|
||||
inbound_number, provider_name
|
||||
reference, provider_name
|
||||
))
|
||||
return False
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ def sns_notification_handler(data, headers):
|
||||
current_app.logger.warning(f"Attempt to raise_for_status()SubscriptionConfirmation Type message files for response: {response.text} with error {e}")
|
||||
raise InvalidRequest("SES-SNS callback failed: attempt to raise_for_status()SubscriptionConfirmation Type message failed", 400)
|
||||
current_app.logger.info("SES-SNS auto-confirm subscription callback succeeded")
|
||||
return {'subscriptionConfirmed': True}
|
||||
return message, message.get('Type')
|
||||
|
||||
# TODO remove after smoke testing on prod is implemented
|
||||
current_app.logger.info(f"SNS message: {message} is a valid message. Attempting to process it now.")
|
||||
|
||||
Reference in New Issue
Block a user