From ac0579263bc2996321f55cb20da3332f027dbb36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Mottet=20=28oms=29?= Date: Mon, 20 Apr 2020 15:02:30 +0000 Subject: [PATCH] [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 --- addons/mass_mailing/controllers/main.py | 29 ++++++++++++++++ addons/mass_mailing/models/mail_mail.py | 28 +++++----------- .../mass_mailing/models/mail_render_mixin.py | 2 +- addons/mass_mailing/models/mailing.py | 31 +++++++++++++++++- .../src/img/blocks/block_header_browser.png | Bin 0 -> 376 bytes .../views/mass_mailing_templates_portal.xml | 5 +++ addons/mass_mailing/views/snippets_themes.xml | 19 +++++++++++ 7 files changed, 93 insertions(+), 21 deletions(-) create mode 100755 addons/mass_mailing/static/src/img/blocks/block_header_browser.png 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//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//m/', 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 new file mode 100755 index 0000000000000000000000000000000000000000..c05196e7e5e0c6aacf2c1e681fa5a6c29936e760 GIT binary patch literal 376 zcmeAS@N?(olHy`uVBq!ia0vp^M}T+=3p0?kW1GDmNJ#|vgt-3y|Nq9#n}ucNyLRpB z>gip&Z295CM=o5rSn_?HE>I0;fk$L90|U1(2s1Lwnj--eWH0gbb!C6TBEqAon!8B- z3sC5@r;B4q#=W=K9Qh6gh`1$A`w*0Se4WwtO$@w-dYzVG3nt#!_pQ^&V8I{GqJ4qs z%eU*l+&z~Ms4?obm8g))J{7^U+3cx{(ziNIypev-VuGrke*U%cl^TMxe;S`i*Aq~6 zx;9{>OV literal 0 HcmV?d00001 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 @@ + + + +