Merge pull request #1354 from alphagov/sms_sender_id-for-post-notfications

SMS sender id for post notifications
This commit is contained in:
Rebecca Law
2017-11-01 11:34:17 +00:00
committed by GitHub
16 changed files with 414 additions and 81 deletions

View File

@@ -33,6 +33,7 @@ from app.models import (
ServiceEmailReplyTo,
Template,
EMAIL_TYPE,
SMS_TYPE,
KEY_TYPE_NORMAL,
KEY_TYPE_TEST,
LETTER_TYPE,
@@ -43,7 +44,9 @@ from app.models import (
NOTIFICATION_TECHNICAL_FAILURE,
NOTIFICATION_TEMPORARY_FAILURE,
NOTIFICATION_PERMANENT_FAILURE,
NOTIFICATION_SENT
NOTIFICATION_SENT,
NotificationSmsSender,
ServiceSmsSender
)
from app.dao.dao_utils import transactional
@@ -372,15 +375,19 @@ def delete_notifications_created_more_than_a_week_ago_by_type(notification_type)
seven_days_ago = date.today() - timedelta(days=7)
# Following could be refactored when NotificationSmsReplyTo and NotificationLetterContact in models.py
if notification_type == EMAIL_TYPE:
if notification_type in [EMAIL_TYPE, SMS_TYPE]:
subq = db.session.query(Notification.id).filter(
func.date(Notification.created_at) < seven_days_ago,
Notification.notification_type == notification_type
).subquery()
deleted = db.session.query(
NotificationEmailReplyTo
if notification_type == EMAIL_TYPE:
notification_sender_mapping_table = NotificationEmailReplyTo
if notification_type == SMS_TYPE:
notification_sender_mapping_table = NotificationSmsSender
db.session.query(
notification_sender_mapping_table
).filter(
NotificationEmailReplyTo.notification_id.in_(subq)
notification_sender_mapping_table.notification_id.in_(subq)
).delete(synchronize_session='fetch')
deleted = db.session.query(Notification).filter(
@@ -650,3 +657,23 @@ def dao_get_last_notification_added_for_job_id(job_id):
).first()
return last_notification_added
@transactional
def dao_create_notification_sms_sender_mapping(notification_id, sms_sender_id):
notification_to_sms_sender = NotificationSmsSender(
notification_id=notification_id,
service_sms_sender_id=sms_sender_id
)
db.session.add(notification_to_sms_sender)
def dao_get_notification_sms_sender_mapping(notification_id):
sms_sender = ServiceSmsSender.query.join(
NotificationSmsSender
).filter(
NotificationSmsSender.notification_id == notification_id
).first()
if sms_sender:
return sms_sender.sms_sender

View File

@@ -10,7 +10,7 @@ from app.dao.dao_utils import (
transactional,
version_class
)
from app.dao.notifications_dao import get_financial_year
from app.dao.date_util import get_financial_year
from app.dao.service_sms_sender_dao import insert_service_sms_sender
from app.models import (
NotificationStatistics,

View File

@@ -11,8 +11,8 @@ from notifications_utils.template import HTMLEmailTemplate, PlainTextEmailTempla
from app import clients, statsd_client, create_uuid
from app.dao.notifications_dao import (
dao_update_notification,
dao_get_notification_email_reply_for_notification
)
dao_get_notification_email_reply_for_notification,
dao_get_notification_sms_sender_mapping)
from app.dao.provider_details_dao import (
get_provider_details_by_notification_type,
dao_toggle_sms_provider
@@ -69,11 +69,15 @@ def send_sms_to_provider(notification):
raise
else:
try:
sms_sender = dao_get_notification_sms_sender_mapping(notification.id)
if not sms_sender:
sms_sender = service.get_default_sms_sender()
provider.send_sms(
to=validate_and_format_phone_number(notification.to, international=notification.international),
content=str(template),
reference=str(notification.id),
sender=service.get_default_sms_sender()
sender=sms_sender
)
except Exception as e:
dao_toggle_sms_provider(provider.name)

View File

@@ -17,7 +17,8 @@ from app.models import SMS_TYPE, Notification, KEY_TYPE_TEST, EMAIL_TYPE, NOTIFI
from app.dao.notifications_dao import (dao_create_notification,
dao_delete_notifications_and_history_by_id,
dao_created_scheduled_notification,
dao_create_notification_email_reply_to_mapping)
dao_create_notification_email_reply_to_mapping,
dao_create_notification_sms_sender_mapping)
from app.v2.errors import BadRequestError
from app.utils import get_template_instance, cache_key_for_service_template_counter, convert_bst_to_utc
@@ -146,3 +147,7 @@ def persist_scheduled_notification(notification_id, scheduled_for):
def persist_email_reply_to_id_for_notification(notification_id, email_reply_to_id):
dao_create_notification_email_reply_to_mapping(notification_id, email_reply_to_id)
def persist_sms_sender_id_for_notification(notification_id, sms_sender_id):
dao_create_notification_sms_sender_mapping(notification_id, sms_sender_id)

View File

@@ -8,6 +8,7 @@ from notifications_utils.recipients import (
from notifications_utils.clients.redis import rate_limit_cache_key, daily_limit_cache_key
from app.dao import services_dao, templates_dao
from app.dao.service_sms_sender_dao import dao_get_service_sms_senders_by_id
from app.models import (
INTERNATIONAL_SMS_TYPE, SMS_TYPE, EMAIL_TYPE,
KEY_TYPE_TEST, KEY_TYPE_TEAM, SCHEDULE_NOTIFICATIONS
@@ -135,11 +136,27 @@ def validate_template(template_id, personalisation, service, notification_type):
return template, template_with_content
def check_service_email_reply_to_id(service_id, reply_to_id):
if not (reply_to_id is None):
def check_service_email_reply_to_id(service_id, reply_to_id, notification_type):
if reply_to_id:
if notification_type != EMAIL_TYPE:
message = 'email_reply_to_id is not a valid option for {} notification'.format(notification_type)
raise BadRequestError(message=message)
try:
dao_get_reply_to_by_id(service_id, reply_to_id)
except NoResultFound:
message = 'email_reply_to_id {} does not exist in database for service id {}'\
.format(reply_to_id, service_id)
raise BadRequestError(message=message)
def check_service_sms_sender_id(service_id, sms_sender_id, notification_type):
if sms_sender_id:
if notification_type != SMS_TYPE:
message = 'sms_sender_id is not a valid option for {} notification'.format(notification_type)
raise BadRequestError(message=message)
try:
dao_get_service_sms_senders_by_id(service_id, sms_sender_id)
except NoResultFound:
message = 'sms_sender_id {} does not exist in database for service id {}'\
.format(sms_sender_id, service_id)
raise BadRequestError(message=message)

View File

@@ -2,13 +2,13 @@ from app.config import QueueNames
from app.notifications.validators import (
check_service_over_daily_message_limit,
validate_and_format_recipient,
validate_template,
check_service_email_reply_to_id)
validate_template)
from app.notifications.process_notifications import (
create_content_for_notification,
persist_notification,
send_notification_to_queue,
persist_email_reply_to_id_for_notification)
persist_email_reply_to_id_for_notification,
persist_sms_sender_id_for_notification
)
from app.models import (
KEY_TYPE_NORMAL,
PRIORITY,
@@ -64,9 +64,11 @@ def send_one_off_notification(service_id, post_data):
created_by_id=post_data['created_by']
)
sender_id = post_data.get('sender_id', None)
if sender_id and template.template_type == EMAIL_TYPE:
check_service_email_reply_to_id(service_id, sender_id)
persist_email_reply_to_id_for_notification(notification.id, sender_id)
if sender_id:
if template.template_type == EMAIL_TYPE:
persist_email_reply_to_id_for_notification(notification.id, sender_id)
if template.template_type == SMS_TYPE:
persist_sms_sender_id_for_notification(notification.id, sender_id)
queue_name = QueueNames.PRIORITY if template.process_type == PRIORITY else None
send_notification_to_queue(

View File

@@ -119,7 +119,8 @@ post_sms_request = {
"phone_number": {"type": "string", "format": "phone_number"},
"template_id": uuid,
"personalisation": personalisation,
"scheduled_for": {"type": ["string", "null"], "format": "datetime"}
"scheduled_for": {"type": ["string", "null"], "format": "datetime"},
"sms_sender_id": uuid
},
"required": ["phone_number", "template_id"]
}

View File

@@ -20,8 +20,8 @@ from app.notifications.process_notifications import (
persist_notification,
persist_scheduled_notification,
send_notification_to_queue,
simulated_recipient
)
simulated_recipient,
persist_sms_sender_id_for_notification)
from app.notifications.process_letter_notifications import (
create_letter_notification
)
@@ -31,7 +31,8 @@ from app.notifications.validators import (
check_service_can_schedule_notification,
check_service_has_permission,
validate_template,
check_service_email_reply_to_id
check_service_email_reply_to_id,
check_service_sms_sender_id
)
from app.schema_validation import validate
from app.v2.errors import BadRequestError
@@ -63,12 +64,14 @@ def post_notification(notification_type):
scheduled_for = form.get("scheduled_for", None)
service_email_reply_to_id = form.get("email_reply_to_id", None)
service_sms_sender_id = form.get("sms_sender_id", None)
check_service_can_schedule_notification(authenticated_service.permissions, scheduled_for)
check_rate_limiting(authenticated_service, api_user)
check_service_email_reply_to_id(str(authenticated_service.id), service_email_reply_to_id)
check_service_email_reply_to_id(str(authenticated_service.id), service_email_reply_to_id, notification_type)
check_service_sms_sender_id(str(authenticated_service.id), service_sms_sender_id, notification_type)
template, template_with_content = validate_template(
form['template_id'],
@@ -142,9 +145,7 @@ def process_sms_or_email_notification(*, form, notification_type, api_key, templ
simulated=simulated
)
email_reply_to_id = form.get("email_reply_to_id", None)
if email_reply_to_id:
persist_email_reply_to_id_for_notification(notification.id, email_reply_to_id)
persist_sender_to_notification_mapping(form, notification)
scheduled_for = form.get("scheduled_for", None)
if scheduled_for:
@@ -163,6 +164,15 @@ def process_sms_or_email_notification(*, form, notification_type, api_key, templ
return notification
def persist_sender_to_notification_mapping(form, notification):
email_reply_to_id = form.get("email_reply_to_id", None)
if email_reply_to_id:
persist_email_reply_to_id_for_notification(notification.id, email_reply_to_id)
sms_sender_id = form.get("sms_sender_id", None)
if sms_sender_id:
persist_sms_sender_id_for_notification(notification.id, sms_sender_id)
def process_letter_notification(*, letter_data, api_key, template):
if api_key.key_type == KEY_TYPE_TEAM:
raise BadRequestError(message='Cannot send letters with a team api key', status_code=403)