diff options
| author | Sébastien Mottet (oms) <oms@odoo.com> | 2020-04-20 15:02:30 +0000 |
|---|---|---|
| committer | Thibault Delavallée <tde@odoo.com> | 2020-08-05 13:55:04 +0000 |
| commit | ac0579263bc2996321f55cb20da3332f027dbb36 (patch) | |
| tree | 56e47c6bded008e4833c87e52ba5e35a125eb04d /addons | |
| parent | 0809601d6da21fcf00be3ad4b28cbcf350c7d09d (diff) | |
[IMP] mass_mailing: add 'view in browser' link in mailings
PURPOSE
Add a block that allows recipients to check the email in a browser in case
their mail service provider does not render it well or to see it full screen.
SPECIFICATIONS
A thumbnail has been added in the snippet thumbnails list of the mail editor.
It allows to add an header snippet. This snippet contains a link allowing the
recipient to see the mail in its browser instead of its mail client.
Add a route to display a mailing content. This route should be recipient
dependent as mailings could contain jinja markers. Using the same access token
and check as unsubscribe route this public route allows to display a mailing
content directly rendered for a given customer.
_get_unsubscribe_url method is moved from mail_mail to mailing as it does
not really belong to the mail model. Indeed it is mailing dependent.
A view URL leading to the view in browser route is added. It is managed like
the unsubscribe url: magically avoid shortening, magically rewrite when
sending email.
Task ID-2239327
PR #49886
Diffstat (limited to 'addons')
| -rw-r--r-- | addons/mass_mailing/controllers/main.py | 29 | ||||
| -rw-r--r-- | addons/mass_mailing/models/mail_mail.py | 28 | ||||
| -rw-r--r-- | addons/mass_mailing/models/mail_render_mixin.py | 2 | ||||
| -rw-r--r-- | addons/mass_mailing/models/mailing.py | 31 | ||||
| -rwxr-xr-x | addons/mass_mailing/static/src/img/blocks/block_header_browser.png | bin | 0 -> 376 bytes | |||
| -rw-r--r-- | addons/mass_mailing/views/mass_mailing_templates_portal.xml | 5 | ||||
| -rw-r--r-- | addons/mass_mailing/views/snippets_themes.xml | 19 |
7 files changed, 93 insertions, 21 deletions
diff --git a/addons/mass_mailing/controllers/main.py b/addons/mass_mailing/controllers/main.py index 30653260425..bae258f9bf1 100644 --- a/addons/mass_mailing/controllers/main.py +++ b/addons/mass_mailing/controllers/main.py @@ -105,6 +105,35 @@ class MassMailController(http.Controller): return response + @http.route(['/mailing/<int:mailing_id>/view'], type='http', website=True, auth='public') + def view(self, mailing_id, email=None, res_id=None, token=""): + mailing = request.env['mailing.mailing'].sudo().browse(mailing_id) + if mailing.exists(): + res_id = int(res_id) if res_id else False + if not self._valid_unsubscribe_token(mailing_id, res_id, email, str(token)) and not request.env.user.has_group('mass_mailing.group_mass_mailing_user'): + raise exceptions.AccessDenied() + + res = mailing.convert_links() + base_url = request.env['ir.config_parameter'].sudo().get_param('web.base.url').rstrip('/') + urls_to_replace = [ + (base_url + '/unsubscribe_from_list', mailing._get_unsubscribe_url(email, res_id)), + (base_url + '/view', mailing._get_view_url(email, res_id)) + ] + for url_to_replace, new_url in urls_to_replace: + if url_to_replace in res[mailing_id]: + res[mailing_id] = res[mailing_id].replace(url_to_replace, new_url if new_url else '#') + + res[mailing_id] = res[mailing_id].replace( + 'class="o_snippet_view_in_browser"', + 'class="o_snippet_view_in_browser" style="display: none;"' + ) + + return request.render('mass_mailing.view', { + 'body': res[mailing_id], + }) + + return request.redirect('/web') + @http.route('/r/<string:code>/m/<int:mailing_trace_id>', type='http', auth="public") def full_url_redirect(self, code, mailing_trace_id, **post): # don't assume geoip is set, it is part of the website module diff --git a/addons/mass_mailing/models/mail_mail.py b/addons/mass_mailing/models/mail_mail.py index 4c627234c27..4339dfdf6bc 100644 --- a/addons/mass_mailing/models/mail_mail.py +++ b/addons/mass_mailing/models/mail_mail.py @@ -29,21 +29,6 @@ class MailMail(models.Model): token = tools.hmac(self.env(su=True), 'mass_mailing-mail_mail-open', self.id) return werkzeug.urls.url_join(base_url, 'mail/track/%s/%s/blank.gif' % (self.id, token)) - def _get_unsubscribe_url(self, email_to): - base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') - url = werkzeug.urls.url_join( - base_url, 'mail/mailing/%(mailing_id)s/unsubscribe?%(params)s' % { - 'mailing_id': self.mailing_id.id, - 'params': werkzeug.urls.url_encode({ - 'res_id': self.res_id, - 'email': email_to, - 'token': self.mailing_id._unsubscribe_token( - self.res_id, email_to), - }), - } - ) - return url - def _send_prepare_body(self): """ Override to add the tracking URL to the body and to add trace ID in shortened urls """ @@ -81,10 +66,15 @@ class MailMail(models.Model): if self.mailing_id and res.get('body') and res.get('email_to'): emails = tools.email_split(res.get('email_to')[0]) email_to = emails and emails[0] or False - unsubscribe_url = self._get_unsubscribe_url(email_to) - link_to_replace = base_url + '/unsubscribe_from_list' - if link_to_replace in res['body']: - res['body'] = res['body'].replace(link_to_replace, unsubscribe_url if unsubscribe_url else '#') + + urls_to_replace = [ + (base_url + '/unsubscribe_from_list', self.mailing_id._get_unsubscribe_url(email_to, self.res_id)), + (base_url + '/view', self.mailing_id._get_view_url(email_to, self.res_id)) + ] + + for url_to_replace, new_url in urls_to_replace: + if url_to_replace in res['body']: + res['body'] = res['body'].replace(url_to_replace, new_url if new_url else '#') return res def _postprocess_sent_message(self, success_pids, failure_reason=False, failure_type=None): diff --git a/addons/mass_mailing/models/mail_render_mixin.py b/addons/mass_mailing/models/mail_render_mixin.py index 4447f3931c8..133643f29ff 100644 --- a/addons/mass_mailing/models/mail_render_mixin.py +++ b/addons/mass_mailing/models/mail_render_mixin.py @@ -18,6 +18,6 @@ class MailRenderMixin(models.AbstractModel): rendered[res_id] = self._shorten_links( html, self.env.context['post_convert_links'], - blacklist=['/unsubscribe_from_list'] + blacklist=['/unsubscribe_from_list', '/view'] ) return rendered diff --git a/addons/mass_mailing/models/mailing.py b/addons/mass_mailing/models/mailing.py index 7d6426b2ca1..78890b1a6d8 100644 --- a/addons/mass_mailing/models/mailing.py +++ b/addons/mass_mailing/models/mailing.py @@ -8,6 +8,7 @@ import lxml import random import re import threading +import werkzeug.urls from ast import literal_eval from datetime import datetime from dateutil.relativedelta import relativedelta @@ -528,6 +529,34 @@ class MassMailing(models.Model): done_res_ids = [record['res_id'] for record in already_mailed] return [rid for rid in res_ids if rid not in done_res_ids] + def _get_unsubscribe_url(self, email_to, res_id): + base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') + url = werkzeug.urls.url_join( + base_url, 'mail/mailing/%(mailing_id)s/unsubscribe?%(params)s' % { + 'mailing_id': self.id, + 'params': werkzeug.urls.url_encode({ + 'res_id': res_id, + 'email': email_to, + 'token': self._unsubscribe_token(res_id, email_to), + }), + } + ) + return url + + def _get_view_url(self, email_to, res_id): + base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') + url = werkzeug.urls.url_join( + base_url, 'mailing/%(mailing_id)s/view?%(params)s' % { + 'mailing_id': self.id, + 'params': werkzeug.urls.url_encode({ + 'res_id': res_id, + 'email': email_to, + 'token': self._unsubscribe_token(res_id, email_to), + }), + } + ) + return url + def action_send_mail(self, res_ids=None): author_id = self.env.user.partner_id.id @@ -583,7 +612,7 @@ class MassMailing(models.Model): if mass_mailing.medium_id: vals['medium_id'] = mass_mailing.medium_id.id - res[mass_mailing.id] = mass_mailing._shorten_links(html, vals, blacklist=['/unsubscribe_from_list']) + res[mass_mailing.id] = mass_mailing._shorten_links(html, vals, blacklist=['/unsubscribe_from_list', '/view']) return res diff --git a/addons/mass_mailing/static/src/img/blocks/block_header_browser.png b/addons/mass_mailing/static/src/img/blocks/block_header_browser.png Binary files differnew file mode 100755 index 00000000000..c05196e7e5e --- /dev/null +++ b/addons/mass_mailing/static/src/img/blocks/block_header_browser.png diff --git a/addons/mass_mailing/views/mass_mailing_templates_portal.xml b/addons/mass_mailing/views/mass_mailing_templates_portal.xml index a3cbdc4dc32..52da35d41e1 100644 --- a/addons/mass_mailing/views/mass_mailing_templates_portal.xml +++ b/addons/mass_mailing/views/mass_mailing_templates_portal.xml @@ -97,6 +97,11 @@ </div> </template> + <template id="view" name="Browser View"> + <!-- Raw body inserted here because it is a rendered mailing, therefore internal content --> + <t t-raw="body"/> + </template> + <template id="page_unsubscribe" name="Unsubscribe"> <t t-call="mass_mailing.layout"> <t t-call="mass_mailing.unsubscribe"/> diff --git a/addons/mass_mailing/views/snippets_themes.xml b/addons/mass_mailing/views/snippets_themes.xml index dad05aa1e5c..5d88537b190 100644 --- a/addons/mass_mailing/views/snippets_themes.xml +++ b/addons/mass_mailing/views/snippets_themes.xml @@ -28,6 +28,7 @@ <t t-snippet="mass_mailing.s_mail_block_header_text_social" t-thumbnail="/mass_mailing/static/src/img/blocks/block_header_text_social.png"/> <t t-snippet="mass_mailing.s_mail_block_header_logo" t-thumbnail="/mass_mailing/static/src/img/blocks/block_header_logo.png"/> <t t-snippet="mass_mailing.s_mail_block_banner" t-thumbnail="/mass_mailing/static/src/img/blocks/block_banner.png"/> + <t t-snippet="mass_mailing.s_mail_block_header_view" t-thumbnail="/mass_mailing/static/src/img/blocks/block_header_browser.png"/> </div> </div> <div id="email_designer_default_body" class="o_panel"> @@ -154,6 +155,24 @@ </div> </template> +<template id="s_mail_block_header_view" name="View in browser"> + <div class="o_snippet_view_in_browser"> + <div class="o_mail_snippet_general"> + <table align="center" cellspacing="0" cellpadding="0" border="0" class="o_mail_table_styles"> + <tbody> + <tr> + <td width="100%" class="o_mail_h_padding o_mail_v_padding o_mail_no_colorpicker text-center"> + <a href="/view"> + View this email in your browser + </a> + </td> + </tr> + </tbody> + </table> + </div> + </div> +</template> + <template id="s_mail_block_title_text" name="Title Content"> <div class="o_mail_block_title_text"> <div class="o_mail_snippet_general"> |
