mirror of
https://github.com/GSA/notifications-api.git
synced 2025-12-15 09:42:38 -05:00
189 lines
5.8 KiB
Python
189 lines
5.8 KiB
Python
import uuid
|
|
from datetime import datetime
|
|
|
|
from flask import current_app
|
|
from notifications_utils.recipients import (
|
|
format_email_address,
|
|
get_international_phone_info,
|
|
validate_and_format_phone_number,
|
|
)
|
|
from notifications_utils.template import PlainTextEmailTemplate, SMSMessageTemplate
|
|
|
|
from app.celery import provider_tasks
|
|
from app.config import QueueNames
|
|
from app.dao.notifications_dao import (
|
|
dao_create_notification,
|
|
dao_delete_notifications_by_id,
|
|
)
|
|
from app.models import (
|
|
EMAIL_TYPE,
|
|
KEY_TYPE_TEST,
|
|
NOTIFICATION_CREATED,
|
|
SMS_TYPE,
|
|
Notification,
|
|
)
|
|
from app.v2.errors import BadRequestError
|
|
|
|
|
|
def create_content_for_notification(template, personalisation):
|
|
if template.template_type == EMAIL_TYPE:
|
|
template_object = PlainTextEmailTemplate(
|
|
{
|
|
"content": template.content,
|
|
"subject": template.subject,
|
|
"template_type": template.template_type,
|
|
},
|
|
personalisation,
|
|
)
|
|
if template.template_type == SMS_TYPE:
|
|
template_object = SMSMessageTemplate(
|
|
{
|
|
"content": template.content,
|
|
"template_type": template.template_type,
|
|
},
|
|
personalisation,
|
|
)
|
|
|
|
check_placeholders(template_object)
|
|
|
|
return template_object
|
|
|
|
|
|
def check_placeholders(template_object):
|
|
if template_object.missing_data:
|
|
message = "Missing personalisation: {}".format(
|
|
", ".join(template_object.missing_data)
|
|
)
|
|
raise BadRequestError(fields=[{"template": message}], message=message)
|
|
|
|
|
|
def persist_notification(
|
|
*,
|
|
template_id,
|
|
template_version,
|
|
recipient,
|
|
service,
|
|
personalisation,
|
|
notification_type,
|
|
api_key_id,
|
|
key_type,
|
|
created_at=None,
|
|
job_id=None,
|
|
job_row_number=None,
|
|
reference=None,
|
|
client_reference=None,
|
|
notification_id=None,
|
|
simulated=False,
|
|
created_by_id=None,
|
|
status=NOTIFICATION_CREATED,
|
|
reply_to_text=None,
|
|
billable_units=None,
|
|
document_download_count=None,
|
|
updated_at=None,
|
|
):
|
|
current_app.logger.info("Persisting notification")
|
|
|
|
notification_created_at = created_at or datetime.utcnow()
|
|
if not notification_id:
|
|
notification_id = uuid.uuid4()
|
|
|
|
current_app.logger.info(f"Persisting notification with id {notification_id}")
|
|
|
|
notification = Notification(
|
|
id=notification_id,
|
|
template_id=template_id,
|
|
template_version=template_version,
|
|
to=recipient,
|
|
service_id=service.id,
|
|
personalisation=personalisation,
|
|
notification_type=notification_type,
|
|
api_key_id=api_key_id,
|
|
key_type=key_type,
|
|
created_at=notification_created_at,
|
|
job_id=job_id,
|
|
job_row_number=job_row_number,
|
|
client_reference=client_reference,
|
|
reference=reference,
|
|
created_by_id=created_by_id,
|
|
status=status,
|
|
reply_to_text=reply_to_text,
|
|
billable_units=billable_units,
|
|
document_download_count=document_download_count,
|
|
updated_at=updated_at,
|
|
)
|
|
|
|
if notification_type == SMS_TYPE:
|
|
formatted_recipient = validate_and_format_phone_number(
|
|
recipient, international=True
|
|
)
|
|
recipient_info = get_international_phone_info(formatted_recipient)
|
|
notification.normalised_to = formatted_recipient
|
|
notification.international = recipient_info.international
|
|
notification.phone_prefix = recipient_info.country_prefix
|
|
notification.rate_multiplier = recipient_info.billable_units
|
|
elif notification_type == EMAIL_TYPE:
|
|
current_app.logger.info(f"Persisting notification with type: {EMAIL_TYPE}")
|
|
notification.normalised_to = format_email_address(notification.to)
|
|
|
|
# if simulated create a Notification model to return but do not persist the Notification to the dB
|
|
if not simulated:
|
|
current_app.logger.info("Firing dao_create_notification")
|
|
dao_create_notification(notification)
|
|
if key_type != KEY_TYPE_TEST and current_app.config["REDIS_ENABLED"]:
|
|
current_app.logger.info(
|
|
"Redis enabled, querying cache key for service id: {}".format(
|
|
service.id
|
|
)
|
|
)
|
|
|
|
current_app.logger.info(
|
|
f"{notification_type} {notification_id} created at {notification_created_at}"
|
|
)
|
|
return notification
|
|
|
|
|
|
def send_notification_to_queue_detached(
|
|
key_type, notification_type, notification_id, queue=None
|
|
):
|
|
if key_type == KEY_TYPE_TEST:
|
|
print("send_notification_to_queue_detached key is test key")
|
|
|
|
if notification_type == SMS_TYPE:
|
|
if not queue:
|
|
queue = QueueNames.SEND_SMS
|
|
deliver_task = provider_tasks.deliver_sms
|
|
if notification_type == EMAIL_TYPE:
|
|
if not queue:
|
|
queue = QueueNames.SEND_EMAIL
|
|
deliver_task = provider_tasks.deliver_email
|
|
|
|
try:
|
|
deliver_task.apply_async([str(notification_id)], queue=queue)
|
|
except Exception:
|
|
dao_delete_notifications_by_id(notification_id)
|
|
raise
|
|
|
|
current_app.logger.debug(
|
|
f"{notification_type} {notification_id} sent to the {queue} queue for delivery"
|
|
)
|
|
|
|
|
|
def send_notification_to_queue(notification, queue=None):
|
|
send_notification_to_queue_detached(
|
|
notification.key_type,
|
|
notification.notification_type,
|
|
notification.id,
|
|
queue,
|
|
)
|
|
|
|
|
|
def simulated_recipient(to_address, notification_type):
|
|
if notification_type == SMS_TYPE:
|
|
formatted_simulated_numbers = [
|
|
validate_and_format_phone_number(number)
|
|
for number in current_app.config["SIMULATED_SMS_NUMBERS"]
|
|
]
|
|
return to_address in formatted_simulated_numbers
|
|
else:
|
|
return to_address in current_app.config["SIMULATED_EMAIL_ADDRESSES"]
|