mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	Add a one-click unsubscribe link to missed message e-mails.
(imported from commit 719eb61c9b7722eb1b0996b4d5f2f8f5929ad701)
This commit is contained in:
		@@ -28,6 +28,10 @@ Please do not reply to this automated message. To respond to the missed messages
 | 
			
		||||
Cheers,
 | 
			
		||||
The Zulip Team
 | 
			
		||||
 | 
			
		||||
Note: click here to open your Zulip Settings page and disable future email notifications:
 | 
			
		||||
Manage email preferences:
 | 
			
		||||
 | 
			
		||||
https://{{ external_host }}/#settings
 | 
			
		||||
 | 
			
		||||
Unsubscribe from missed message emails:
 | 
			
		||||
 | 
			
		||||
{{ unsubscribe_link }}
 | 
			
		||||
 
 | 
			
		||||
@@ -37,4 +37,4 @@ While you were away you received {{ message_count }} new message{{ message_count
 | 
			
		||||
<br>
 | 
			
		||||
The Zulip Team</p>
 | 
			
		||||
 | 
			
		||||
<p>Note: click <a href="https://{{ external_host }}/#settings">here</a> to open your Zulip Settings page and disable future email notifications</p>
 | 
			
		||||
<p><a href="https://{{ external_host }}/#settings">Manage email preferences</a> | <a href="{{ unsubscribe_link }}">Unsubscribe from missed message emails</a></p>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								templates/zerver/unsubscribe_link_error.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								templates/zerver/unsubscribe_link_error.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
{% extends "zerver/portico.html" %}
 | 
			
		||||
 | 
			
		||||
{% block portico_content %}
 | 
			
		||||
 | 
			
		||||
<h1>Unknown email unsubscribe request</h1>
 | 
			
		||||
 | 
			
		||||
<p>Hi there! It looks like you tried to unsubscribe from something, but we don't
 | 
			
		||||
recognize the URL.</p>
 | 
			
		||||
 | 
			
		||||
<p>Please double-check that you have the full URL and try again, or <a href="mailto:{{ zulip_admin }}?Subject=Unsubscribe%20me%2C%20please!&Body=Hi%20there!%0A%0AI%20clicked%20this%20unsubscribe%20link%20in%20a%20Zulip%20e-mail%2C%20but%20it%20took%20me%20to%20an%20error%20page%3A%0A%0A_____________%0A%0APlease%20unsubscribe%20me.%0A%0AThanks%2C%0A_____________%0A">email us</a> and we'll get this squared away!</p>
 | 
			
		||||
 | 
			
		||||
{% endblock %}
 | 
			
		||||
							
								
								
									
										12
									
								
								templates/zerver/unsubscribe_success.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								templates/zerver/unsubscribe_success.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
{% extends "zerver/portico.html" %}
 | 
			
		||||
 | 
			
		||||
{% block portico_content %}
 | 
			
		||||
 | 
			
		||||
<h1>Email settings updated</h1>
 | 
			
		||||
 | 
			
		||||
<p>We've updated your email subscription settings, and you won't get emails
 | 
			
		||||
about {{ subscription_type }} anymore.</p>
 | 
			
		||||
 | 
			
		||||
<p>To undo this change or review your other subscription settings, please visit your <a href="https://{{ external_host }}/#settings">Zulip Settings page</a>.</p>
 | 
			
		||||
 | 
			
		||||
{% endblock %}
 | 
			
		||||
@@ -1920,6 +1920,21 @@ def build_message_list(user_profile, messages):
 | 
			
		||||
 | 
			
		||||
    return messages_to_render
 | 
			
		||||
 | 
			
		||||
def unsubscribe_token(user_profile):
 | 
			
		||||
    # Leverage the Django confirmations framework to generate and track unique
 | 
			
		||||
    # unsubscription tokens.
 | 
			
		||||
    return Confirmation.objects.get_link_for_object(user_profile).split("/")[-1]
 | 
			
		||||
 | 
			
		||||
def one_click_unsubscribe_link(user_profile, endpoint):
 | 
			
		||||
    """
 | 
			
		||||
    Generate a unique link that a logged-out user can visit to unsubscribe from
 | 
			
		||||
    Zulip e-mails without having to first log in.
 | 
			
		||||
    """
 | 
			
		||||
    token = unsubscribe_token(user_profile)
 | 
			
		||||
    base_url = "https://" + settings.EXTERNAL_HOST
 | 
			
		||||
    resource_path = "accounts/unsubscribe/%s/%s" % (endpoint, token)
 | 
			
		||||
    return "%s/%s" % (base_url.rstrip("/"), resource_path)
 | 
			
		||||
 | 
			
		||||
@statsd_increment("missed_message_reminders")
 | 
			
		||||
def do_send_missedmessage_events(user_profile, missed_messages):
 | 
			
		||||
    """
 | 
			
		||||
@@ -1960,6 +1975,11 @@ def do_send_missedmessage_events(user_profile, missed_messages):
 | 
			
		||||
            template_payload['reply_warning'] = True
 | 
			
		||||
            headers['Reply-To'] = "Nobody <%s>" % (settings.NOREPLY_EMAIL_ADDRESS,)
 | 
			
		||||
 | 
			
		||||
        # Give users a one-click unsubscribe link they can use to stop getting
 | 
			
		||||
        # missed message emails without having to log in first.
 | 
			
		||||
        unsubscribe_link = one_click_unsubscribe_link(user_profile, "missed_messages")
 | 
			
		||||
        template_payload["unsubscribe_link"] = unsubscribe_link
 | 
			
		||||
 | 
			
		||||
        subject = "Missed Zulip%s from %s" % (plural_messages, sender_str)
 | 
			
		||||
        from_email = "%s (via Zulip) <%s>" % (sender_str, settings.NOREPLY_EMAIL_ADDRESS)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2325,3 +2325,23 @@ def remove_apns_device_token(request, user_profile, token=REQ):
 | 
			
		||||
 | 
			
		||||
def generate_204(request):
 | 
			
		||||
    return HttpResponse(content=None, status=204)
 | 
			
		||||
 | 
			
		||||
def process_missedmessages_unsubscribe(token):
 | 
			
		||||
    try:
 | 
			
		||||
        confirmation = Confirmation.objects.get(confirmation_key=token)
 | 
			
		||||
    except Confirmation.DoesNotExist:
 | 
			
		||||
        return render_to_response('zerver/unsubscribe_link_error.html')
 | 
			
		||||
 | 
			
		||||
    user_profile = confirmation.content_object
 | 
			
		||||
    do_change_enable_offline_email_notifications(user_profile, False)
 | 
			
		||||
    return render_to_response('zerver/unsubscribe_success.html',
 | 
			
		||||
                              {"subscription_type": "missed messages",
 | 
			
		||||
                               "external_host": settings.EXTERNAL_HOST})
 | 
			
		||||
 | 
			
		||||
# Login NOT required. These are for one-click unsubscribes.
 | 
			
		||||
def email_unsubscribe(request, type, token):
 | 
			
		||||
    if type == "missed_messages":
 | 
			
		||||
        return process_missedmessages_unsubscribe(token)
 | 
			
		||||
 | 
			
		||||
    return render_to_response('zerver/unsubscribe_link_error.html', {},
 | 
			
		||||
                              context_instance=RequestContext(request))
 | 
			
		||||
 
 | 
			
		||||
@@ -56,6 +56,11 @@ urlpatterns = patterns('',
 | 
			
		||||
    url(r'^accounts/do_confirm/(?P<confirmation_key>[\w]+)', 'confirmation.views.confirm'),
 | 
			
		||||
    url(r'^invite/$', 'zerver.views.initial_invite_page', name='initial-invite-users'),
 | 
			
		||||
 | 
			
		||||
    # Unsubscription endpoint. Used for various types of e-mails (day 1 & 2,
 | 
			
		||||
    # missed PMs, etc.)
 | 
			
		||||
    url(r'^accounts/unsubscribe/(?P<type>[\w]+)/(?P<token>[\w]+)',
 | 
			
		||||
        'zerver.views.email_unsubscribe'),
 | 
			
		||||
 | 
			
		||||
    # Portico-styled page used to provide email confirmation of terms acceptance.
 | 
			
		||||
    url(r'^accounts/accept_terms/$', 'zerver.views.accounts_accept_terms'),
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user