def send_user_reset_password(): email, errors = email_data_request_schema.load(request.get_json()) user_to_send_to = get_user_by_email(email['email']) if user_to_send_to.blocked: return jsonify({'message': 'cannot reset password: user blocked'}), 400 template = dao_get_template_by_id(current_app.config['PASSWORD_RESET_TEMPLATE_ID']) service = Service.query.get(current_app.config['NOTIFY_SERVICE_ID']) saved_notification = persist_notification( template_id=template.id, template_version=template.version, recipient=email['email'], service=service, personalisation={ 'user_name': user_to_send_to.name, 'url': _create_reset_password_url(user_to_send_to.email_address) }, notification_type=template.template_type, api_key_id=None, key_type=KEY_TYPE_NORMAL, reply_to_text=service.get_default_reply_to_email_address() ) send_notification_to_queue(saved_notification, False, queue=QueueNames.NOTIFY) return jsonify({}), 204
def send_support_email(user_id): to, errors = support_email_data_schema.load(request.get_json()) template = dao_get_template_by_id( current_app.config['CONTACT_US_TEMPLATE_ID']) service = Service.query.get(current_app.config['NOTIFY_SERVICE_ID']) saved_notification = persist_notification( template_id=template.id, template_version=template.version, recipient=to['email'], service=service, personalisation={ 'user': to['email'], 'message': to['message'], 'sender_email': to["sender"] if "sender" in to else "", 'support_type': to["support_type"] if "support_type" in to else "" }, notification_type=template.template_type, api_key_id=None, key_type=KEY_TYPE_NORMAL, reply_to_text=service.get_default_reply_to_email_address()) send_notification_to_queue(saved_notification, False, queue=QueueNames.NOTIFY) return jsonify({}), 204
def send_new_user_email_verification(user_id): # when registering, we verify all users' email addresses using this function user_to_send_to = get_user_by_id(user_id=user_id) template = dao_get_template_by_id(current_app.config['NEW_USER_EMAIL_VERIFICATION_TEMPLATE_ID']) service = Service.query.get(current_app.config['NOTIFY_SERVICE_ID']) saved_notification = persist_notification( template_id=template.id, template_version=template.version, recipient=user_to_send_to.email_address, service=service, personalisation={ 'name': user_to_send_to.name, 'url': _create_verification_url(user_to_send_to) }, notification_type=template.template_type, api_key_id=None, key_type=KEY_TYPE_NORMAL, reply_to_text=service.get_default_reply_to_email_address() ) send_notification_to_queue(saved_notification, False, queue=QueueNames.NOTIFY) return jsonify({}), 204
def _update_alert(user_to_update, changes=None): service = Service.query.get(current_app.config['NOTIFY_SERVICE_ID']) template = dao_get_template_by_id(current_app.config['ACCOUNT_CHANGE_TEMPLATE_ID']) recipient = user_to_update.email_address reply_to = template.service.get_default_reply_to_email_address() change_type_en = "" change_type_fr = "" if changes: change_type_en = update_dct_to_str(changes, 'EN') change_type_fr = update_dct_to_str(changes, 'FR') saved_notification = persist_notification( template_id=template.id, template_version=template.version, recipient=recipient, service=service, personalisation={ 'base_url': Config.ADMIN_BASE_URL, 'contact_us_url': f'{Config.ADMIN_BASE_URL}/support/ask-question-give-feedback', 'change_type_en': change_type_en, 'change_type_fr': change_type_fr, }, notification_type=template.template_type, api_key_id=None, key_type=KEY_TYPE_NORMAL, reply_to_text=reply_to ) send_notification_to_queue(saved_notification, False, queue=QueueNames.NOTIFY)
def send_user_confirm_new_email(user_id): user_to_send_to = get_user_by_id(user_id=user_id) email, errors = email_data_request_schema.load(request.get_json()) if errors: raise InvalidRequest(message=errors, status_code=400) template = dao_get_template_by_id(current_app.config['CHANGE_EMAIL_CONFIRMATION_TEMPLATE_ID']) notify_service_id = current_app.config['NOTIFY_SERVICE_ID'] saved_notification = persist_notification( template_id=template.id, template_version=template.version, recipient=email['email'], service_id=notify_service_id, personalisation={ 'name': user_to_send_to.name, 'url': _create_confirmation_url(user=user_to_send_to, email_address=email['email']), 'feedback_url': current_app.config['ADMIN_BASE_URL'] + '/feedback' }, notification_type=EMAIL_TYPE, api_key_id=None, key_type=KEY_TYPE_NORMAL ) send_notification_to_queue(saved_notification, False, queue='notify') return jsonify({}), 204
def post_email_notification(): form = validate(request.get_json(), post_email_request) service = services_dao.dao_fetch_service_by_id(api_user.service_id) check_service_message_limit(api_user.key_type, service) service_can_send_to_recipient(form["email_address"], api_user.key_type, service) template, template_with_content = __validate_template(form, service, EMAIL_TYPE) notification = persist_notification( template_id=template.id, template_version=template.version, recipient=form["email_address"], service_id=service.id, personalisation=form.get("personalisation", None), notification_type=EMAIL_TYPE, api_key_id=api_user.id, key_type=api_user.key_type, reference=form.get("reference"), ) send_notification_to_queue(notification, service.research_mode) resp = create_post_email_response_from_notification( notification=notification, content=str(template_with_content), subject=template_with_content.subject, email_from=service.email_from, url_root=request.url_root, ) return jsonify(resp), 201
def create_invited_user(service_id): request_json = request.get_json() invited_user, errors = invited_user_schema.load(request_json) save_invited_user(invited_user) template = dao_get_template_by_id( current_app.config['INVITATION_EMAIL_TEMPLATE_ID']) service = Service.query.get(current_app.config['NOTIFY_SERVICE_ID']) saved_notification = persist_notification( template_id=template.id, template_version=template.version, recipient=invited_user.email_address, service=service, personalisation={ 'user_name': invited_user.from_user.name, 'service_name': invited_user.service.name, 'url': invited_user_url( invited_user.id, request_json.get('invite_link_host'), ), }, notification_type=EMAIL_TYPE, api_key_id=None, key_type=KEY_TYPE_NORMAL, reply_to_text=invited_user.from_user.email_address) send_notification_to_queue(saved_notification, False, queue=QueueNames.NOTIFY) return jsonify(data=invited_user_schema.dump(invited_user).data), 201
def post_sms_notification(): form = validate(request.get_json(), post_sms_request) service = services_dao.dao_fetch_service_by_id(api_user.service_id) check_service_message_limit(api_user.key_type, service) service_can_send_to_recipient(form["phone_number"], api_user.key_type, service) template, template_with_content = __validate_template(form, service, SMS_TYPE) notification = persist_notification( template_id=template.id, template_version=template.version, recipient=form["phone_number"], service_id=service.id, personalisation=form.get("personalisation", None), notification_type=SMS_TYPE, api_key_id=api_user.id, key_type=api_user.key_type, reference=form.get("reference"), ) send_notification_to_queue(notification, service.research_mode) sms_sender = service.sms_sender if service.sms_sender else current_app.config.get("FROM_NUMBER") resp = create_post_sms_response_from_notification( notification, str(template_with_content), sms_sender, request.url_root ) return jsonify(resp), 201
def send_notification_to_service_users(service_id, template_id, personalisation=None, include_user_fields=None): personalisation = personalisation or {} include_user_fields = include_user_fields or [] template = dao_get_template_by_id(template_id) service = dao_fetch_service_by_id(service_id) active_users = dao_fetch_active_users_for_service(service.id) notify_service = dao_fetch_service_by_id( current_app.config['NOTIFY_SERVICE_ID']) for user in active_users: personalisation = _add_user_fields(user, personalisation, include_user_fields) notification = persist_notification( template_id=template.id, template_version=template.version, recipient=user.email_address if template.template_type == EMAIL_TYPE else user.mobile_number, service=notify_service, personalisation=personalisation, notification_type=template.template_type, api_key_id=None, key_type=KEY_TYPE_NORMAL, reply_to_text=notify_service.get_default_reply_to_email_address()) send_notification_to_queue(notification, False, queue=QueueNames.NOTIFY)
def send_already_registered_email(user_id): to, errors = email_data_request_schema.load(request.get_json()) template = dao_get_template_by_id( current_app.config['ALREADY_REGISTERED_EMAIL_TEMPLATE_ID']) service = Service.query.get(current_app.config['NOTIFY_SERVICE_ID']) saved_notification = persist_notification( template_id=template.id, template_version=template.version, recipient=to['email'], service=service, personalisation={ 'signin_url': current_app.config['ADMIN_BASE_URL'] + '/sign-in', 'forgot_password_url': current_app.config['ADMIN_BASE_URL'] + '/forgot-password', 'feedback_url': current_app.config['ADMIN_BASE_URL'] + '/support' }, notification_type=template.template_type, api_key_id=None, key_type=KEY_TYPE_NORMAL, reply_to_text=service.get_default_reply_to_email_address()) send_notification_to_queue(saved_notification, False, queue=QueueNames.NOTIFY) return jsonify({}), 204
def test_send_notification_to_queue( notify_db, notify_db_session, research_mode, requested_queue, notification_type, key_type, expected_queue, expected_task, mocker, ): mocked = mocker.patch('app.celery.{}.apply_async'.format(expected_task)) Notification = namedtuple( 'Notification', ['id', 'key_type', 'notification_type', 'created_at']) notification = Notification( id=uuid.uuid4(), key_type=key_type, notification_type=notification_type, created_at=datetime.datetime(2016, 11, 11, 16, 8, 18), ) send_notification_to_queue(notification=notification, research_mode=research_mode, queue=requested_queue) mocked.assert_called_once_with([str(notification.id)], queue=expected_queue)
def test_send_notification_to_queue( notify_db, notify_db_session, research_mode, requested_queue, notification_type, key_type, reply_to_text, expected_queue, expected_task, mocker, ): if "." not in expected_task: expected_task = f"provider_tasks.{expected_task}" mocked = mocker.patch(f"app.celery.{expected_task}.apply_async") notification = Notification( id=uuid.uuid4(), key_type=key_type, notification_type=notification_type, created_at=datetime.datetime(2016, 11, 11, 16, 8, 18), reply_to_text=reply_to_text, ) send_notification_to_queue(notification=notification, research_mode=research_mode, queue=requested_queue) mocked.assert_called_once_with([str(notification.id)], queue=expected_queue)
def send_user_sms_code(user_id): user_to_send_to = get_user_by_id(user_id=user_id) verify_code, errors = request_verify_code_schema.load(request.get_json()) secret_code = create_secret_code() create_user_code(user_to_send_to, secret_code, SMS_TYPE) mobile = user_to_send_to.mobile_number if verify_code.get('to', None) is None else verify_code.get('to') sms_code_template_id = current_app.config['SMS_CODE_TEMPLATE_ID'] sms_code_template = dao_get_template_by_id(sms_code_template_id) notify_service_id = current_app.config['NOTIFY_SERVICE_ID'] saved_notification = persist_notification( template_id=sms_code_template_id, template_version=sms_code_template.version, recipient=mobile, service_id=notify_service_id, personalisation={'verify_code': secret_code}, notification_type=SMS_TYPE, api_key_id=None, key_type=KEY_TYPE_NORMAL ) # Assume that we never want to observe the Notify service's research mode # setting for this notification - we still need to be able to log into the # admin even if we're doing user research using this service: send_notification_to_queue(saved_notification, False, queue='notify') return jsonify({}), 204
def send_one_off_notification(service_id, post_data): service = dao_fetch_service_by_id(service_id) template = dao_get_template_by_id_and_service_id( template_id=post_data['template_id'], service_id=service_id ) personalisation = post_data.get('personalisation', None) validate_template(template.id, personalisation, service, template.template_type) check_service_over_daily_message_limit(KEY_TYPE_NORMAL, service) validate_and_format_recipient( send_to=post_data['to'], key_type=KEY_TYPE_NORMAL, service=service, notification_type=template.template_type, allow_whitelisted_recipients=False, ) validate_created_by(service, post_data['created_by']) sender_id = post_data.get('sender_id', None) reply_to = get_reply_to_text( notification_type=template.template_type, sender_id=sender_id, service=service, template=template ) notification = persist_notification( template_id=template.id, template_version=template.version, template_postage=template.postage, recipient=post_data['to'], service=service, personalisation=personalisation, notification_type=template.template_type, api_key_id=None, key_type=KEY_TYPE_NORMAL, created_by_id=post_data['created_by'], reply_to_text=reply_to, reference=create_one_off_reference(template.template_type), ) queue_name = QueueNames.PRIORITY if template.process_type == PRIORITY else None if template.template_type == LETTER_TYPE and service.research_mode: _update_notification_status( notification, NOTIFICATION_DELIVERED, ) else: send_notification_to_queue( notification=notification, research_mode=service.research_mode, queue=queue_name, ) return {'id': str(notification.id)}
def send_branding_request(user_id): to, errors = branding_request_data_schema.load(request.get_json()) template = dao_get_template_by_id( current_app.config['BRANDING_REQUEST_TEMPLATE_ID']) service = Service.query.get(current_app.config['NOTIFY_SERVICE_ID']) saved_notification = persist_notification( template_id=template.id, template_version=template.version, recipient=to['email'], service=service, personalisation={ 'email': to['email'], 'serviceID': to['serviceID'], 'service_name': to['service_name'], 'filename': to['filename'] }, notification_type=template.template_type, api_key_id=None, key_type=KEY_TYPE_NORMAL, reply_to_text=service.get_default_reply_to_email_address()) send_notification_to_queue(saved_notification, False, queue=QueueNames.NOTIFY) return jsonify({}), 204
def replay_created_notifications(): # if the notification has not be send after 1 hour, then try to resend. resend_created_notifications_older_than = (60 * 60) for notification_type in (EMAIL_TYPE, SMS_TYPE): notifications_to_resend = notifications_not_yet_sent( resend_created_notifications_older_than, notification_type ) if len(notifications_to_resend) > 0: current_app.logger.info("Sending {} {} notifications " "to the delivery queue because the notification " "status was created.".format(len(notifications_to_resend), notification_type)) for n in notifications_to_resend: send_notification_to_queue(notification=n, research_mode=n.service.research_mode) # if the letter has not be send after an hour, then create a zendesk ticket letters = letters_missing_from_sending_bucket(resend_created_notifications_older_than) if len(letters) > 0: msg = "{} letters were created over an hour ago, " \ "but do not have an updated_at timestamp or billable units. " \ "\n Creating app.celery.letters_pdf_tasks.create_letters tasks to upload letter to S3 " \ "and update notifications for the following notification ids: " \ "\n {}".format(len(letters), [x.id for x in letters]) current_app.logger.info(msg) for letter in letters: get_pdf_for_templated_letter.apply_async([str(letter.id)], queue=QueueNames.CREATE_LETTERS_PDF)
def create_2fa_code(template_id, user_to_send_to, secret_code, recipient, personalisation): template = dao_get_template_by_id(template_id) # save the code in the VerifyCode table create_user_code(user_to_send_to, secret_code, template.template_type) reply_to = None if template.template_type == SMS_TYPE: reply_to = template.service.get_default_sms_sender() elif template.template_type == EMAIL_TYPE: reply_to = template.service.get_default_reply_to_email_address() saved_notification = persist_notification( template_id=template.id, template_version=template.version, recipient=recipient, service=template.service, personalisation=personalisation, notification_type=template.template_type, api_key_id=None, key_type=KEY_TYPE_NORMAL, reply_to_text=reply_to ) # Assume that we never want to observe the Notify service's research mode # setting for this notification - we still need to be able to log into the # admin even if we're doing user research using this service: send_notification_to_queue(saved_notification, False, queue=QueueNames.NOTIFY)
def send_user_confirm_new_email(user_id): user_to_send_to = get_user_by_id(user_id=user_id) email, errors = email_data_request_schema.load(request.get_json()) if errors: raise InvalidRequest(message=errors, status_code=400) template = dao_get_template_by_id(current_app.config['CHANGE_EMAIL_CONFIRMATION_TEMPLATE_ID']) service = Service.query.get(current_app.config['NOTIFY_SERVICE_ID']) saved_notification = persist_notification( template_id=template.id, template_version=template.version, recipient=email['email'], service=service, personalisation={ 'name': user_to_send_to.name, 'url': _create_confirmation_url(user=user_to_send_to, email_address=email['email']), 'feedback_url': current_app.config['ADMIN_BASE_URL'] + '/support/ask-question-give-feedback' }, notification_type=template.template_type, api_key_id=None, key_type=KEY_TYPE_NORMAL, reply_to_text=service.get_default_reply_to_email_address() ) send_notification_to_queue(saved_notification, False, queue=QueueNames.NOTIFY) return jsonify({}), 204
def test_send_notification_to_queue_throws_exception_deletes_notification(sample_notification, mocker): mocked = mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async', side_effect=Boto3Error("EXPECTED")) with pytest.raises(SendNotificationToQueueError): send_notification_to_queue(sample_notification, False) mocked.assert_called_once_with([(str(sample_notification.id))], queue='send-sms') assert Notification.query.count() == 0 assert NotificationHistory.query.count() == 0
def test_send_notification_to_queue_throws_exception_deletes_notification(sample_notification, mocker): mocked = mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async', side_effect=Boto3Error("EXPECTED")) with pytest.raises(Boto3Error): send_notification_to_queue(sample_notification, False) mocked.assert_called_once_with([(str(sample_notification.id))], queue='send-sms-tasks') assert Notification.query.count() == 0 assert NotificationHistory.query.count() == 0
def update_user_attribute(user_id): user_to_update = get_user_by_id(user_id=user_id) req_json = request.get_json() if 'updated_by' in req_json: updated_by = get_user_by_id(user_id=req_json.pop('updated_by')) else: updated_by = None update_dct, errors = user_update_schema_load_json.load(req_json) if errors: raise InvalidRequest(errors, status_code=400) save_user_attribute(user_to_update, update_dict=update_dct) service = Service.query.get(current_app.config['NOTIFY_SERVICE_ID']) # Alert user that account change took place user_alert_dct = update_dct.copy() user_alert_dct.pop('blocked', None) user_alert_dct.pop('current_session_id', None) if not updated_by and user_alert_dct: _update_alert(user_to_update, user_alert_dct) # Alert that team member edit user if updated_by: if 'email_address' in update_dct: template = dao_get_template_by_id( current_app.config['TEAM_MEMBER_EDIT_EMAIL_TEMPLATE_ID']) recipient = user_to_update.email_address reply_to = template.service.get_default_reply_to_email_address() elif 'mobile_number' in update_dct: template = dao_get_template_by_id( current_app.config['TEAM_MEMBER_EDIT_MOBILE_TEMPLATE_ID']) recipient = user_to_update.mobile_number reply_to = template.service.get_default_sms_sender() else: return jsonify(data=user_to_update.serialize()), 200 saved_notification = persist_notification( template_id=template.id, template_version=template.version, recipient=recipient, service=service, personalisation={ 'name': user_to_update.name, 'servicemanagername': updated_by.name, 'email address': user_to_update.email_address }, notification_type=template.template_type, api_key_id=None, key_type=KEY_TYPE_NORMAL, reply_to_text=reply_to) send_notification_to_queue(saved_notification, False, queue=QueueNames.NOTIFY) return jsonify(data=user_to_update.serialize()), 200
def save_sms(self, service_id, notification_id, encrypted_notification, sender_id=None): notification = encryption.decrypt(encrypted_notification) service = dao_fetch_service_by_id(service_id) template = dao_get_template_by_id(notification["template"], version=notification["template_version"]) if sender_id: reply_to_text = dao_get_service_sms_senders_by_id( service_id, sender_id).sms_sender else: reply_to_text = template.get_reply_to_text() if not service_allowed_to_send_to(notification["to"], service, KEY_TYPE_NORMAL): current_app.logger.debug( "SMS {} failed as restricted service".format(notification_id)) return check_service_over_daily_message_limit(KEY_TYPE_NORMAL, service) try: # this task is used by two main things... process_job and process_sms_or_email_notification # if the data is not present in the encrypted data then fallback on whats needed for process_job saved_notification = persist_notification( notification_id=notification.get("id", notification_id), template_id=notification["template"], template_version=notification["template_version"], recipient=notification["to"], service=service, personalisation=notification.get("personalisation"), notification_type=SMS_TYPE, simulated=notification.get("simulated", None), api_key_id=notification.get("api_key", None), key_type=notification.get("key_type", KEY_TYPE_NORMAL), created_at=datetime.utcnow(), job_id=notification.get("job", None), job_row_number=notification.get("row_number", None), reply_to_text=reply_to_text, ) send_notification_to_queue( saved_notification, service.research_mode, queue=notification.get("queue") or template.queue_to_use(), ) current_app.logger.debug("SMS {} created at {} for job {}".format( saved_notification.id, saved_notification.created_at, notification.get("job", None), )) except SQLAlchemyError as e: handle_exception(self, notification, notification_id, e)
def save_letter( self, service_id, notification_id, encrypted_notification, ): notification = encryption.decrypt(encrypted_notification) # we store the recipient as just the first item of the person's address recipient = notification["personalisation"]["addressline1"] service = dao_fetch_service_by_id(service_id) template = dao_get_template_by_id(notification["template"], version=notification["template_version"]) check_service_over_daily_message_limit(KEY_TYPE_NORMAL, service) try: # if we don't want to actually send the letter, then start it off in SENDING so we don't pick it up status = NOTIFICATION_CREATED if not service.research_mode else NOTIFICATION_SENDING saved_notification = persist_notification( template_id=notification["template"], template_version=notification["template_version"], template_postage=template.postage, recipient=recipient, service=service, personalisation=notification["personalisation"], notification_type=LETTER_TYPE, api_key_id=notification.get("api_key", None), key_type=KEY_TYPE_NORMAL, created_at=datetime.utcnow(), job_id=notification["job"], job_row_number=notification["row_number"], notification_id=notification_id, reference=create_random_identifier(), reply_to_text=template.get_reply_to_text(), status=status, ) if not service.research_mode: send_notification_to_queue(saved_notification, service.research_mode) elif current_app.config["NOTIFY_ENVIRONMENT"] in [ "preview", "development" ]: research_mode_tasks.create_fake_letter_response_file.apply_async( (saved_notification.reference, ), queue=QueueNames.RESEARCH_MODE) else: update_notification_status_by_reference( saved_notification.reference, "delivered") current_app.logger.debug("Letter {} created at {}".format( saved_notification.id, saved_notification.created_at)) except SQLAlchemyError as e: handle_exception(self, notification, notification_id, e)
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 send_one_off_notification(service_id, post_data): service = dao_fetch_service_by_id(service_id) template = dao_get_template_by_id_and_service_id(template_id=post_data["template_id"], service_id=service_id) personalisation = post_data.get("personalisation", None) validate_template(template.id, personalisation, service, template.template_type) check_service_over_daily_message_limit(KEY_TYPE_NORMAL, service) validate_and_format_recipient( send_to=post_data["to"], key_type=KEY_TYPE_NORMAL, service=service, notification_type=template.template_type, allow_safelisted_recipients=False, ) validate_created_by(service, post_data["created_by"]) sender_id = post_data.get("sender_id", None) reply_to = get_reply_to_text( notification_type=template.template_type, sender_id=sender_id, service=service, template=template, ) notification = persist_notification( template_id=template.id, template_version=template.version, template_postage=template.postage, recipient=post_data["to"], service=service, personalisation=personalisation, notification_type=template.template_type, api_key_id=None, key_type=KEY_TYPE_NORMAL, created_by_id=post_data["created_by"], reply_to_text=reply_to, reference=create_one_off_reference(template.template_type), ) if template.template_type == LETTER_TYPE and service.research_mode: _update_notification_status( notification, NOTIFICATION_DELIVERED, ) else: send_notification_to_queue( notification=notification, research_mode=service.research_mode, queue=template.queue_to_use(), ) return {"id": str(notification.id)}
def send_scheduled_notifications(): try: scheduled_notifications = dao_get_scheduled_notifications() for notification in scheduled_notifications: send_notification_to_queue(notification, notification.service.research_mode) set_scheduled_notification_to_processed(notification.id) current_app.logger.info( "Sent {} scheduled notifications to the provider queue".format(len(scheduled_notifications))) except SQLAlchemyError: current_app.logger.exception("Failed to send scheduled notifications") raise
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 update_service(service_id): req_json = request.get_json() fetched_service = dao_fetch_service_by_id(service_id) # Capture the status change here as Marshmallow changes this later service_going_live = fetched_service.restricted and not req_json.get('restricted', True) service_go_live_requested = 'go_live_user' in req_json current_data = dict(service_schema.dump(fetched_service).data.items()) current_data.update(request.get_json()) service = service_schema.load(current_data).data if 'email_branding' in req_json: email_branding_id = req_json['email_branding'] service.email_branding = None if not email_branding_id else EmailBranding.query.get(email_branding_id) if 'letter_branding' in req_json: letter_branding_id = req_json['letter_branding'] service.letter_branding = None if not letter_branding_id else LetterBranding.query.get(letter_branding_id) dao_update_service(service) if service_go_live_requested: template = dao_get_template_by_id(current_app.config['NOTIFY_ADMIN_OF_GO_LIVE_REQUEST_TEMPLATE_ID']) service_url = "{}/services/{}".format(current_app.config['ADMIN_BASE_URL'], str(service.id)) saved_notification = persist_notification( template_id=template.id, template_version=template.version, recipient=get_or_build_support_email_address(), service=template.service, personalisation={ 'service_name': service.name, 'service_dashboard_url': service_url }, notification_type=EMAIL_TYPE, api_key_id=None, key_type=KEY_TYPE_NORMAL, reply_to_text=get_or_build_support_email_address() ) send_notification_to_queue(saved_notification, research_mode=False, queue=QueueNames.NOTIFY) if service_going_live: send_notification_to_service_users( service_id=service_id, template_id=current_app.config['SERVICE_NOW_LIVE_TEMPLATE_ID'], personalisation={ 'service_name': current_data['name'], 'message_limit': '{:,}'.format(current_data['message_limit']) }, include_user_fields=['name'] ) return jsonify(data=service_schema.dump(fetched_service).data), 200
def send_letters_volume_email_to_dvla(letters_volumes, date): personalisation = { 'total_volume': 0, 'first_class_volume': 0, 'second_class_volume': 0, 'international_volume': 0, 'total_sheets': 0, 'first_class_sheets': 0, "second_class_sheets": 0, 'international_sheets': 0, 'date': date.strftime("%d %B %Y") } for item in letters_volumes: personalisation['total_volume'] += item.letters_count personalisation['total_sheets'] += item.sheets_count if f"{item.postage}_class_volume" in personalisation: personalisation[ f"{item.postage}_class_volume"] = item.letters_count personalisation[f"{item.postage}_class_sheets"] = item.sheets_count else: personalisation["international_volume"] += item.letters_count personalisation["international_sheets"] += item.sheets_count template = dao_get_template_by_id( current_app.config['LETTERS_VOLUME_EMAIL_TEMPLATE_ID']) recipients = current_app.config['DVLA_EMAIL_ADDRESSES'] reply_to = template.service.get_default_reply_to_email_address() service = Service.query.get(current_app.config['NOTIFY_SERVICE_ID']) # avoid circular imports: from app.notifications.process_notifications import ( persist_notification, send_notification_to_queue, ) for recipient in recipients: saved_notification = persist_notification( template_id=template.id, template_version=template.version, recipient=recipient, service=service, personalisation=personalisation, notification_type=template.template_type, api_key_id=None, key_type=KEY_TYPE_NORMAL, reply_to_text=reply_to) send_notification_to_queue(saved_notification, False, queue=QueueNames.NOTIFY)
def replay_created_notifications(): # if the notification has not be send after 4 hours + 15 minutes, then try to resend. resend_created_notifications_older_than = (60 * 60 * 4) + (60 * 15) for notification_type in (EMAIL_TYPE, SMS_TYPE): notifications_to_resend = notifications_not_yet_sent( resend_created_notifications_older_than, notification_type ) current_app.logger.info("Sending {} {} notifications " "to the delivery queue because the notification " "status was created.".format(len(notifications_to_resend), notification_type)) for n in notifications_to_resend: send_notification_to_queue(notification=n, research_mode=n.service.research_mode)
def _send_notification(template_id, recipient, personalisation): template = dao_get_template_by_id(template_id) saved_notification = persist_notification( template_id=template.id, template_version=template.version, recipient=recipient, service=notify_service, personalisation=personalisation, notification_type=template.template_type, api_key_id=None, key_type=KEY_TYPE_NORMAL, reply_to_text=notify_service.get_default_reply_to_email_address() ) send_notification_to_queue(saved_notification, research_mode=False, queue=QueueNames.NOTIFY)
def test_send_notification_to_queue(notify_db, notify_db_session, research_mode, requested_queue, expected_queue, notification_type, key_type, mocker): mocked = mocker.patch('app.celery.provider_tasks.deliver_{}.apply_async'.format(notification_type)) Notification = namedtuple('Notification', ['id', 'key_type', 'notification_type', 'created_at']) notification = Notification( id=uuid.uuid4(), key_type=key_type, notification_type=notification_type, created_at=datetime.datetime(2016, 11, 11, 16, 8, 18), ) send_notification_to_queue(notification=notification, research_mode=research_mode, queue=requested_queue) mocked.assert_called_once_with([str(notification.id)], queue=expected_queue)
def save_sms(self, service_id, notification_id, encrypted_notification, sender_id=None): notification = encryption.decrypt(encrypted_notification) service = dao_fetch_service_by_id(service_id) template = dao_get_template_by_id(notification['template'], version=notification['template_version']) if sender_id: reply_to_text = dao_get_service_sms_senders_by_id( service_id, sender_id).sms_sender else: reply_to_text = template.get_reply_to_text() if not service_allowed_to_send_to(notification['to'], service, KEY_TYPE_NORMAL): current_app.logger.debug( "SMS {} failed as restricted service".format(notification_id)) return try: saved_notification = persist_notification( template_id=notification['template'], template_version=notification['template_version'], recipient=notification['to'], service=service, personalisation=notification.get('personalisation'), notification_type=SMS_TYPE, api_key_id=None, key_type=KEY_TYPE_NORMAL, created_at=datetime.utcnow(), job_id=notification.get('job', None), job_row_number=notification.get('row_number', None), notification_id=notification_id, reply_to_text=reply_to_text) send_notification_to_queue(saved_notification, service.research_mode) current_app.logger.debug("SMS {} created at {} for job {}".format( saved_notification.id, saved_notification.created_at, notification.get('job', None))) except SQLAlchemyError as e: handle_exception(self, notification, notification_id, e)
def send_notification_to_notify_support(template_id, personalisation=None): personalisation = personalisation or {} template = dao_get_template_by_id(template_id) notify_service = dao_fetch_service_by_id(current_app.config['NOTIFY_SERVICE_ID']) validate_template(template.id, personalisation, notify_service, template.template_type) notification = persist_notification( template_id=template.id, template_version=template.version, recipient=current_app.config['NOTIFY_SUPPORT_EMAIL'], service=notify_service, personalisation=personalisation, notification_type=template.template_type, api_key_id=None, key_type=KEY_TYPE_NORMAL, reply_to_text=notify_service.get_default_reply_to_email_address() ) send_notification_to_queue(notification, False, queue=QueueNames.NOTIFY)
def verify_reply_to_email_address(service_id): email_address, errors = email_data_request_schema.load(request.get_json()) check_if_reply_to_address_already_in_use(service_id, email_address["email"]) template = dao_get_template_by_id(current_app.config['REPLY_TO_EMAIL_ADDRESS_VERIFICATION_TEMPLATE_ID']) notify_service = Service.query.get(current_app.config['NOTIFY_SERVICE_ID']) saved_notification = persist_notification( template_id=template.id, template_version=template.version, recipient=email_address["email"], service=notify_service, personalisation='', notification_type=template.template_type, api_key_id=None, key_type=KEY_TYPE_NORMAL, reply_to_text=notify_service.get_default_reply_to_email_address() ) send_notification_to_queue(saved_notification, False, queue=QueueNames.NOTIFY) return jsonify(data={"id": saved_notification.id}), 201
def invite_user_to_org(organisation_id): data = request.get_json() validate(data, post_create_invited_org_user_status_schema) invited_org_user = InvitedOrganisationUser( email_address=data["email_address"], invited_by_id=data["invited_by"], organisation_id=organisation_id, ) save_invited_org_user(invited_org_user) template = dao_get_template_by_id( current_app.config["ORGANISATION_INVITATION_EMAIL_TEMPLATE_ID"]) saved_notification = persist_notification( template_id=template.id, template_version=template.version, recipient=invited_org_user.email_address, service=template.service, personalisation={ "user_name": invited_org_user.invited_by.name, "organisation_name": invited_org_user.organisation.name, "url": invited_org_user_url( invited_org_user.id, data.get("invite_link_host"), ), }, notification_type=EMAIL_TYPE, api_key_id=None, key_type=KEY_TYPE_NORMAL, reply_to_text=invited_org_user.invited_by.email_address, ) send_notification_to_queue(saved_notification, research_mode=False, queue=QueueNames.NOTIFY) return jsonify(data=invited_org_user.serialize()), 201
def send_user_email_verification(user_id): user_to_send_to = get_user_by_id(user_id=user_id) secret_code = create_secret_code() create_user_code(user_to_send_to, secret_code, 'email') template = dao_get_template_by_id(current_app.config['EMAIL_VERIFY_CODE_TEMPLATE_ID']) saved_notification = persist_notification( template_id=template.id, template_version=template.version, recipient=user_to_send_to.email_address, service_id=current_app.config['NOTIFY_SERVICE_ID'], personalisation={ 'name': user_to_send_to.name, 'url': _create_verification_url(user_to_send_to, secret_code) }, notification_type=EMAIL_TYPE, api_key_id=None, key_type=KEY_TYPE_NORMAL ) send_notification_to_queue(saved_notification, False, queue="notify") return jsonify({}), 204