mirror of
https://github.com/GSA/notifications-api.git
synced 2025-12-24 09:21:39 -05:00
This adds the `template_id` and `template_version` fields to the data sent to services from the `send_delivery_status_to_service` task. We need to account for the task not being passed these fields at first since there might be tasks retrying which don't have that data. Once all tasks have been called with the new fields we can then update the code to assume they are always there. Since we only send delivery status callbacks for SMS and emails, I've removed the tests where we call that task with letters.
147 lines
5.6 KiB
Python
147 lines
5.6 KiB
Python
import json
|
|
|
|
from flask import current_app
|
|
from notifications_utils.statsd_decorators import statsd
|
|
from requests import HTTPError, RequestException, request
|
|
|
|
from app import encryption, notify_celery
|
|
from app.config import QueueNames
|
|
from app.utils import DATETIME_FORMAT
|
|
|
|
|
|
@notify_celery.task(bind=True, name="send-delivery-status", max_retries=5, default_retry_delay=300)
|
|
@statsd(namespace="tasks")
|
|
def send_delivery_status_to_service(
|
|
self, notification_id, encrypted_status_update
|
|
):
|
|
status_update = encryption.decrypt(encrypted_status_update)
|
|
|
|
data = {
|
|
"id": str(notification_id),
|
|
"reference": status_update['notification_client_reference'],
|
|
"to": status_update['notification_to'],
|
|
"status": status_update['notification_status'],
|
|
"created_at": status_update['notification_created_at'],
|
|
"completed_at": status_update['notification_updated_at'],
|
|
"sent_at": status_update['notification_sent_at'],
|
|
"notification_type": status_update['notification_type']
|
|
}
|
|
# TODO: set the template_id and template_version keys when data dict is created once this change has
|
|
# been deployed long enough for all tasks to have those keys in status_update
|
|
if status_update.get("template_id"):
|
|
data["template_id"] = status_update['template_id']
|
|
data["template_version"] = status_update['template_version']
|
|
|
|
_send_data_to_service_callback_api(
|
|
self,
|
|
data,
|
|
status_update['service_callback_api_url'],
|
|
status_update['service_callback_api_bearer_token'],
|
|
'send_delivery_status_to_service'
|
|
)
|
|
|
|
|
|
@notify_celery.task(bind=True, name="send-complaint", max_retries=5, default_retry_delay=300)
|
|
@statsd(namespace="tasks")
|
|
def send_complaint_to_service(self, complaint_data):
|
|
complaint = encryption.decrypt(complaint_data)
|
|
|
|
data = {
|
|
"notification_id": complaint['notification_id'],
|
|
"complaint_id": complaint['complaint_id'],
|
|
"reference": complaint['reference'],
|
|
"to": complaint['to'],
|
|
"complaint_date": complaint['complaint_date']
|
|
}
|
|
|
|
_send_data_to_service_callback_api(
|
|
self,
|
|
data,
|
|
complaint['service_callback_api_url'],
|
|
complaint['service_callback_api_bearer_token'],
|
|
'send_complaint_to_service'
|
|
)
|
|
|
|
|
|
def _send_data_to_service_callback_api(self, data, service_callback_url, token, function_name):
|
|
notification_id = (data["notification_id"] if "notification_id" in data else data["id"])
|
|
try:
|
|
response = request(
|
|
method="POST",
|
|
url=service_callback_url,
|
|
data=json.dumps(data),
|
|
headers={
|
|
'Content-Type': 'application/json',
|
|
'Authorization': 'Bearer {}'.format(token)
|
|
},
|
|
timeout=60
|
|
)
|
|
current_app.logger.info('{} sending {} to {}, response {}'.format(
|
|
function_name,
|
|
notification_id,
|
|
service_callback_url,
|
|
response.status_code
|
|
))
|
|
response.raise_for_status()
|
|
except RequestException as e:
|
|
current_app.logger.warning(
|
|
"{} request failed for notification_id: {} and url: {}. exception: {}".format(
|
|
function_name,
|
|
notification_id,
|
|
service_callback_url,
|
|
e
|
|
)
|
|
)
|
|
if not isinstance(e, HTTPError) or e.response.status_code >= 500:
|
|
try:
|
|
self.retry(queue=QueueNames.CALLBACKS_RETRY)
|
|
except self.MaxRetriesExceededError:
|
|
current_app.logger.warning(
|
|
"Retry: {} has retried the max num of times for callback url {} and notification_id: {}".format(
|
|
function_name,
|
|
service_callback_url,
|
|
notification_id
|
|
)
|
|
)
|
|
else:
|
|
current_app.logger.warning(
|
|
"{} callback is not being retried for notification_id: {} and url: {}. exception: {}".format(
|
|
function_name,
|
|
notification_id,
|
|
service_callback_url,
|
|
e
|
|
)
|
|
)
|
|
|
|
|
|
def create_delivery_status_callback_data(notification, service_callback_api):
|
|
data = {
|
|
"notification_id": str(notification.id),
|
|
"notification_client_reference": notification.client_reference,
|
|
"notification_to": notification.to,
|
|
"notification_status": notification.status,
|
|
"notification_created_at": notification.created_at.strftime(DATETIME_FORMAT),
|
|
"notification_updated_at":
|
|
notification.updated_at.strftime(DATETIME_FORMAT) if notification.updated_at else None,
|
|
"notification_sent_at": notification.sent_at.strftime(DATETIME_FORMAT) if notification.sent_at else None,
|
|
"notification_type": notification.notification_type,
|
|
"service_callback_api_url": service_callback_api.url,
|
|
"service_callback_api_bearer_token": service_callback_api.bearer_token,
|
|
"template_id": str(notification.template_id),
|
|
"template_version": notification.template_version,
|
|
}
|
|
return encryption.encrypt(data)
|
|
|
|
|
|
def create_complaint_callback_data(complaint, notification, service_callback_api, recipient):
|
|
data = {
|
|
"complaint_id": str(complaint.id),
|
|
"notification_id": str(notification.id),
|
|
"reference": notification.client_reference,
|
|
"to": recipient,
|
|
"complaint_date": complaint.complaint_date.strftime(DATETIME_FORMAT),
|
|
"service_callback_api_url": service_callback_api.url,
|
|
"service_callback_api_bearer_token": service_callback_api.bearer_token,
|
|
}
|
|
return encryption.encrypt(data)
|