[REF] mail, mass_mailing: improve logging of emails exclusion

Purpose of this commit is to use the newly introduced feature to log a message
when adding or removing an entry in block list of emails in email marketing
application.

Logging itself is improved, as it now contains

  * source of the request (unsubscribe link, or manual ask through the portal
    unsubscription page);
  * link to the source mailing;
  * link to the document that generated the click (a mailing contact, a sales
    order, ...);

Task-2710804 (Mail: Clean MailThread API)
Prepares Task-2150462 (Mass Mailing: Unsubscribe flow refactoring)

Part-of: odoo/odoo#106568
This commit is contained in:
Thibault Delavallée
2022-11-25 18:55:20 +01:00
parent 1844f335d7
commit f0bbe9561f
3 changed files with 53 additions and 26 deletions
+5 -5
View File
@@ -189,11 +189,11 @@ class Users(models.Model):
super(Users, self)._deactivate_portal_user(**post)
for user in users_to_blacklist:
blacklist = self.env['mail.blacklist']._add(user.email)
blacklist._message_log(
body=_('Blocked by deletion of portal account %(portal_user_name)s by %(user_name)s (#%(user_id)s)',
user_name=current_user.name, user_id=current_user.id,
portal_user_name=user.name),
self.env['mail.blacklist']._add(
user.email,
message=_('Blocked by deletion of portal account %(portal_user_name)s by %(user_name)s (#%(user_id)s)',
user_name=current_user.name, user_id=current_user.id,
portal_user_name=user.name)
)
# ------------------------------------------------------------
+42 -17
View File
@@ -7,6 +7,8 @@ import werkzeug
from odoo import _, exceptions, http, tools
from odoo.http import request
from odoo.tools import consteq
from markupsafe import Markup, escape
from werkzeug.exceptions import BadRequest, NotFound
@@ -18,11 +20,6 @@ class MassMailController(http.Controller):
mailing = request.env['mailing.mailing'].sudo().browse(mailing_id)
return consteq(mailing._unsubscribe_token(res_id, email), token)
def _log_blacklist_action(self, blacklist_entry, mailing_id, description):
mailing = request.env['mailing.mailing'].sudo().browse(mailing_id)
model_display = mailing.mailing_model_id.display_name
blacklist_entry._message_log(body=description + " ({})".format(model_display))
# ------------------------------------------------------------
# SUBSCRIPTION MANAGEMENT
# ------------------------------------------------------------
@@ -66,10 +63,15 @@ class MassMailController(http.Controller):
('contact_id.email_normalized', '=', email),
('opt_out', '=', False)
]).mapped('list_id')
blacklist_rec = request.env['mail.blacklist'].sudo()._add(email)
self._log_blacklist_action(
blacklist_rec, mailing_id,
_("""Requested blacklisting via unsubscribe link."""))
message = Markup('<p>%s</p>') % Markup(
_(
'Blocklist request from unsubscribe link of mailing %(mailing_link)s (document %(record_link)s)',
**self._format_bl_request(mailing, res_id)
)
)
_blacklist_rec = request.env['mail.blacklist'].sudo()._add(email, message=message)
return request.render('mass_mailing.page_unsubscribed', {
'email': email,
'mailing_id': mailing_id,
@@ -204,10 +206,18 @@ class MassMailController(http.Controller):
if not self._valid_unsubscribe_token(mailing_id, res_id, email, token):
return 'unauthorized'
if email:
blacklist_rec = request.env['mail.blacklist'].sudo()._add(email)
self._log_blacklist_action(
blacklist_rec, mailing_id,
_("""Requested blacklisting via unsubscription page."""))
if mailing_id and res_id:
mailing_sudo = request.env['mailing.mailing'].sudo().browse(mailing_id)
message = Markup('<p>%s</p>') % Markup(
_(
'Blocklist request from portal of mailing %(mailing_link)s (document %(record_link)s)',
**self._format_bl_request(mailing_sudo, res_id)
)
)
else:
message = Markup('<p>%s</p>') % _('Blocklist request from portal')
_blacklist_rec = request.env['mail.blacklist'].sudo()._add(email, message=message)
return True
return 'error'
@@ -216,13 +226,28 @@ class MassMailController(http.Controller):
if not self._valid_unsubscribe_token(mailing_id, res_id, email, token):
return 'unauthorized'
if email:
blacklist_rec = request.env['mail.blacklist'].sudo()._remove(email)
self._log_blacklist_action(
blacklist_rec, mailing_id,
_("""Requested de-blacklisting via unsubscription page."""))
if mailing_id and res_id:
mailing_sudo = request.env['mailing.mailing'].sudo().browse(mailing_id)
message = Markup('<p>%s</p>') % Markup(
_(
'Blocklist removal request from portal of mailing %(mailing_link)s (document %(record_link)s)',
**self._format_bl_request(mailing_sudo, res_id)
)
)
else:
message = Markup('<p>%s</p>') % _('Blocklist removal request from portal')
_blacklist_rec = request.env['mail.blacklist'].sudo()._remove(email, message=message)
return True
return 'error'
def _format_bl_request(self, mailing, document_id):
mailing_model_name = request.env['ir.model']._get(mailing.mailing_model_real).display_name
return {
'mailing_link': Markup(f'<a href="#" data-oe-model="mailing.mailing" data-oe-id="{mailing.id}">{escape(mailing.subject)}</a>'),
'record_link': Markup(f'<a href="#" data-oe-model="{escape(mailing.mailing_model_real)}" data-oe-id="{int(document_id)}">{escape(mailing_model_name)}</a>'),
}
# ------------------------------------------------------------
# MISCELLANEOUS
# ------------------------------------------------------------
+6 -4
View File
@@ -2,8 +2,9 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import datetime
from markupsafe import Markup
from odoo import api, models, fields, tools
from odoo import api, models, fields, tools, _
BLACKLIST_MAX_BOUNCED_LIMIT = 5
@@ -59,9 +60,10 @@ class MailThread(models.AbstractModel):
stats = self.env['mailing.trace'].search(['&', '&', ('trace_status', '=', 'bounce'), ('write_date', '>', three_months_ago), ('email', '=ilike', bounced_email)]).mapped('write_date')
if len(stats) >= BLACKLIST_MAX_BOUNCED_LIMIT and (not bounced_partner or any(p.message_bounce >= BLACKLIST_MAX_BOUNCED_LIMIT for p in bounced_partner)):
if max(stats) > min(stats) + datetime.timedelta(weeks=1):
blacklist_rec = self.env['mail.blacklist'].sudo()._add(bounced_email)
blacklist_rec._message_log(
body='This email has been automatically blacklisted because of too much bounced.')
self.env['mail.blacklist'].sudo()._add(
bounced_email,
message=Markup('<p>%s</p>') % _('This email has been automatically added in blocklist because of too much bounced.')
)
@api.model
def message_new(self, msg_dict, custom_values=None):