mirror of
https://github.com/zulip/zulip.git
synced 2025-11-04 22:13:26 +00:00
demo-orgs: Schedule onboarding/welcome emails when owner adds email.
When a demo organization creator confirms their email change for their account, we now schedule the series of onboarding emails via enqueue_welcome_emails. If a demo organization is deactivated/deleted before the emails are sent, any scheduled emails are deleted as part of that process. We use the current datetime for getting the onboarding schedule for the onboarding emails in this case, instead of the datetime the user joined/created the organization.
This commit is contained in:
committed by
Tim Abbott
parent
bf325ff6b2
commit
28b1a071fe
@@ -686,7 +686,9 @@ def handle_missedmessage_emails(
|
||||
)
|
||||
|
||||
|
||||
def get_onboarding_email_schedule(user: UserProfile) -> dict[str, timedelta]:
|
||||
def get_onboarding_email_schedule(
|
||||
user: UserProfile, demo_organization_creator: bool = False
|
||||
) -> dict[str, timedelta]:
|
||||
onboarding_emails = {
|
||||
# The delay should be 1 hour before the below specified number of days
|
||||
# as our goal is to maximize the chance that this email is near the top
|
||||
@@ -700,7 +702,16 @@ def get_onboarding_email_schedule(user: UserProfile) -> dict[str, timedelta]:
|
||||
user_tz = user.timezone
|
||||
if user_tz == "":
|
||||
user_tz = "UTC"
|
||||
signup_day = user.date_joined.astimezone(
|
||||
|
||||
# Because demo organizations are created without setting an email for the
|
||||
# owner's account, we schedule these emails when/if they add an email to
|
||||
# their account.
|
||||
if demo_organization_creator:
|
||||
start_date = timezone_now()
|
||||
else:
|
||||
start_date = user.date_joined
|
||||
|
||||
day_of_week_user_registered = start_date.astimezone(
|
||||
zoneinfo.ZoneInfo(canonicalize_timezone(user_tz))
|
||||
).isoweekday()
|
||||
|
||||
@@ -708,27 +719,27 @@ def get_onboarding_email_schedule(user: UserProfile) -> dict[str, timedelta]:
|
||||
# -Do not send emails on Saturday or Sunday
|
||||
# -Have at least one weekday between each (potential) email
|
||||
|
||||
# User signed up on Monday
|
||||
if signup_day == 1:
|
||||
# User registered on Monday
|
||||
if day_of_week_user_registered == 1:
|
||||
# Send onboarding_team_to_zulip on Tuesday
|
||||
onboarding_emails["onboarding_team_to_zulip"] = timedelta(days=8, hours=-1)
|
||||
|
||||
# User signed up on Tuesday
|
||||
if signup_day == 2:
|
||||
# User registered on Tuesday
|
||||
if day_of_week_user_registered == 2:
|
||||
# Send onboarding_zulip_guide on Monday
|
||||
onboarding_emails["onboarding_zulip_guide"] = timedelta(days=6, hours=-1)
|
||||
# Send onboarding_team_to_zulip on Wednesday
|
||||
onboarding_emails["onboarding_team_to_zulip"] = timedelta(days=8, hours=-1)
|
||||
|
||||
# User signed up on Wednesday
|
||||
if signup_day == 3:
|
||||
# User registered on Wednesday
|
||||
if day_of_week_user_registered == 3:
|
||||
# Send onboarding_zulip_guide on Tuesday
|
||||
onboarding_emails["onboarding_zulip_guide"] = timedelta(days=6, hours=-1)
|
||||
# Send onboarding_team_to_zulip on Thursday
|
||||
onboarding_emails["onboarding_team_to_zulip"] = timedelta(days=8, hours=-1)
|
||||
|
||||
# User signed up on Thursday
|
||||
if signup_day == 4:
|
||||
# User registered on Thursday
|
||||
if day_of_week_user_registered == 4:
|
||||
# Send onboarding_zulip_topics on Monday
|
||||
onboarding_emails["onboarding_zulip_topics"] = timedelta(days=4, hours=-1)
|
||||
# Send onboarding_zulip_guide on Wednesday
|
||||
@@ -736,8 +747,8 @@ def get_onboarding_email_schedule(user: UserProfile) -> dict[str, timedelta]:
|
||||
# Send onboarding_team_to_zulip on Friday
|
||||
onboarding_emails["onboarding_team_to_zulip"] = timedelta(days=8, hours=-1)
|
||||
|
||||
# User signed up on Friday
|
||||
if signup_day == 5:
|
||||
# User registered on Friday
|
||||
if day_of_week_user_registered == 5:
|
||||
# Send onboarding_zulip_topics on Tuesday
|
||||
onboarding_emails["onboarding_zulip_topics"] = timedelta(days=4, hours=-1)
|
||||
# Send onboarding_zulip_guide on Thursday
|
||||
@@ -745,10 +756,10 @@ def get_onboarding_email_schedule(user: UserProfile) -> dict[str, timedelta]:
|
||||
# Send onboarding_team_to_zulip on Monday
|
||||
onboarding_emails["onboarding_team_to_zulip"] = timedelta(days=10, hours=-1)
|
||||
|
||||
# User signed up on Saturday; no adjustments needed
|
||||
# User registered on Saturday; no adjustments needed
|
||||
|
||||
# User signed up on Sunday
|
||||
if signup_day == 7:
|
||||
# User registered on Sunday
|
||||
if day_of_week_user_registered == 7:
|
||||
# Send onboarding_team_to_zulip on Monday
|
||||
onboarding_emails["onboarding_team_to_zulip"] = timedelta(days=8, hours=-1)
|
||||
|
||||
@@ -838,7 +849,9 @@ def send_account_registered_email(user: UserProfile, realm_creation: bool = Fals
|
||||
)
|
||||
|
||||
|
||||
def enqueue_welcome_emails(user: UserProfile, realm_creation: bool = False) -> None:
|
||||
def enqueue_welcome_emails(
|
||||
user: UserProfile, realm_creation: bool = False, demo_organization_creator: bool = False
|
||||
) -> None:
|
||||
# Imported here to avoid import cycles.
|
||||
from zerver.context_processors import common_context
|
||||
|
||||
@@ -860,7 +873,7 @@ def enqueue_welcome_emails(user: UserProfile, realm_creation: bool = False) -> N
|
||||
|
||||
# Any emails scheduled below should be added to the logic in get_onboarding_email_schedule
|
||||
# to determine how long to delay sending the email based on when the user signed up.
|
||||
onboarding_email_schedule = get_onboarding_email_schedule(user)
|
||||
onboarding_email_schedule = get_onboarding_email_schedule(user, demo_organization_creator)
|
||||
|
||||
if other_account_count == 0:
|
||||
onboarding_zulip_topics_context = common_context(user)
|
||||
@@ -915,7 +928,7 @@ def enqueue_welcome_emails(user: UserProfile, realm_creation: bool = False) -> N
|
||||
)
|
||||
|
||||
# We only send the onboarding_team_to_zulip email to user who created the organization.
|
||||
if realm_creation:
|
||||
if realm_creation or demo_organization_creator:
|
||||
onboarding_team_to_zulip_context = common_context(user)
|
||||
onboarding_team_to_zulip_context.update(
|
||||
unsubscribe_link=unsubscribe_link,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from datetime import timedelta
|
||||
from email.headerregistry import Address
|
||||
|
||||
import orjson
|
||||
import time_machine
|
||||
from django.conf import settings
|
||||
from django.core import mail
|
||||
@@ -20,6 +21,7 @@ from zerver.actions.users import do_deactivate_user
|
||||
from zerver.lib.test_classes import ZulipTestCase
|
||||
from zerver.models import EmailChangeStatus, UserProfile
|
||||
from zerver.models.realms import get_realm
|
||||
from zerver.models.scheduled_jobs import ScheduledEmail
|
||||
from zerver.models.users import get_user, get_user_by_delivery_email, get_user_profile_by_id
|
||||
|
||||
|
||||
@@ -403,3 +405,20 @@ class EmailChangeTestCase(ZulipTestCase):
|
||||
|
||||
user_profile = get_user_profile_by_id(desdemona.id)
|
||||
self.assertEqual(user_profile.delivery_email, "desdemona-new@zulip.com")
|
||||
|
||||
scheduled_emails = ScheduledEmail.objects.filter(users=user_profile).order_by(
|
||||
"scheduled_timestamp"
|
||||
)
|
||||
self.assert_length(scheduled_emails, 3)
|
||||
self.assertEqual(
|
||||
orjson.loads(scheduled_emails[0].data)["template_prefix"],
|
||||
"zerver/emails/onboarding_zulip_topics",
|
||||
)
|
||||
self.assertEqual(
|
||||
orjson.loads(scheduled_emails[1].data)["template_prefix"],
|
||||
"zerver/emails/onboarding_zulip_guide",
|
||||
)
|
||||
self.assertEqual(
|
||||
orjson.loads(scheduled_emails[2].data)["template_prefix"],
|
||||
"zerver/emails/onboarding_team_to_zulip",
|
||||
)
|
||||
|
||||
@@ -34,6 +34,7 @@ from zerver.actions.user_settings import (
|
||||
from zerver.actions.users import generate_password_reset_url
|
||||
from zerver.decorator import human_users_only
|
||||
from zerver.lib.avatar import avatar_url
|
||||
from zerver.lib.email_notifications import enqueue_welcome_emails
|
||||
from zerver.lib.email_validation import (
|
||||
get_realm_email_validator,
|
||||
validate_email_is_valid,
|
||||
@@ -135,6 +136,9 @@ def confirm_email_change(request: HttpRequest, confirmation_key: str) -> HttpRes
|
||||
user_profile.realm.demo_organization_scheduled_deletion_date is not None
|
||||
and user_profile.is_realm_owner
|
||||
)
|
||||
# Schedule onboarding emails for demo organization owner now that we have an
|
||||
# email address for their account.
|
||||
enqueue_welcome_emails(user_profile, demo_organization_creator=True)
|
||||
# Because demo organizations are created without setting an email and password
|
||||
# we want to redirect to setting a password after configuring and confirming
|
||||
# an email for the owner's account.
|
||||
|
||||
Reference in New Issue
Block a user