def send_email_notification(notification: Notification):
    try:
        assert notification.channel is NotificationChannel.EMAIL

        recipient_email_address = validate_email(notification.recipient).email

        email = Mail(
            from_email=Config['notifications']['email_default_from_address'],
            to_emails=recipient_email_address,
            subject=notification.subject or 'This is a test Vol Portal Email',
            html_content=notification.message or
            '<strong>Test email with message</strong> <p>E-mail is working!</p>'
        )

        response = email_client.send(email)

        if response.status_code < 300:
            notification.status = NotificationStatus.SENT
            notification.sent_date = datetime.utcnow()
        else:
            notification.status = NotificationStatus.FAILED

    except Exception as e:
        logging.error(e)
        notification.status = NotificationStatus.FAILED
def send_slack_notification(notification: Notification):
    try:
        assert notification.channel is NotificationChannel.SLACK

        slack_client.chat_postMessage(channel=notification.recipient,
                                      text=notification.message)

        # WebClient automatically raises a SlackApiError if response.ok is False; no need to check
        notification.status = NotificationStatus.SENT
        notification.sent_date = datetime.utcnow()

    except Exception as e:
        logging.error(e)
        notification.status = NotificationStatus.FAILED
def send_sms_notification(notification: Notification):
    # this costs (a very small amount of) money each time we send a text; please test with another channel where possible
    try:
        assert notification.channel is NotificationChannel.SMS

        recipient_phone_number = phonenumbers.parse(notification.recipient,
                                                    None)
        assert phonenumbers.is_valid_number(recipient_phone_number) is True

        response = sms_client.messages.create(
            from_=Config['notifications']['sms_default_from_number'],
            to=phonenumbers.format_number(recipient_phone_number,
                                          phonenumbers.PhoneNumberFormat.E164),
            body=notification.message)

        if response and not response.error_code:
            notification.status = NotificationStatus.SENT
            notification.sent_date = datetime.utcnow()
        else:
            notification.status = NotificationStatus.FAILED

    except Exception as e:
        logging.error(e)
        notification.status = NotificationStatus.FAILED