diff --git a/subscribie/blueprints/checkout/__init__.py b/subscribie/blueprints/checkout/__init__.py index b48df5fa..5c08811e 100644 --- a/subscribie/blueprints/checkout/__init__.py +++ b/subscribie/blueprints/checkout/__init__.py @@ -277,6 +277,20 @@ def instant_payment_complete(): return redirect(url_for("checkout.thankyou", _scheme=scheme, _external=True)) +def return_thankyou_page(): + settings = Setting.query.first() + # If a custom_thank_you_url is set, + # get custom_thank_you_url + # so can redirect subscriber to the custom_thank_you_url + # otherwise use default thankyou.html + # https://github.com/Subscribie/subscribie/issues/1219 + custom_thank_you_url = settings.custom_thank_you_url + if custom_thank_you_url is None: + return render_template("thankyou.html") + else: + return redirect(custom_thank_you_url) + + @checkout.route("/thankyou", methods=["GET"]) def thankyou(): is_donation = session.get("is_donation", False) @@ -286,6 +300,15 @@ def thankyou(): log.warn("Visit to /thankyou with no plan in session") return redirect("/") + # Remove subscribie_checkout_session_id from session + checkout_session_id = session.pop("subscribie_checkout_session_id", None) + if checkout_session_id is None: + log.warning( + """checkout_session_id returned None. redirecting to thank you page.\n + This can happen if the thank you page is reloaded, for example.""" + ) + return return_thankyou_page() + # Activate shop if session["sitename"] present if session.get("sitename"): # Build activation api request @@ -321,8 +344,6 @@ def thankyou(): f"Unable to activate shop {sitename}. Unhandled reason: {e}." ) # noqa: E501 - # Remove subscribie_checkout_session_id from session - checkout_session_id = session.pop("subscribie_checkout_session_id", None) email = session.get("email", current_app.config["MAIL_DEFAULT_SENDER"]) if is_donation is False: @@ -342,7 +363,7 @@ def thankyou(): # Signal that a new subscriber has signed up signal_new_subscriber.send( - current_app._get_current_object(), email=email, subscription_uuid=uuid + current_app._get_current_object(), subscription_uuid=uuid ) else: uuid = None @@ -363,17 +384,7 @@ def thankyou(): subscription_uuid=uuid, ) - # If a custom_thank_you_url is set, - # redirect subscriber to the custom_thank_you_url - # otherwise use default thankyou.html - # https://github.com/Subscribie/subscribie/issues/1219 - settings = Setting.query.first() - - custom_thank_you_url = settings.custom_thank_you_url - if custom_thank_you_url is None: - return render_template("thankyou.html") - else: - return redirect(custom_thank_you_url) + return return_thankyou_page() @checkout.route("/stripe-create-checkout-session", methods=["POST"]) @@ -761,7 +772,6 @@ def create_subscription( if subscription.plan.is_free() is False: log.error("Could not set cancel_at: {e}") - newSubscriberEmailNotification() # Clear chosen_question_ids_answers from session since we've now stored them # Ref https://github.com/Subscribie/subscribie/issues/1374 session.pop("chosen_question_ids_answers", None) diff --git a/subscribie/email.py b/subscribie/email.py index 00475488..756004e7 100644 --- a/subscribie/email.py +++ b/subscribie/email.py @@ -5,7 +5,6 @@ Setting, User, Company, - Plan, EmailTemplate, ) from subscribie import settings @@ -53,9 +52,12 @@ def send_email(to_email=None, subject=None, body_html=None, body_plaintext=None) log.error(f"Failed to send email. {e}") -def send_welcome_email(to_email=None): +def send_welcome_email(to_email=None, subscription=None, **kwargs): company = Company.query.first() - plan = Plan.query.filter_by(uuid=session.get("plan", None)).first() + if subscription is None: + log.error("Cannot send_welcome_email because subscription is None") + return + plan = subscription.plan # Send welcome email (either default template of custom, if active) custom_template = EmailTemplate.query.first() diff --git a/subscribie/emails/user-new-subscriber-notification.jinja2.html b/subscribie/emails/user-new-subscriber-notification.jinja2.html new file mode 100644 index 00000000..9d582506 --- /dev/null +++ b/subscribie/emails/user-new-subscriber-notification.jinja2.html @@ -0,0 +1,9 @@ +You have a new subscriber!
+ +{% if subscriber_email %} +Email: {{ subscriber_email }}
+{% endif %} + +{% if subscription %} +Name: {{ subscription.person.given_name }} {{ subscription.person.family_name }}
+{% endif %} \ No newline at end of file diff --git a/subscribie/notifications.py b/subscribie/notifications.py index 4cd969ac..5e59b1e9 100644 --- a/subscribie/notifications.py +++ b/subscribie/notifications.py @@ -17,11 +17,28 @@ def newSubscriberEmailNotification(*args, **kwargs): try: company = Company.query.first() msg = EmailMessageQueue() - msg["subject"] = f"{company.name} - new subscriber" + subscriber_email = kwargs.get("subscriber_email") + log.debug( + f"newSubscriberEmailNotification subscriber_email is: {subscriber_email}" + ) + msg["subject"] = f"{company.name} - new subscriber ({subscriber_email})" msg["from"] = current_app.config["EMAIL_LOGIN_FROM"] shopadmins = User.query.all() # all shop admins msg["to"] = [user.email for user in shopadmins] # all shop admins - msg.set_content("you have a new subscriber!") + # use user-new-subscriber-notification.jinja2.html + email_template = str( + Path( + current_app.root_path + + "/emails/user-new-subscriber-notification.jinja2.html" + ) + ) + with open(email_template) as file_: + template = Template(file_.read()) + html = template.render(**kwargs) + msg.add_alternative(html, subtype="html") + log.debug( + f"newSubscriberEmailNotification rendered as:\nSubject: {msg['subject']}\n{html}" # noqa: E501 + ) setting = Setting.query.first() if setting.reply_to_email_address is not None: msg["reply-to"] = setting.reply_to_email_address diff --git a/subscribie/receivers.py b/subscribie/receivers.py index 4be254df..34847e70 100644 --- a/subscribie/receivers.py +++ b/subscribie/receivers.py @@ -4,7 +4,10 @@ send_donation_thankyou_email, send_welcome_email, ) -from subscribie.notifications import subscriberPaymentFailedNotification +from subscribie.notifications import ( + subscriberPaymentFailedNotification, + newSubscriberEmailNotification, +) from subscribie.models import Subscription, Document from subscribie.database import database import sqlalchemy @@ -100,8 +103,31 @@ def receiver_send_subscriber_payment_failed_notification_email(*args, **kwargs): def receiver_new_subscriber(*args, **kwargs): - to_email = kwargs.get("email") - send_welcome_email(to_email=to_email) + subscription_uuid = kwargs.get("subscription_uuid") + subscription = None + try: + subscription = ( + Subscription.query.where(Subscription.uuid == subscription_uuid) + .execution_options(include_archived=True) + .one() + ) + subscriber_email = subscription.person.email + except sqlalchemy.exc.NoResultFound: + if subscription is None and subscription_uuid != "test": + msg = "Got receiver_new_subscriber event but no associated subscription found." # noqa: E501 + log.error(msg) + return + elif subscription_uuid == "test": + log.info("Testing receiver_new_subscriber with dummy subscription") + subscriber_email = "test-subscriber@example.com" + + kwargs = {} + kwargs["subscription_uuid"] = subscription_uuid + kwargs["subscriber_email"] = subscriber_email + kwargs["subscription"] = subscription + + send_welcome_email(to_email=subscriber_email, subscription=subscription) + newSubscriberEmailNotification(**kwargs) def receiver_new_donation(*args, **kwargs): diff --git a/subscribie/views.py b/subscribie/views.py index 3f262289..23e99a56 100644 --- a/subscribie/views.py +++ b/subscribie/views.py @@ -29,7 +29,8 @@ ) from subscribie.blueprints.style import inject_custom_style from subscribie.database import database -from subscribie.signals import register_signal_handlers +from subscribie.signals import register_signal_handlers, signal_new_subscriber + from subscribie.blueprints.admin.stats import ( get_number_of_active_subscribers, get_monthly_revenue, @@ -48,6 +49,7 @@ from pathlib import PurePosixPath from urllib.parse import unquote from sqlalchemy import func +from subscribie.notifications import newSubscriberEmailNotification log = logging.getLogger(__name__) @@ -177,6 +179,12 @@ def health(): return "OK", 200 +@bp.route("/test-signal_new_subscriber") +def test_email(): + signal_new_subscriber.send(subscription_uuid="test") + return "Test signal_new_subscriber email generated." + + @bp.route("/notification") def test_notifications(): log.debug("Test debug notification")