Source code for app.emails

from datetime import datetime, timezone, timedelta
from itsdangerous import URLSafeTimedSerializer

from flask import flash, render_template, url_for, current_app
from flask_mail import Message

from app import mail
from app.config import appTimezone
from app.decorators import asyncr
from app.models import Users


# Sends an email with the password reset link
[docs] def send_email_to_reset_password(email): # Tokenize the email address ts = URLSafeTimedSerializer(current_app.config["SECRET_KEY"]) token = ts.dumps(email, salt="recover-key") resetLink = url_for("auth_bp.set_new_password", _external=True) + "/" + token user = Users.query.filter_by(email=email).first_or_404() # Email with this information: msg = Message("Password Reset") msg.add_recipient(email) msg.sender = (current_app.config["APP_NAME"], current_app.config["MAIL_FROM"]) msg.body = render_template( "emails/password-reset.txt", user=user, appName=current_app.config["APP_NAME"], appHome=current_app.config["APP_ROOT_URL"], resetLink=resetLink, ) msg.html = render_template( "emails/password-reset.html", user=user, appName=current_app.config["APP_NAME"], appHome=current_app.config["APP_ROOT_URL"], resetLink=resetLink, ) send_async_email(msg, current_app._get_current_object())
# Send the email for user the verify their email address
[docs] def send_email_with_code(user): # If last confirmation email was sent more than 60 seconds ago now = datetime.now(timezone.utc).replace(tzinfo=None) last_sent = user.last_confirmation_codes_sent long_enough_since_last_email = last_sent + timedelta(minutes=1) < now # If total number of confirmation emails sent is not greater than 5: max_email_limit_reached = user.number_of_email_confirmation_codes_sent == 5 if long_enough_since_last_email and not max_email_limit_reached: # Email with this information: msg = Message("Verification Code") msg.add_recipient(user.email) msg.sender = (current_app.config["APP_NAME"], current_app.config["MAIL_FROM"]) msg.body = render_template( "emails/email-verification-code.txt", user=user, appName=current_app.config["APP_NAME"], appHome=current_app.config["APP_ROOT_URL"], ) msg.html = render_template( "emails/email-verification-code.html", user=user, appName=current_app.config["APP_NAME"], appHome=current_app.config["APP_ROOT_URL"], ) send_async_email(msg, current_app._get_current_object()) user.number_of_email_confirmation_codes_sent += 1 user.last_confirmation_codes_sent = datetime.now(timezone.utc).replace( tzinfo=None ) user.save() flash( f"We have sent your verification code to {user.email}.", "info", ) elif max_email_limit_reached: flash( "We are not able to send more than 5 verification emails. Please contact us if you think you are seeing this message by error.", "danger", ) else: flash( "Please wait for 60 seconds before requesting another email to be sent.", "danger", )
# Sends an email with the password reset link
[docs] def send_email_about_subscription_confirmation(user, tier_name): # Email with this information: msg = Message("Subscription Confirmed") msg.add_recipient(user.email) msg.sender = (current_app.config["APP_NAME"], current_app.config["MAIL_FROM"]) msg.body = render_template( "emails/email-subscription-confirmed.txt", user=user, appName=current_app.config["APP_NAME"], appHome=current_app.config["APP_ROOT_URL"], tier_name=tier_name, ) msg.html = render_template( "emails/email-subscription-confirmed.html", user=user, appName=current_app.config["APP_NAME"], appHome=current_app.config["APP_ROOT_URL"], tier_name=tier_name, ) send_async_email(msg, current_app._get_current_object())
# Sends an email with the password reset link
[docs] def send_email_about_subscription_cancellation(user, tier_name, cancellation_date): # Email with this information: msg = Message("Subscription Canceled") msg.add_recipient(user.email) msg.sender = (current_app.config["APP_NAME"], current_app.config["MAIL_FROM"]) msg.body = render_template( "emails/email-subscription-canceled.txt", user=user, appName=current_app.config["APP_NAME"], appHome=current_app.config["APP_ROOT_URL"], tier_name=tier_name, cancellation_date=cancellation_date, ) msg.html = render_template( "emails/email-subscription-canceled.html", user=user, appName=current_app.config["APP_NAME"], appHome=current_app.config["APP_ROOT_URL"], tier_name=tier_name, cancellation_date=cancellation_date, ) send_async_email(msg, current_app._get_current_object())
# Sends an email with the password reset link
[docs] def send_email_about_subscription_deletion(user, tier_name): # Email with this information: msg = Message("Subscription Ended") msg.add_recipient(user.email) msg.sender = (current_app.config["APP_NAME"], current_app.config["MAIL_FROM"]) msg.body = render_template( "emails/email-subscription-deleted.txt", user=user, appName=current_app.config["APP_NAME"], appHome=current_app.config["APP_ROOT_URL"], tier_name=tier_name, ) msg.html = render_template( "emails/email-subscription-deleted.html", user=user, appName=current_app.config["APP_NAME"], appHome=current_app.config["APP_ROOT_URL"], tier_name=tier_name, ) send_async_email(msg, current_app._get_current_object())
# Async emailing - all information is passed in an instance of the Message object @asyncr
[docs] def send_async_email(msg, app): with app.app_context(): mail.send(msg)