def process_sms_or_email_notification(*, form, notification_type, api_key, template, service, reply_to_text=None): form_send_to = form[ 'email_address'] if notification_type == EMAIL_TYPE else form[ 'phone_number'] send_to = validate_and_format_recipient( send_to=form_send_to, key_type=api_key.key_type, service=service, notification_type=notification_type) # Do not persist or send notification to the queue if it is a simulated recipient simulated = simulated_recipient(send_to, notification_type) personalisation = process_document_uploads(form.get('personalisation'), service, simulated=simulated) additional_email_parameters = {"importance": form.get('importance', None), "cc_address": form.get('cc_address', None)} \ if notification_type == EMAIL_TYPE else {} notification = persist_notification( template_id=template.id, template_version=template.version, recipient=form_send_to, service=service, personalisation=personalisation, notification_type=notification_type, api_key_id=api_key.id, key_type=api_key.key_type, client_reference=form.get('reference', None), simulated=simulated, reply_to_text=reply_to_text, additional_email_parameters=additional_email_parameters) scheduled_for = form.get("scheduled_for", None) if scheduled_for: persist_scheduled_notification(notification.id, form["scheduled_for"]) else: if not simulated: queue_name = QueueNames.PRIORITY if template.process_type == PRIORITY else None send_notification_to_queue(notification=notification, research_mode=service.research_mode, queue=queue_name) else: current_app.logger.debug( "POST simulated notification for id: {}".format( notification.id)) return notification
def process_sms_or_email_notification(*, form, notification_type, api_key, template, service, reply_to_text=None): form_send_to = form[ 'email_address'] if notification_type == EMAIL_TYPE else form[ 'phone_number'] send_to = validate_and_format_recipient( send_to=form_send_to, key_type=api_key.key_type, service=service, notification_type=notification_type) # Do not persist or send notification to the queue if it is a simulated recipient simulated = simulated_recipient(send_to, notification_type) notification = persist_notification( template_id=template.id, template_version=template.version, recipient=form_send_to, service=service, personalisation=form.get('personalisation', None), notification_type=notification_type, api_key_id=api_key.id, key_type=api_key.key_type, client_reference=form.get('reference', None), simulated=simulated, reply_to_text=reply_to_text, status_callback_url=form.get('status_callback_url', None), status_callback_bearer_token=form.get('status_callback_bearer_token', None), ) scheduled_for = form.get("scheduled_for", None) if scheduled_for: persist_scheduled_notification(notification.id, form["scheduled_for"]) else: if not simulated: queue_name = QueueNames.PRIORITY if template.process_type == PRIORITY else None send_notification_to_queue(notification=notification, research_mode=service.research_mode, queue=queue_name) else: current_app.logger.debug( "POST simulated notification for id: {}".format( notification.id)) return notification
def test_simulated_recipient(notify_api, to_address, notification_type, expected): """ The values where the expected = 'research-mode' are listed in the config['SIMULATED_EMAIL_ADDRESSES'] and config['SIMULATED_SMS_NUMBERS']. These values should result in using the research mode queue. SIMULATED_EMAIL_ADDRESSES = ( '*****@*****.**', '*****@*****.**', '*****@*****.**' ) SIMULATED_SMS_NUMBERS = ('6132532222', '+16132532222', '+16132532223') """ formatted_address = None if notification_type == 'email': formatted_address = validate_and_format_email_address(to_address) else: formatted_address = validate_and_format_phone_number(to_address) is_simulated_address = simulated_recipient(formatted_address, notification_type) assert is_simulated_address == expected
def test_simulated_recipient(notify_api, to_address, notification_type, expected): """ The values where the expected = 'research-mode' are listed in the config['SIMULATED_EMAIL_ADDRESSES'] and config['SIMULATED_SMS_NUMBERS']. These values should result in using the research mode queue. SIMULATED_EMAIL_ADDRESSES = ( '*****@*****.**', '*****@*****.**', '*****@*****.**' ) SIMULATED_SMS_NUMBERS = ('+61400900000', '+61400900111', '+61400900222', '+61426305772', '+61426305773', '+61426305774') """ formatted_address = None if notification_type == 'email': formatted_address = validate_and_format_email_address(to_address) else: formatted_address = validate_and_format_phone_number_and_allow_international( to_address) is_simulated_address = simulated_recipient(formatted_address, notification_type) assert is_simulated_address == expected
def send_notification(notification_type): if notification_type not in [SMS_TYPE, EMAIL_TYPE]: msg = "{} notification type is not supported".format(notification_type) msg = msg + ", please use the latest version of the client" if notification_type == LETTER_TYPE else msg raise InvalidRequest(msg, 400) notification_form, errors = (sms_template_notification_schema if notification_type == SMS_TYPE else email_notification_schema).load( request.get_json()) if errors: raise InvalidRequest(errors, status_code=400) check_rate_limiting(authenticated_service, api_user) template = templates_dao.dao_get_template_by_id_and_service_id( template_id=notification_form['template'], service_id=authenticated_service.id) check_template_is_for_notification_type(notification_type, template.template_type) check_template_is_active(template) template_object = create_template_object_for_notification( template, notification_form.get('personalisation', {})) _service_allowed_to_send_to(notification_form, authenticated_service) if not service_has_permission(notification_type, authenticated_service.permissions): raise InvalidRequest( { 'service': [ "Cannot send {}".format( get_public_notify_type_text(notification_type, plural=True)) ] }, status_code=400) if notification_type == SMS_TYPE: _service_can_send_internationally(authenticated_service, notification_form['to']) # Do not persist or send notification to the queue if it is a simulated recipient simulated = simulated_recipient(notification_form['to'], notification_type) notification_model = persist_notification( template_id=template.id, template_version=template.version, recipient=request.get_json()['to'], service=authenticated_service, personalisation=notification_form.get('personalisation', None), notification_type=notification_type, api_key_id=api_user.id, key_type=api_user.key_type, simulated=simulated, reply_to_text=template.get_reply_to_text()) if not simulated: queue_name = QueueNames.PRIORITY if template.process_type == PRIORITY else None send_notification_to_queue( notification=notification_model, research_mode=authenticated_service.research_mode, queue=queue_name) else: current_app.logger.debug( "POST simulated notification for id: {}".format( notification_model.id)) notification_form.update({"template_version": template.version}) return jsonify(data=get_notification_return_data( notification_model.id, notification_form, template_object)), 201
def process_sms_or_email_notification(*, form, notification_type, api_key, template, service, reply_to_text=None): form_send_to = form["email_address"] if notification_type == EMAIL_TYPE else form["phone_number"] send_to = validate_and_format_recipient( send_to=form_send_to, key_type=api_key.key_type, service=service, notification_type=notification_type, ) # Do not persist or send notification to the queue if it is a simulated recipient simulated = simulated_recipient(send_to, notification_type) personalisation = process_document_uploads(form.get("personalisation"), service, simulated, template.id) notification = { "id": create_uuid(), "template": str(template.id), "template_version": str(template.version), "to": form_send_to, "personalisation": personalisation, "simulated": simulated, "api_key": str(api_key.id), "key_type": str(api_key.key_type), "client_reference": form.get("reference", None), } encrypted_notification_data = encryption.encrypt(notification) scheduled_for = form.get("scheduled_for", None) if scheduled_for: notification = persist_notification( template_id=template.id, template_version=template.version, recipient=form_send_to, service=service, personalisation=personalisation, notification_type=notification_type, api_key_id=api_key.id, key_type=api_key.key_type, client_reference=form.get("reference", None), simulated=simulated, reply_to_text=reply_to_text, ) persist_scheduled_notification(notification.id, form["scheduled_for"]) elif current_app.config["FF_NOTIFICATION_CELERY_PERSISTENCE"] and not simulated: # depending on the type route to the appropriate save task if notification_type == EMAIL_TYPE: current_app.logger.info("calling save email task") save_email.apply_async( (authenticated_service.id, create_uuid(), encrypted_notification_data), queue=QueueNames.DATABASE if not authenticated_service.research_mode else QueueNames.RESEARCH_MODE, ) elif notification_type == SMS_TYPE: save_sms.apply_async( (authenticated_service.id, create_uuid(), encrypted_notification_data), queue=QueueNames.DATABASE if not authenticated_service.research_mode else QueueNames.RESEARCH_MODE, ) else: notification = persist_notification( template_id=template.id, template_version=template.version, recipient=form_send_to, service=service, personalisation=personalisation, notification_type=notification_type, api_key_id=api_key.id, key_type=api_key.key_type, client_reference=form.get("reference", None), simulated=simulated, reply_to_text=reply_to_text, ) if not simulated: send_notification_to_queue( notification=notification, research_mode=service.research_mode, queue=template.queue_to_use(), ) else: current_app.logger.debug("POST simulated notification for id: {}".format(notification.id)) if not isinstance(notification, Notification): notification["template_id"] = notification["template"] notification["api_key_id"] = notification["api_key"] notification["template_version"] = template.version notification["service"] = service notification["service_id"] = service.id notification["reply_to_text"] = reply_to_text del notification["template"] del notification["api_key"] del notification["simulated"] notification = Notification(**notification) return notification
def process_sms_or_email_notification(*, form, notification_type, api_key, template, service, reply_to_text=None): notification_id = None form_send_to = form[ 'email_address'] if notification_type == EMAIL_TYPE else form[ 'phone_number'] send_to = validate_and_format_recipient( send_to=form_send_to, key_type=api_key.key_type, service=service, notification_type=notification_type) # Do not persist or send notification to the queue if it is a simulated recipient simulated = simulated_recipient(send_to, notification_type) personalisation, document_download_count = process_document_uploads( form.get('personalisation'), service, simulated=simulated) if str(service.id) in current_app.config.get('HIGH_VOLUME_SERVICE') and api_key.key_type == KEY_TYPE_NORMAL \ and notification_type == EMAIL_TYPE: # Put GOV.UK Email notifications onto a queue # To take the pressure off the db for API requests put the notification for our high volume service onto a queue # the task will then save the notification, then call send_notification_to_queue. # We know that this team does not use the GET request, but relies on callbacks to get the status updates. try: notification_id = uuid.uuid4() notification = save_email_to_queue( form=form, notification_id=str(notification_id), notification_type=notification_type, api_key=api_key, template=template, service_id=service.id, personalisation=personalisation, document_download_count=document_download_count, reply_to_text=reply_to_text) return notification except SQSError: # if SQS cannot put the task on the queue, it's probably because the notification body was too long and it # went over SQS's 256kb message limit. If so, we current_app.logger.info( f'Notification {notification_id} failed to save to high volume queue. Using normal flow instead' ) notification = persist_notification( notification_id=notification_id, template_id=template.id, template_version=template.version, recipient=form_send_to, service=service, personalisation=personalisation, notification_type=notification_type, api_key_id=api_key.id, key_type=api_key.key_type, client_reference=form.get('reference', None), simulated=simulated, reply_to_text=reply_to_text, document_download_count=document_download_count) scheduled_for = form.get("scheduled_for", None) if scheduled_for: persist_scheduled_notification(notification.id, form["scheduled_for"]) else: if not simulated: queue_name = QueueNames.PRIORITY if template.process_type == PRIORITY else None send_notification_to_queue(notification=notification, research_mode=service.research_mode, queue=queue_name) else: current_app.logger.debug( "POST simulated notification for id: {}".format( notification.id)) return notification
def process_sms_or_email_notification( *, form, notification_type, template, template_with_content, template_process_type, service, reply_to_text=None, ): notification_id = uuid.uuid4() form_send_to = form[ 'email_address'] if notification_type == EMAIL_TYPE else form[ 'phone_number'] send_to = validate_and_format_recipient( send_to=form_send_to, key_type=api_user.key_type, service=service, notification_type=notification_type) # Do not persist or send notification to the queue if it is a simulated recipient simulated = simulated_recipient(send_to, notification_type) personalisation, document_download_count = process_document_uploads( form.get('personalisation'), service, simulated=simulated) if document_download_count: # We changed personalisation which means we need to update the content template_with_content.values = personalisation # validate content length after url is replaced in personalisation. check_is_message_too_long(template_with_content) resp = create_response_for_post_notification( notification_id=notification_id, client_reference=form.get('reference', None), template_id=template.id, template_version=template.version, service_id=service.id, notification_type=notification_type, reply_to=reply_to_text, template_with_content=template_with_content) if service.id in current_app.config.get('HIGH_VOLUME_SERVICE') \ and api_user.key_type == KEY_TYPE_NORMAL \ and notification_type in [EMAIL_TYPE, SMS_TYPE]: # Put service with high volumes of notifications onto a queue # To take the pressure off the db for API requests put the notification for our high volume service onto a queue # the task will then save the notification, then call send_notification_to_queue. # NOTE: The high volume service should be aware that the notification is not immediately # available by a GET request, it is recommend they use callbacks to keep track of status updates. try: save_email_or_sms_to_queue( form=form, notification_id=str(notification_id), notification_type=notification_type, api_key=api_user, template=template, service_id=service.id, personalisation=personalisation, document_download_count=document_download_count, reply_to_text=reply_to_text) return resp except SQSError: # if SQS cannot put the task on the queue, it's probably because the notification body was too long and it # went over SQS's 256kb message limit. If so, we current_app.logger.info( f'Notification {notification_id} failed to save to high volume queue. Using normal flow instead' ) persist_notification(notification_id=notification_id, template_id=template.id, template_version=template.version, recipient=form_send_to, service=service, personalisation=personalisation, notification_type=notification_type, api_key_id=api_user.id, key_type=api_user.key_type, client_reference=form.get('reference', None), simulated=simulated, reply_to_text=reply_to_text, document_download_count=document_download_count) if not simulated: queue_name = QueueNames.PRIORITY if template_process_type == PRIORITY else None send_notification_to_queue_detached( key_type=api_user.key_type, notification_type=notification_type, notification_id=notification_id, research_mode=service.research_mode, # research_mode is deprecated queue=queue_name) else: current_app.logger.debug( "POST simulated notification for id: {}".format(notification_id)) return resp