def enqueue_welcome_emails(user: UserProfile) -> None: from zerver.context_processors import common_context if settings.WELCOME_EMAIL_SENDER is not None: # line break to avoid triggering lint rule from_name = settings.WELCOME_EMAIL_SENDER['name'] from_address = settings.WELCOME_EMAIL_SENDER['email'] else: from_name = None from_address = FromAddress.SUPPORT unsubscribe_link = one_click_unsubscribe_link(user, "welcome") context = common_context(user) context.update({ 'unsubscribe_link': unsubscribe_link, 'keyboard_shortcuts_link': user.realm.uri + '/help/keyboard-shortcuts', }) if user.is_realm_admin: context['user_role_group'] = _('admins') context['getting_started_link'] = (user.realm.uri + '/help/getting-your-organization-started-with-zulip') else: context['user_role_group'] = _('members') context['getting_started_link'] = user.realm.uri + '/help/getting-started-with-zulip' send_future_email( "zerver/emails/followup_day1", user.realm, to_user_id=user.id, from_name=from_name, from_address=from_address, context=context) send_future_email( "zerver/emails/followup_day2", user.realm, to_user_id=user.id, from_name=from_name, from_address=from_address, context=context, delay=followup_day2_email_delay(user))
def enqueue_welcome_emails(user): # type: (UserProfile) -> None from zerver.context_processors import common_context if settings.WELCOME_EMAIL_SENDER is not None: # line break to avoid triggering lint rule from_name = settings.WELCOME_EMAIL_SENDER['name'] from_address = settings.WELCOME_EMAIL_SENDER['email'] else: from_name = None from_address = FromAddress.SUPPORT unsubscribe_link = one_click_unsubscribe_link(user, "welcome") context = common_context(user) context.update({ 'unsubscribe_link': unsubscribe_link, 'organization_setup_advice_link': user.realm.uri + '%s/help/getting-your-organization-started-with-zulip', 'is_realm_admin': user.is_realm_admin, }) send_future_email("zerver/emails/followup_day1", to_user_id=user.id, from_name=from_name, from_address=from_address, context=context) send_future_email("zerver/emails/followup_day2", to_user_id=user.id, from_name=from_name, from_address=from_address, context=context, delay=datetime.timedelta(days=1))
def enqueue_welcome_emails(email, name, realm): # type: (Text, Text, Realm) -> None from zerver.context_processors import common_context if settings.WELCOME_EMAIL_SENDER is not None: # line break to avoid triggering lint rule from_name = settings.WELCOME_EMAIL_SENDER['name'] from_address = settings.WELCOME_EMAIL_SENDER['email'] else: from_name = None from_address = FromAddress.SUPPORT user_profile = get_user(email, realm) unsubscribe_link = one_click_unsubscribe_link(user_profile, "welcome") context = common_context(user_profile) context.update({'unsubscribe_link': unsubscribe_link}) send_future_email("zerver/emails/followup_day1", '%s <%s>' % (name, email), from_name=from_name, from_address=from_address, context=context, delay=datetime.timedelta(hours=1)) send_future_email("zerver/emails/followup_day2", '%s <%s>' % (name, email), from_name=from_name, from_address=from_address, context=context, delay=datetime.timedelta(days=1))
def test_clear_scheduled_jobs(self) -> None: user = self.example_user('hamlet') send_future_email('zerver/emails/followup_day1', user.realm, to_user_id=user.id, delay=datetime.timedelta(hours=1)) self.assertEqual(ScheduledEmail.objects.count(), 1) do_deactivate_user(user) self.assertEqual(ScheduledEmail.objects.count(), 0)
def test_do_deactivate_realm_clears_scheduled_jobs(self): # type: () -> None user = self.example_user('hamlet') send_future_email('zerver/emails/followup_day1', to_user_id=user.id, delay=datetime.timedelta(hours=1)) self.assertEqual(ScheduledEmail.objects.count(), 1) do_deactivate_realm(user.realm) self.assertEqual(ScheduledEmail.objects.count(), 0)
def handle_digest_email( user_profile_id: int, cutoff: float, render_to_web: bool = False) -> Union[None, Dict[str, Any]]: user_profile = get_user_profile_by_id(user_profile_id) # Convert from epoch seconds to a datetime object. cutoff_date = datetime.datetime.fromtimestamp(int(cutoff), tz=pytz.utc) context = common_context(user_profile) # Start building email template data. context.update({ 'unsubscribe_link': one_click_unsubscribe_link(user_profile, "digest") }) home_view_streams = Subscription.objects.filter( user_profile=user_profile, recipient__type=Recipient.STREAM, active=True, is_muted=False).values_list('recipient__type_id', flat=True) if not user_profile.long_term_idle: stream_ids = home_view_streams else: stream_ids = exclude_subscription_modified_streams( user_profile, home_view_streams, cutoff_date) # Fetch list of all messages sent after cutoff_date where the user is subscribed messages = Message.objects.filter(recipient__type=Recipient.STREAM, recipient__type_id__in=stream_ids, pub_date__gt=cutoff_date).select_related( 'recipient', 'sender', 'sending_client') # Gather hot conversations. context["hot_conversations"] = gather_hot_conversations( user_profile, messages) # Gather new streams. new_streams_count, new_streams = gather_new_streams( user_profile, cutoff_date) context["new_streams"] = new_streams context["new_streams_count"] = new_streams_count if render_to_web: return context # We don't want to send emails containing almost no information. if enough_traffic(context["hot_conversations"], new_streams_count): logger.info("Sending digest email for %s" % (user_profile.email, )) # Send now, as a ScheduledEmail send_future_email('zerver/emails/digest', user_profile.realm, to_user_ids=[user_profile.id], from_name="Zulip Digest", from_address=FromAddress.NOREPLY, context=context) return None
def consume(self, data: Mapping[str, Any]) -> None: if "email" in data: # When upgrading from a version up through 1.7.1, there may be # existing items in the queue with `email` instead of `prereg_id`. invitee = PreregistrationUser.objects.filter( email__iexact=data["email"].strip()).latest("invited_at") else: invitee = PreregistrationUser.objects.filter( id=data["prereg_id"]).first() if invitee is None: # The invitation could have been revoked return referrer = get_user_profile_by_id(data["referrer_id"]) logger.info("Sending invitation for realm %s to %s" % (referrer.realm.string_id, invitee.email)) do_send_confirmation_email(invitee, referrer) # queue invitation reminder for two days from now. link = create_confirmation_link(invitee, referrer.realm.host, Confirmation.INVITATION) context = common_context(referrer) context.update({ 'activate_url': link, 'referrer_name': referrer.full_name, 'referrer_email': referrer.email, 'referrer_realm_name': referrer.realm.name, }) send_future_email( "zerver/emails/invitation_reminder", referrer.realm, to_emails=[invitee.email], from_address=FromAddress.tokenized_no_reply_address(), context=context, delay=datetime.timedelta(days=2))
def consume(self, data: Mapping[str, Any]) -> None: if "email" in data: # When upgrading from a version up through 1.7.1, there may be # existing items in the queue with `email` instead of `prereg_id`. invitee = PreregistrationUser.objects.filter( email__iexact=data["email"].strip()).latest("invited_at") else: invitee = PreregistrationUser.objects.filter(id=data["prereg_id"]).first() if invitee is None: # The invitation could have been revoked return referrer = get_user_profile_by_id(data["referrer_id"]) logger.info("Sending invitation for realm %s to %s" % (referrer.realm.string_id, invitee.email)) do_send_confirmation_email(invitee, referrer) # queue invitation reminder for two days from now. link = create_confirmation_link(invitee, referrer.realm.host, Confirmation.INVITATION) context = common_context(referrer) context.update({ 'activate_url': link, 'referrer_name': referrer.full_name, 'referrer_email': referrer.email, 'referrer_realm_name': referrer.realm.name, }) send_future_email( "zerver/emails/invitation_reminder", referrer.realm, to_emails=[invitee.email], from_address=FromAddress.tokenized_no_reply_address(), language=referrer.realm.default_language, context=context, delay=datetime.timedelta(days=2))
def test_clear_scheduled_jobs(self) -> None: user = self.example_user('hamlet') send_future_email('zerver/emails/followup_day1', user.realm, to_user_ids=[user.id], delay=datetime.timedelta(hours=1)) self.assertEqual(ScheduledEmail.objects.count(), 1) do_deactivate_user(user) self.assertEqual(ScheduledEmail.objects.count(), 0)
def bulk_handle_digest_email(user_ids: List[int], cutoff: float) -> None: # We go directly to the database to get user objects, # since inactive users are likely to not be in the cache. users = (UserProfile.objects.filter( id__in=user_ids, is_active=True, realm__deactivated=False).order_by("id").select_related("realm")) context_map = bulk_get_digest_context(users, cutoff) digest_users = [] for user in users: context = context_map[user.id] # We don't want to send emails containing almost no information. if enough_traffic(context["hot_conversations"], context["new_streams_count"]): digest_users.append(user) logger.info("Sending digest email for user %s", user.id) # Send now, as a ScheduledEmail send_future_email( "zerver/emails/digest", user.realm, to_user_ids=[user.id], from_name="Zulip Digest", from_address=FromAddress.no_reply_placeholder, context=context, ) bulk_write_realm_audit_logs(digest_users)
def enqueue_welcome_emails(user: UserProfile, realm_creation: bool = False) -> None: from zerver.context_processors import common_context if settings.WELCOME_EMAIL_SENDER is not None: # line break to avoid triggering lint rule from_name = settings.WELCOME_EMAIL_SENDER['name'] from_address = settings.WELCOME_EMAIL_SENDER['email'] else: from_name = None from_address = FromAddress.support_placeholder other_account_count = UserProfile.objects.filter( delivery_email__iexact=user.delivery_email).exclude( id=user.id).count() unsubscribe_link = one_click_unsubscribe_link(user, "welcome") context = common_context(user) context.update( unsubscribe_link=unsubscribe_link, keyboard_shortcuts_link=user.realm.uri + '/help/keyboard-shortcuts', realm_name=user.realm.name, realm_creation=realm_creation, email=user.delivery_email, is_realm_admin=user.role == UserProfile.ROLE_REALM_ADMINISTRATOR, ) if user.is_realm_admin: context['getting_started_link'] = ( user.realm.uri + '/help/getting-your-organization-started-with-zulip') else: context['getting_started_link'] = "https://zulip.com" # Imported here to avoid import cycles. from zproject.backends import ZulipLDAPAuthBackend, email_belongs_to_ldap if email_belongs_to_ldap(user.realm, user.delivery_email): context["ldap"] = True for backend in get_backends(): # If the user is doing authentication via LDAP, Note that # we exclude ZulipLDAPUserPopulator here, since that # isn't used for authentication. if isinstance(backend, ZulipLDAPAuthBackend): context["ldap_username"] = backend.django_to_ldap_username( user.delivery_email) break send_future_email("zerver/emails/followup_day1", user.realm, to_user_ids=[user.id], from_name=from_name, from_address=from_address, context=context) if other_account_count == 0: send_future_email("zerver/emails/followup_day2", user.realm, to_user_ids=[user.id], from_name=from_name, from_address=from_address, context=context, delay=followup_day2_email_delay(user))
def consume(self, data: Mapping[str, Any]) -> None: invitee = filter_to_valid_prereg_users( PreregistrationUser.objects.filter(id=data["prereg_id"]) ).first() if invitee is None: # The invitation could have been revoked return referrer = get_user_profile_by_id(data["referrer_id"]) logger.info( "Sending invitation for realm %s to %s", referrer.realm.string_id, invitee.email ) activate_url = do_send_confirmation_email(invitee, referrer) # queue invitation reminder if settings.INVITATION_LINK_VALIDITY_DAYS >= 4: context = common_context(referrer) context.update( activate_url=activate_url, referrer_name=referrer.full_name, referrer_email=referrer.delivery_email, referrer_realm_name=referrer.realm.name, ) send_future_email( "zerver/emails/invitation_reminder", referrer.realm, to_emails=[invitee.email], from_address=FromAddress.tokenized_no_reply_placeholder, language=referrer.realm.default_language, context=context, delay=datetime.timedelta(days=settings.INVITATION_LINK_VALIDITY_DAYS - 2), )
def enqueue_welcome_emails(user: UserProfile) -> None: from zerver.context_processors import common_context if settings.WELCOME_EMAIL_SENDER is not None: # line break to avoid triggering lint rule from_name = settings.WELCOME_EMAIL_SENDER['name'] from_address = settings.WELCOME_EMAIL_SENDER['email'] else: from_name = None from_address = FromAddress.SUPPORT unsubscribe_link = one_click_unsubscribe_link(user, "welcome") context = common_context(user) context.update({ 'unsubscribe_link': unsubscribe_link, 'organization_setup_advice_link': user.realm.uri + '/help/getting-your-organization-started-with-zulip', 'getting_started_with_zulip_link': user.realm.uri + '/help/getting-started-with-zulip', 'keyboard_shortcuts_link': user.realm.uri + '/help/keyboard-shortcuts', 'is_realm_admin': user.is_realm_admin, }) send_future_email( "zerver/emails/followup_day1", user.realm, to_user_id=user.id, from_name=from_name, from_address=from_address, context=context) send_future_email( "zerver/emails/followup_day2", user.realm, to_user_id=user.id, from_name=from_name, from_address=from_address, context=context, delay=followup_day2_email_delay(user))
def enqueue_welcome_emails(email, name): # type: (Text, Text) -> None from zerver.context_processors import common_context if settings.WELCOME_EMAIL_SENDER is not None: # line break to avoid triggering lint rule from_email = '%(name)s <%(email)s>' % \ settings.WELCOME_EMAIL_SENDER else: from_email = settings.ZULIP_ADMINISTRATOR user_profile = get_user_profile_by_email(email) unsubscribe_link = one_click_unsubscribe_link(user_profile, "welcome") context = common_context(user_profile) context.update({ 'verbose_support_offers': settings.VERBOSE_SUPPORT_OFFERS, 'unsubscribe_link': unsubscribe_link }) send_future_email("zerver/emails/followup_day1", '%s <%s>' % (name, email), from_email=from_email, context=context, delay=datetime.timedelta(hours=1)) send_future_email("zerver/emails/followup_day2", '%s <%s>' % (name, email), from_email=from_email, context=context, delay=datetime.timedelta(days=1))
def consume(self, data: Mapping[str, Any]) -> None: if "email" in data: # When upgrading from a version up through 1.7.1, there may be # existing items in the queue with `email` instead of `prereg_id`. invitee = PreregistrationUser.objects.filter( email__iexact=data["email"].strip()).latest("invited_at") else: invitee = PreregistrationUser.objects.filter(id=data["prereg_id"]).first() if invitee is None: # The invitation could have been revoked return referrer = get_user_profile_by_id(data["referrer_id"]) logger.info("Sending invitation for realm %s to %s", referrer.realm.string_id, invitee.email) activate_url = do_send_confirmation_email(invitee, referrer) # queue invitation reminder if settings.INVITATION_LINK_VALIDITY_DAYS >= 4: context = common_context(referrer) context.update({ 'activate_url': activate_url, 'referrer_name': referrer.full_name, 'referrer_email': referrer.delivery_email, 'referrer_realm_name': referrer.realm.name, }) send_future_email( "zerver/emails/invitation_reminder", referrer.realm, to_emails=[invitee.email], from_address=FromAddress.tokenized_no_reply_placeholder, language=referrer.realm.default_language, context=context, delay=datetime.timedelta(days=settings.INVITATION_LINK_VALIDITY_DAYS - 2))
def test_send_future_email_with_multiple_recipients(self) -> None: hamlet = self.example_user('hamlet') iago = self.example_user('iago') send_future_email('zerver/emails/followup_day1', iago.realm, to_user_ids=[hamlet.id, iago.id], delay=datetime.timedelta(hours=1)) self.assertEqual(ScheduledEmail.objects.filter(users__in=[hamlet, iago]).distinct().count(), 1) email = ScheduledEmail.objects.all().first() self.assertEqual(email.users.count(), 2)
def test_clear_scheduled_emails_with_multiple_user_ids(self) -> None: hamlet = self.example_user('hamlet') iago = self.example_user('iago') send_future_email('zerver/emails/followup_day1', iago.realm, to_user_ids=[hamlet.id, iago.id], delay=datetime.timedelta(hours=1)) self.assertEqual(ScheduledEmail.objects.count(), 1) clear_scheduled_emails([hamlet.id, iago.id]) self.assertEqual(ScheduledEmail.objects.count(), 0)
def enqueue_welcome_emails(user: UserProfile, realm_creation: bool = False) -> None: from zerver.context_processors import common_context if settings.WELCOME_EMAIL_SENDER is not None: # line break to avoid triggering lint rule from_name = settings.WELCOME_EMAIL_SENDER['name'] from_address = settings.WELCOME_EMAIL_SENDER['email'] else: from_name = None from_address = FromAddress.SUPPORT other_account_count = UserProfile.objects.filter( delivery_email__iexact=user.delivery_email).exclude( id=user.id).count() unsubscribe_link = one_click_unsubscribe_link(user, "welcome") context = common_context(user) context.update({ 'unsubscribe_link': unsubscribe_link, 'keyboard_shortcuts_link': user.realm.uri + '/help/keyboard-shortcuts', 'realm_name': user.realm.name, 'realm_creation': realm_creation, 'email': user.email, 'is_realm_admin': user.is_realm_admin, }) if user.is_realm_admin: context['getting_started_link'] = ( user.realm.uri + '/help/getting-your-organization-started-with-zulip') else: context['getting_started_link'] = "https://zulipchat.com" from zproject.backends import email_belongs_to_ldap if email_belongs_to_ldap(user.realm, user.email): context["ldap"] = True if settings.LDAP_APPEND_DOMAIN: for backend in get_backends(): if isinstance(backend, LDAPBackend): context["ldap_username"] = backend.django_to_ldap_username( user.email) elif not settings.LDAP_EMAIL_ATTR: context["ldap_username"] = user.email send_future_email("zerver/emails/followup_day1", user.realm, to_user_ids=[user.id], from_name=from_name, from_address=from_address, context=context) if other_account_count == 0: send_future_email("zerver/emails/followup_day2", user.realm, to_user_ids=[user.id], from_name=from_name, from_address=from_address, context=context, delay=followup_day2_email_delay(user))
def test_do_deactivate_realm_clears_scheduled_jobs(self) -> None: user = self.example_user("hamlet") send_future_email( "zerver/emails/followup_day1", user.realm, to_user_ids=[user.id], delay=datetime.timedelta(hours=1), ) self.assertEqual(ScheduledEmail.objects.count(), 1) do_deactivate_realm(user.realm, acting_user=None) self.assertEqual(ScheduledEmail.objects.count(), 0)
def consume(self, data: Mapping[str, Any]) -> None: if "invite_expires_in_days" in data: invite_expires_in_minutes = data["invite_expires_in_days"] * 24 * 60 elif "invite_expires_in_minutes" in data: invite_expires_in_minutes = data["invite_expires_in_minutes"] invitee = filter_to_valid_prereg_users( PreregistrationUser.objects.filter(id=data["prereg_id"]), invite_expires_in_minutes).first() if invitee is None: # The invitation could have been revoked return referrer = get_user_profile_by_id(data["referrer_id"]) logger.info("Sending invitation for realm %s to %s", referrer.realm.string_id, invitee.email) if "email_language" in data: email_language = data["email_language"] else: email_language = referrer.realm.default_language activate_url = do_send_confirmation_email(invitee, referrer, email_language, invite_expires_in_minutes) if invite_expires_in_minutes is None: # We do not queue reminder email for never expiring # invitations. This is probably a low importance bug; it # would likely be more natural to send a reminder after 7 # days. return # queue invitation reminder if invite_expires_in_minutes >= 4 * 24 * 60: context = common_context(referrer) context.update( activate_url=activate_url, referrer_name=referrer.full_name, referrer_email=referrer.delivery_email, referrer_realm_name=referrer.realm.name, ) send_future_email( "zerver/emails/invitation_reminder", referrer.realm, to_emails=[invitee.email], from_address=FromAddress.tokenized_no_reply_placeholder, language=email_language, context=context, delay=datetime.timedelta(minutes=invite_expires_in_minutes - (2 * 24 * 60)), )
def test_deliver_email(self) -> None: iago = self.example_user('iago') hamlet = self.example_user('hamlet') send_future_email('zerver/emails/followup_day1', iago.realm, to_user_ids=[hamlet.id, iago.id], delay=datetime.timedelta(hours=1)) self.assertEqual(ScheduledEmail.objects.count(), 1) email = ScheduledEmail.objects.all().first() deliver_email(email) from django.core.mail import outbox self.assertEqual(len(outbox), 1) for message in outbox: self.assertEqual(set([hamlet.delivery_email, iago.delivery_email]), set(message.to)) self.assertEqual(ScheduledEmail.objects.count(), 0)
def enqueue_welcome_emails(user: UserProfile, realm_creation: bool=False) -> None: from zerver.context_processors import common_context if settings.WELCOME_EMAIL_SENDER is not None: # line break to avoid triggering lint rule from_name = settings.WELCOME_EMAIL_SENDER['name'] from_address = settings.WELCOME_EMAIL_SENDER['email'] else: from_name = None from_address = FromAddress.SUPPORT other_account_count = UserProfile.objects.filter( delivery_email__iexact=user.delivery_email).exclude(id=user.id).count() unsubscribe_link = one_click_unsubscribe_link(user, "welcome") context = common_context(user) context.update({ 'unsubscribe_link': unsubscribe_link, 'keyboard_shortcuts_link': user.realm.uri + '/help/keyboard-shortcuts', 'realm_name': user.realm.name, 'realm_creation': realm_creation, 'email': user.email, 'is_realm_admin': user.is_realm_admin, }) if user.is_realm_admin: context['getting_started_link'] = (user.realm.uri + '/help/getting-your-organization-started-with-zulip') else: context['getting_started_link'] = "https://zulipchat.com" from zproject.backends import email_belongs_to_ldap if email_belongs_to_ldap(user.realm, user.email): context["ldap"] = True if settings.LDAP_APPEND_DOMAIN: for backend in get_backends(): if isinstance(backend, LDAPBackend): context["ldap_username"] = backend.django_to_ldap_username(user.email) elif not settings.LDAP_EMAIL_ATTR: context["ldap_username"] = user.email send_future_email( "zerver/emails/followup_day1", user.realm, to_user_ids=[user.id], from_name=from_name, from_address=from_address, context=context) if other_account_count == 0: send_future_email( "zerver/emails/followup_day2", user.realm, to_user_ids=[user.id], from_name=from_name, from_address=from_address, context=context, delay=followup_day2_email_delay(user))
def bulk_handle_digest_email(user_ids: List[int], cutoff: float) -> None: users = [get_user_profile_by_id(user_id) for user_id in user_ids] context_map = bulk_get_digest_context(users, cutoff) for user in users: context = context_map[user.id] # We don't want to send emails containing almost no information. if enough_traffic(context["hot_conversations"], context["new_streams_count"]): logger.info("Sending digest email for user %s", user.id) # Send now, as a ScheduledEmail send_future_email( 'zerver/emails/digest', user.realm, to_user_ids=[user.id], from_name="Zulip Digest", from_address=FromAddress.no_reply_placeholder, context=context, )
def consume(self, data): # type: (Mapping[str, Any]) -> None invitee = get_prereg_user_by_email(data["email"]) referrer = get_user_profile_by_id(data["referrer_id"]) body = data["email_body"] do_send_confirmation_email(invitee, referrer, body) # queue invitation reminder for two days from now. link = create_confirmation_link(invitee, referrer.realm.host, Confirmation.INVITATION) context = common_context(referrer) context.update({ 'activate_url': link, 'referrer_name': referrer.full_name, 'referrer_email': referrer.email, 'referrer_realm_name': referrer.realm.name, }) send_future_email( "zerver/emails/invitation_reminder", to_email=data["email"], from_address=FromAddress.NOREPLY, context=context, delay=datetime.timedelta(days=2))
def consume(self, data): # type: (Mapping[str, Any]) -> None invitee = get_prereg_user_by_email(data["email"]) referrer = get_user_profile_by_id(data["referrer_id"]) body = data["email_body"] do_send_confirmation_email(invitee, referrer, body) # queue invitation reminder for two days from now. link = create_confirmation_link(invitee, referrer.realm.host, Confirmation.INVITATION) context = common_context(referrer) context.update({ 'activate_url': link, 'referrer_name': referrer.full_name, 'referrer_email': referrer.email, 'referrer_realm_name': referrer.realm.name, }) send_future_email("zerver/emails/invitation_reminder", to_email=data["email"], from_address=FromAddress.NOREPLY, context=context, delay=datetime.timedelta(days=2))
def consume(self, data): # type: (Mapping[str, Any]) -> None invitee = get_prereg_user_by_email(data["email"]) referrer = get_user_profile_by_id(data["referrer_id"]) body = data["email_body"] do_send_confirmation_email(invitee, referrer, body) # queue invitation reminder for two days from now. link = Confirmation.objects.get_link_for_object( invitee, host=referrer.realm.host) context = common_context(referrer) context.update({ 'activate_url': link, 'referrer_name': referrer.full_name, 'referrer_email': referrer.email, 'referrer_realm_name': referrer.realm.name, }) send_future_email("zerver/emails/invitation_reminder", data["email"], from_email=settings.ZULIP_ADMINISTRATOR, context=context, delay=datetime.timedelta(days=2))
def consume(self, data): # type: (Mapping[str, Any]) -> None invitee = get_prereg_user_by_email(data["email"]) referrer = get_user_profile_by_id(data["referrer_id"]) body = data["email_body"] do_send_confirmation_email(invitee, referrer, body) # queue invitation reminder for two days from now. link = Confirmation.objects.get_link_for_object(invitee, host=referrer.realm.host) context = common_context(referrer) context.update({ 'activate_url': link, 'referrer_name': referrer.full_name, 'referrer_email': referrer.email, 'referrer_realm_name': referrer.realm.name, }) send_future_email( "zerver/emails/invitation_reminder", data["email"], from_email=settings.ZULIP_ADMINISTRATOR, context=context, delay=datetime.timedelta(days=2))
def enqueue_welcome_emails(email, name): # type: (Text, Text) -> None from zerver.context_processors import common_context if settings.WELCOME_EMAIL_SENDER is not None: # line break to avoid triggering lint rule from_email = '%(name)s <%(email)s>' % \ settings.WELCOME_EMAIL_SENDER else: from_email = settings.ZULIP_ADMINISTRATOR user_profile = get_user_profile_by_email(email) unsubscribe_link = one_click_unsubscribe_link(user_profile, "welcome") context = common_context(user_profile) context.update({ 'unsubscribe_link': unsubscribe_link }) send_future_email( "zerver/emails/followup_day1", '%s <%s>' % (name, email), from_email=from_email, context=context, delay=datetime.timedelta(hours=1)) send_future_email( "zerver/emails/followup_day2", '%s <%s>' % (name, email), from_email=from_email, context=context, delay=datetime.timedelta(days=1))
def enqueue_welcome_emails(user_id): # type: (int) -> None from zerver.context_processors import common_context if settings.WELCOME_EMAIL_SENDER is not None: # line break to avoid triggering lint rule from_name = settings.WELCOME_EMAIL_SENDER['name'] from_address = settings.WELCOME_EMAIL_SENDER['email'] else: from_name = None from_address = FromAddress.SUPPORT user_profile = get_user_profile_by_id(user_id) unsubscribe_link = one_click_unsubscribe_link(user_profile, "welcome") context = common_context(user_profile) context.update({ 'unsubscribe_link': unsubscribe_link }) send_future_email( "zerver/emails/followup_day1", to_user_id=user_id, from_name=from_name, from_address=from_address, context=context, delay=datetime.timedelta(hours=1)) send_future_email( "zerver/emails/followup_day2", to_user_id=user_id, from_name=from_name, from_address=from_address, context=context, delay=datetime.timedelta(days=1))
def handle_digest_email(user_profile_id: int, cutoff: float) -> None: user_profile = get_user_profile_by_id(user_profile_id) # We are disabling digest emails for soft deactivated users for the time. # TODO: Find an elegant way to generate digest emails for these users. if user_profile.long_term_idle: return None # Convert from epoch seconds to a datetime object. cutoff_date = datetime.datetime.fromtimestamp(int(cutoff), tz=pytz.utc) all_messages = UserMessage.objects.filter( user_profile=user_profile, message__pub_date__gt=cutoff_date).order_by("message__pub_date") context = common_context(user_profile) # Start building email template data. context.update({ 'realm_name': user_profile.realm.name, 'name': user_profile.full_name, 'unsubscribe_link': one_click_unsubscribe_link(user_profile, "digest") }) # Gather recent missed PMs, re-using the missed PM email logic. # You can't have an unread message that you sent, but when testing # this causes confusion so filter your messages out. pms = all_messages.filter( ~Q(message__recipient__type=Recipient.STREAM) & ~Q(message__sender=user_profile)) # Show up to 4 missed PMs. pms_limit = 4 context['unread_pms'] = build_message_list( user_profile, [pm.message for pm in pms[:pms_limit]]) context['remaining_unread_pms_count'] = min(0, len(pms) - pms_limit) home_view_recipients = [sub.recipient for sub in Subscription.objects.filter( user_profile=user_profile, active=True, in_home_view=True)] stream_messages = all_messages.filter( message__recipient__type=Recipient.STREAM, message__recipient__in=home_view_recipients) # Gather hot conversations. context["hot_conversations"] = gather_hot_conversations( user_profile, stream_messages) # Gather new streams. new_streams_count, new_streams = gather_new_streams( user_profile, cutoff_date) context["new_streams"] = new_streams context["new_streams_count"] = new_streams_count # Gather users who signed up recently. new_users_count, new_users = gather_new_users( user_profile, cutoff_date) context["new_users"] = new_users # We don't want to send emails containing almost no information. if enough_traffic(context["unread_pms"], context["hot_conversations"], new_streams_count, new_users_count): logger.info("Sending digest email for %s" % (user_profile.email,)) # Send now, as a ScheduledEmail send_future_email('zerver/emails/digest', to_user_id=user_profile.id, from_name="Zulip Digest", from_address=FromAddress.NOREPLY, context=context)
def handle_digest_email(user_profile_id: int, cutoff: float) -> None: user_profile = get_user_profile_by_id(user_profile_id) # We are disabling digest emails for soft deactivated users for the time. # TODO: Find an elegant way to generate digest emails for these users. if user_profile.long_term_idle: return None # Convert from epoch seconds to a datetime object. cutoff_date = datetime.datetime.fromtimestamp(int(cutoff), tz=pytz.utc) all_messages = UserMessage.objects.filter( user_profile=user_profile, message__pub_date__gt=cutoff_date).order_by("message__pub_date") context = common_context(user_profile) # Start building email template data. context.update({ 'realm_name': user_profile.realm.name, 'name': user_profile.full_name, 'unsubscribe_link': one_click_unsubscribe_link(user_profile, "digest") }) # Gather recent missed PMs, re-using the missed PM email logic. # You can't have an unread message that you sent, but when testing # this causes confusion so filter your messages out. pms = all_messages.filter( ~Q(message__recipient__type=Recipient.STREAM) & ~Q(message__sender=user_profile)) # Show up to 4 missed PMs. pms_limit = 4 context['unread_pms'] = build_message_list( user_profile, [pm.message for pm in pms[:pms_limit]]) context['remaining_unread_pms_count'] = min(0, len(pms) - pms_limit) home_view_recipients = [sub.recipient for sub in Subscription.objects.filter( user_profile=user_profile, active=True, in_home_view=True)] stream_messages = all_messages.filter( message__recipient__type=Recipient.STREAM, message__recipient__in=home_view_recipients) # Gather hot conversations. context["hot_conversations"] = gather_hot_conversations( user_profile, stream_messages) # Gather new streams. new_streams_count, new_streams = gather_new_streams( user_profile, cutoff_date) context["new_streams"] = new_streams context["new_streams_count"] = new_streams_count # Gather users who signed up recently. new_users_count, new_users = gather_new_users( user_profile, cutoff_date) context["new_users"] = new_users # We don't want to send emails containing almost no information. if enough_traffic(context["unread_pms"], context["hot_conversations"], new_streams_count, new_users_count): logger.info("Sending digest email for %s" % (user_profile.email,)) # Send now, as a ScheduledEmail send_future_email('zerver/emails/digest', user_profile.realm, to_user_id=user_profile.id, from_name="Zulip Digest", from_address=FromAddress.NOREPLY, context=context)