Handle on-click unsubcribe
This commit is contained in:
parent
88d63bd931
commit
da6441b4b8
|
@ -52,6 +52,7 @@ from app.config import (
|
||||||
URL,
|
URL,
|
||||||
ALIAS_DOMAINS,
|
ALIAS_DOMAINS,
|
||||||
POSTFIX_SUBMISSION_TLS,
|
POSTFIX_SUBMISSION_TLS,
|
||||||
|
UNSUBSCRIBER,
|
||||||
)
|
)
|
||||||
from app.email_utils import (
|
from app.email_utils import (
|
||||||
send_email,
|
send_email,
|
||||||
|
@ -459,11 +460,15 @@ def handle_forward(envelope, smtp: SMTP, msg: Message, rcpt_to: str) -> (bool, s
|
||||||
add_or_replace_header(msg, "To", to_header.strip())
|
add_or_replace_header(msg, "To", to_header.strip())
|
||||||
|
|
||||||
# add List-Unsubscribe header
|
# add List-Unsubscribe header
|
||||||
unsubscribe_link = f"{URL}/dashboard/unsubscribe/{alias.id}"
|
if UNSUBSCRIBER:
|
||||||
add_or_replace_header(msg, "List-Unsubscribe", f"<{unsubscribe_link}>")
|
unsubscribe_link = f"mailto:{UNSUBSCRIBER}?subject={alias.id}="
|
||||||
add_or_replace_header(
|
add_or_replace_header(msg, "List-Unsubscribe", f"<{unsubscribe_link}>")
|
||||||
msg, "List-Unsubscribe-Post", "List-Unsubscribe=One-Click"
|
else:
|
||||||
)
|
unsubscribe_link = f"{URL}/dashboard/unsubscribe/{alias.id}"
|
||||||
|
add_or_replace_header(msg, "List-Unsubscribe", f"<{unsubscribe_link}>")
|
||||||
|
add_or_replace_header(
|
||||||
|
msg, "List-Unsubscribe-Post", "List-Unsubscribe=One-Click"
|
||||||
|
)
|
||||||
|
|
||||||
add_dkim_signature(msg, EMAIL_DOMAIN)
|
add_dkim_signature(msg, EMAIL_DOMAIN)
|
||||||
|
|
||||||
|
@ -743,6 +748,54 @@ def handle_bounce(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def handle_unsubscribe(envelope):
|
||||||
|
message_data = envelope.content.decode("utf8", errors="replace")
|
||||||
|
msg = Parser(policy=SMTPUTF8).parsestr(message_data)
|
||||||
|
|
||||||
|
# format: alias_id:
|
||||||
|
subject = msg["Subject"]
|
||||||
|
try:
|
||||||
|
alias_id = int(subject[:-1])
|
||||||
|
alias = Alias.get(alias_id)
|
||||||
|
except Exception:
|
||||||
|
LOG.warning("Cannot parse alias from subject %s", msg["Subject"])
|
||||||
|
return "550 SL ignored"
|
||||||
|
|
||||||
|
if not alias:
|
||||||
|
LOG.warning("No such alias %s", alias_id)
|
||||||
|
return "550 SL ignored"
|
||||||
|
|
||||||
|
# This sender cannot unsubscribe
|
||||||
|
if alias.mailbox_email() != envelope.mail_from:
|
||||||
|
LOG.d("%s cannot disable alias %s", envelope.mail_from, alias)
|
||||||
|
return "550 SL ignored"
|
||||||
|
|
||||||
|
# Sender is owner of this alias
|
||||||
|
alias.enabled = False
|
||||||
|
db.session.commit()
|
||||||
|
user = alias.user
|
||||||
|
|
||||||
|
enable_alias_url = URL + f"/dashboard/?highlight_alias_id={alias.id}"
|
||||||
|
send_email(
|
||||||
|
envelope.mail_from,
|
||||||
|
f"Alias {alias.email} has been disabled successfully",
|
||||||
|
render(
|
||||||
|
"transactional/unsubscribe-disable-alias.txt",
|
||||||
|
user=user,
|
||||||
|
alias=alias.email,
|
||||||
|
enable_alias_url=enable_alias_url,
|
||||||
|
),
|
||||||
|
render(
|
||||||
|
"transactional/unsubscribe-disable-alias.html",
|
||||||
|
user=user,
|
||||||
|
alias=alias.email,
|
||||||
|
enable_alias_url=enable_alias_url,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
return "250 Unsubscribe request accepted"
|
||||||
|
|
||||||
|
|
||||||
class MailHandler:
|
class MailHandler:
|
||||||
async def handle_DATA(self, server, session, envelope):
|
async def handle_DATA(self, server, session, envelope):
|
||||||
LOG.debug(
|
LOG.debug(
|
||||||
|
@ -757,6 +810,14 @@ class MailHandler:
|
||||||
else:
|
else:
|
||||||
smtp = SMTP(POSTFIX_SERVER, 25)
|
smtp = SMTP(POSTFIX_SERVER, 25)
|
||||||
|
|
||||||
|
# unsubscribe request
|
||||||
|
if UNSUBSCRIBER and envelope.rcpt_tos == [UNSUBSCRIBER]:
|
||||||
|
LOG.d("Handle unsubscribe request from %s", envelope.mail_from)
|
||||||
|
app = new_app()
|
||||||
|
|
||||||
|
with app.app_context():
|
||||||
|
return handle_unsubscribe(envelope)
|
||||||
|
|
||||||
# result of all deliveries
|
# result of all deliveries
|
||||||
# each element is a couple of whether the delivery is successful and the smtp status
|
# each element is a couple of whether the delivery is successful and the smtp status
|
||||||
res: [(bool, str)] = []
|
res: [(bool, str)] = []
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{{ render_text("Hi " + user.name) }}
|
||||||
|
{{ render_text("Your alias <b>"+ alias +"</b> has been disabled successfully.") }}
|
||||||
|
{{ render_text("If this is a mistake, you can re-enable the alias on the dashboard.") }}
|
||||||
|
{{ render_button("Enable Alias", enable_alias_url) }}
|
||||||
|
{{ render_text('Thanks, <br />SimpleLogin Team.') }}
|
||||||
|
{{ raw_url(enable_alias_url) }}
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
Hi {{user.name}}
|
||||||
|
|
||||||
|
Your alias {{alias}} has been disabled successfully.
|
||||||
|
|
||||||
|
If this is a mistake, you can re-enable the alias on the dashboard via
|
||||||
|
|
||||||
|
{{ enable_alias_url }}
|
||||||
|
|
||||||
|
Please let us know if you have any question.
|
||||||
|
|
||||||
|
Best,
|
||||||
|
SimpleLogin team.
|
Loading…
Reference in New Issue