mirror of https://github.com/zulip/zulip.git
send_custom_email: Only put the unsubscribe footer on marketing emails.
This commit is contained in:
parent
cb42a1b88d
commit
95b0ab31be
|
@ -14,7 +14,7 @@
|
||||||
{% block manage_preferences %}
|
{% block manage_preferences %}
|
||||||
{% if remote_server_email %}
|
{% if remote_server_email %}
|
||||||
<p>You are receiving this email to update you about important changes to Zulip's Terms of Service.</p>
|
<p>You are receiving this email to update you about important changes to Zulip's Terms of Service.</p>
|
||||||
{% else %}
|
{% elif unsubscribe_link %}
|
||||||
<p><a href="{{ realm_uri }}/#settings/notifications">{{ _("Manage email preferences") }}</a> | <a href="{{ unsubscribe_link }}">{{ _("Unsubscribe from marketing emails") }}</a></p>
|
<p><a href="{{ realm_uri }}/#settings/notifications">{{ _("Manage email preferences") }}</a> | <a href="{{ unsubscribe_link }}">{{ _("Unsubscribe from marketing emails") }}</a></p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -27,7 +27,7 @@ from django.utils.timezone import now as timezone_now
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
from django.utils.translation import override as override_language
|
from django.utils.translation import override as override_language
|
||||||
|
|
||||||
from confirmation.models import generate_key, one_click_unsubscribe_link
|
from confirmation.models import generate_key
|
||||||
from zerver.lib.logging_util import log_to_file
|
from zerver.lib.logging_util import log_to_file
|
||||||
from zerver.models import EMAIL_TYPES, Realm, ScheduledEmail, UserProfile, get_user_profile_by_id
|
from zerver.models import EMAIL_TYPES, Realm, ScheduledEmail, UserProfile, get_user_profile_by_id
|
||||||
from zproject.email_backends import EmailLogBackEnd, get_forward_address
|
from zproject.email_backends import EmailLogBackEnd, get_forward_address
|
||||||
|
@ -565,7 +565,6 @@ def send_custom_email(
|
||||||
context: Dict[str, Union[List[str], str]] = {
|
context: Dict[str, Union[List[str], str]] = {
|
||||||
"realm_uri": user_profile.realm.uri,
|
"realm_uri": user_profile.realm.uri,
|
||||||
"realm_name": user_profile.realm.name,
|
"realm_name": user_profile.realm.name,
|
||||||
"unsubscribe_link": one_click_unsubscribe_link(user_profile, "marketing"),
|
|
||||||
}
|
}
|
||||||
if add_context is not None:
|
if add_context is not None:
|
||||||
add_context(context, user_profile)
|
add_context(context, user_profile)
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from typing import Any, List
|
from typing import Any, Callable, Dict, List, Optional, Union
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db.models import Q, QuerySet
|
from django.db.models import Q, QuerySet
|
||||||
|
|
||||||
|
from confirmation.models import one_click_unsubscribe_link
|
||||||
from zerver.lib.management import ZulipBaseCommand
|
from zerver.lib.management import ZulipBaseCommand
|
||||||
from zerver.lib.send_email import send_custom_email
|
from zerver.lib.send_email import send_custom_email
|
||||||
from zerver.models import Realm, UserProfile
|
from zerver.models import Realm, UserProfile
|
||||||
|
@ -79,6 +80,9 @@ class Command(ZulipBaseCommand):
|
||||||
def handle(self, *args: Any, **options: str) -> None:
|
def handle(self, *args: Any, **options: str) -> None:
|
||||||
target_emails: List[str] = []
|
target_emails: List[str] = []
|
||||||
users: QuerySet[UserProfile] = UserProfile.objects.none()
|
users: QuerySet[UserProfile] = UserProfile.objects.none()
|
||||||
|
add_context: Optional[
|
||||||
|
Callable[[Dict[str, Union[List[str], str]], UserProfile], None]
|
||||||
|
] = None
|
||||||
|
|
||||||
if options["entire_server"]:
|
if options["entire_server"]:
|
||||||
users = UserProfile.objects.filter(
|
users = UserProfile.objects.filter(
|
||||||
|
@ -95,6 +99,13 @@ class Command(ZulipBaseCommand):
|
||||||
enable_marketing_emails=True,
|
enable_marketing_emails=True,
|
||||||
long_term_idle=False,
|
long_term_idle=False,
|
||||||
).distinct("delivery_email")
|
).distinct("delivery_email")
|
||||||
|
|
||||||
|
def add_marketing_unsubscribe(
|
||||||
|
context: Dict[str, Union[List[str], str]], user: UserProfile
|
||||||
|
) -> None:
|
||||||
|
context["unsubscribe_link"] = one_click_unsubscribe_link(user, "marketing")
|
||||||
|
|
||||||
|
add_context = add_marketing_unsubscribe
|
||||||
elif options["remote_servers"]:
|
elif options["remote_servers"]:
|
||||||
from zilencer.models import RemoteZulipServer
|
from zilencer.models import RemoteZulipServer
|
||||||
|
|
||||||
|
@ -129,7 +140,9 @@ class Command(ZulipBaseCommand):
|
||||||
users = users.exclude(
|
users = users.exclude(
|
||||||
Q(tos_version=None) | Q(tos_version=UserProfile.TOS_VERSION_BEFORE_FIRST_LOGIN)
|
Q(tos_version=None) | Q(tos_version=UserProfile.TOS_VERSION_BEFORE_FIRST_LOGIN)
|
||||||
)
|
)
|
||||||
send_custom_email(users, target_emails=target_emails, options=options)
|
send_custom_email(
|
||||||
|
users, target_emails=target_emails, options=options, add_context=add_context
|
||||||
|
)
|
||||||
|
|
||||||
if options["dry_run"]:
|
if options["dry_run"]:
|
||||||
print("Would send the above email to:")
|
print("Would send the above email to:")
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
From: TestFrom
|
||||||
|
Subject: Test subject
|
||||||
|
|
||||||
|
Test body with {{ custom }} value.
|
|
@ -1,5 +1,6 @@
|
||||||
import tempfile
|
import tempfile
|
||||||
from datetime import datetime, timedelta, timezone
|
from datetime import datetime, timedelta, timezone
|
||||||
|
from typing import Dict, List, Union
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
import ldap
|
import ldap
|
||||||
|
@ -105,6 +106,48 @@ class TestCustomEmails(ZulipTestCase):
|
||||||
self.assertFalse(msg.reply_to)
|
self.assertFalse(msg.reply_to)
|
||||||
self.assertEqual("Test body", msg.body)
|
self.assertEqual("Test body", msg.body)
|
||||||
|
|
||||||
|
def test_send_custom_email_context(self) -> None:
|
||||||
|
hamlet = self.example_user("hamlet")
|
||||||
|
markdown_template_path = (
|
||||||
|
"zerver/tests/fixtures/email/custom_emails/email_base_headers_test.md"
|
||||||
|
)
|
||||||
|
send_custom_email(
|
||||||
|
UserProfile.objects.filter(id=hamlet.id),
|
||||||
|
options={
|
||||||
|
"markdown_template_path": markdown_template_path,
|
||||||
|
"dry_run": False,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
self.assert_length(mail.outbox, 1)
|
||||||
|
msg = mail.outbox[0]
|
||||||
|
|
||||||
|
# We default to not including an unsubscribe link in the headers
|
||||||
|
self.assertEqual(msg.extra_headers.get("X-Auto-Response-Suppress"), "All")
|
||||||
|
self.assertIsNone(msg.extra_headers.get("List-Unsubscribe"))
|
||||||
|
|
||||||
|
mail.outbox = []
|
||||||
|
markdown_template_path = (
|
||||||
|
"zerver/tests/fixtures/email/custom_emails/email_base_headers_custom_test.md"
|
||||||
|
)
|
||||||
|
|
||||||
|
def add_context(context: Dict[str, Union[List[str], str]], user: UserProfile) -> None:
|
||||||
|
context["unsubscribe_link"] = "some@email"
|
||||||
|
context["custom"] = str(user.id)
|
||||||
|
|
||||||
|
send_custom_email(
|
||||||
|
UserProfile.objects.filter(id=hamlet.id),
|
||||||
|
options={
|
||||||
|
"markdown_template_path": markdown_template_path,
|
||||||
|
"dry_run": False,
|
||||||
|
},
|
||||||
|
add_context=add_context,
|
||||||
|
)
|
||||||
|
self.assert_length(mail.outbox, 1)
|
||||||
|
msg = mail.outbox[0]
|
||||||
|
self.assertEqual(msg.extra_headers.get("X-Auto-Response-Suppress"), "All")
|
||||||
|
self.assertEqual(msg.extra_headers.get("List-Unsubscribe"), "<some@email>")
|
||||||
|
self.assertIn(f"Test body with {hamlet.id} value", msg.body)
|
||||||
|
|
||||||
def test_send_custom_email_no_argument(self) -> None:
|
def test_send_custom_email_no_argument(self) -> None:
|
||||||
hamlet = self.example_user("hamlet")
|
hamlet = self.example_user("hamlet")
|
||||||
from_name = "from_name_test"
|
from_name = "from_name_test"
|
||||||
|
|
Loading…
Reference in New Issue