From 73ee8b6508689faa4a13a0ec2f460ce8280b322f Mon Sep 17 00:00:00 2001 From: jeet-dreambits Date: Fri, 10 Jul 2026 16:34:02 +0530 Subject: [PATCH 1/5] [18.0]mig_mass_mailing_disable_tracking --- mass_mailing_disable_tracking/README.rst | 111 +++++ mass_mailing_disable_tracking/__init__.py | 5 + mass_mailing_disable_tracking/__manifest__.py | 23 + mass_mailing_disable_tracking/i18n/it.po | 60 +++ .../i18n/mass_mailing_disable_tracking.pot | 52 ++ .../models/__init__.py | 7 + .../models/mail_mail.py | 86 ++++ .../models/mail_render_mixin.py | 27 ++ .../models/res_config_settings.py | 19 + .../readme/CONTRIBUTORS.rst | 1 + .../readme/DESCRIPTION.rst | 15 + .../readme/USAGE.rst | 5 + .../static/description/icon.png | Bin 0 -> 10254 bytes .../static/description/index.html | 452 ++++++++++++++++++ .../tests/__init__.py | 5 + .../test_mass_mailing_disable_tracking.py | 132 +++++ .../views/res_config_settings_view.xml | 46 ++ 17 files changed, 1046 insertions(+) create mode 100644 mass_mailing_disable_tracking/README.rst create mode 100644 mass_mailing_disable_tracking/__init__.py create mode 100644 mass_mailing_disable_tracking/__manifest__.py create mode 100644 mass_mailing_disable_tracking/i18n/it.po create mode 100644 mass_mailing_disable_tracking/i18n/mass_mailing_disable_tracking.pot create mode 100644 mass_mailing_disable_tracking/models/__init__.py create mode 100644 mass_mailing_disable_tracking/models/mail_mail.py create mode 100644 mass_mailing_disable_tracking/models/mail_render_mixin.py create mode 100644 mass_mailing_disable_tracking/models/res_config_settings.py create mode 100644 mass_mailing_disable_tracking/readme/CONTRIBUTORS.rst create mode 100644 mass_mailing_disable_tracking/readme/DESCRIPTION.rst create mode 100644 mass_mailing_disable_tracking/readme/USAGE.rst create mode 100644 mass_mailing_disable_tracking/static/description/icon.png create mode 100644 mass_mailing_disable_tracking/static/description/index.html create mode 100644 mass_mailing_disable_tracking/tests/__init__.py create mode 100644 mass_mailing_disable_tracking/tests/test_mass_mailing_disable_tracking.py create mode 100644 mass_mailing_disable_tracking/views/res_config_settings_view.xml diff --git a/mass_mailing_disable_tracking/README.rst b/mass_mailing_disable_tracking/README.rst new file mode 100644 index 0000000000..0fc9abee63 --- /dev/null +++ b/mass_mailing_disable_tracking/README.rst @@ -0,0 +1,111 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +============================= +Mass Mailing Disable Tracking +============================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:1e2637616e4184bea186bcb57d3a5eca2df0bad6829bd9c9379853c2a6ea2b05 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsocial-lightgray.png?logo=github + :target: https://github.com/OCA/social/tree/16.0/mass_mailing_disable_tracking + :alt: OCA/social +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/social-16-0/social-16-0-mass_mailing_disable_tracking + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/social&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows to disable open and link click tracking in mass mailing messages. + +Odoo Mass Mailing (aka Email Marketing) includes 2 ways of tracking (spying on, invade the privacy of) the recipients: + +1. Tracking the “opening” of the email message by including a 1-pixel transparent GIF image at the bottom of the message, using a URL to the Odoo instance that uniquely identifies that message sent to that recipient. + As soon as the recipient displays the remote images of the message, their email client downloads the tracking image and the Odoo instance knows that that particular recipient opened that particular message. +2. Tracking the “clicks” on the links included in the message by converting all links of the message to a tracking URL to the Odoo instance. + As soon as the recipient clicks one of those links, their browser will make a request to the Odoo instance, which will record that click on that particular link for that particular recipient before redirecting the browser to the original link address. + +This module allows to disable both of these mechanisms by preventing the original email message to be modified by Odoo to include these tracking mechanisms. + +Another issue that link click tracking causes is that recipients are unable to inspect the links: they cannot know on which website they will land before clicking on them. +This, and the fact that they are tracked, can cause some recipients to not click the links, making the mass mailing actually less effective. + +Statistics can be useful, but respecting your recipients’ privacy is important. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +By default, just by installing this module, open and link click tracking is disabled for new mass mailings. + +It is still possible to enable each one separately by going to **Settings** > **Email Marketing** and checking the corresponding checkboxes. + +.. note:: This module is incompatible with the ``mail_tracking`` module. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* hugues de keyzer + +Contributors +~~~~~~~~~~~~ + +* hugues de keyzer + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +.. |maintainer-huguesdk| image:: https://github.com/huguesdk.png?size=40px + :target: https://github.com/huguesdk + :alt: huguesdk + +Current `maintainer `__: + +|maintainer-huguesdk| + +This module is part of the `OCA/social `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/mass_mailing_disable_tracking/__init__.py b/mass_mailing_disable_tracking/__init__.py new file mode 100644 index 0000000000..0c988b743b --- /dev/null +++ b/mass_mailing_disable_tracking/__init__.py @@ -0,0 +1,5 @@ +# SPDX-FileCopyrightText: 2025 hugues de keyzer +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from . import models diff --git a/mass_mailing_disable_tracking/__manifest__.py b/mass_mailing_disable_tracking/__manifest__.py new file mode 100644 index 0000000000..eda1ad13db --- /dev/null +++ b/mass_mailing_disable_tracking/__manifest__.py @@ -0,0 +1,23 @@ +# SPDX-FileCopyrightText: 2025 hugues de keyzer +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +{ + "name": "Mass Mailing Disable Tracking", + "summary": "Allow to disable open and link click tracking in mass mailing messages", + "version": "18.0.1.0.0", + "category": "Marketing/Email Marketing", + "website": "https://github.com/OCA/social", + "author": "hugues de keyzer, Odoo Community Association (OCA)", + "maintainers": ["huguesdk"], + "license": "AGPL-3", + "depends": [ + "mass_mailing", + ], + "excludes": [ + "mail_tracking", + ], + "data": [ + "views/res_config_settings_view.xml", + ], +} diff --git a/mass_mailing_disable_tracking/i18n/it.po b/mass_mailing_disable_tracking/i18n/it.po new file mode 100644 index 0000000000..6d790490ae --- /dev/null +++ b/mass_mailing_disable_tracking/i18n/it.po @@ -0,0 +1,60 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mass_mailing_disable_tracking +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2026-04-30 10:45+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.15.2\n" + +#. module: mass_mailing_disable_tracking +#: model_terms:ir.ui.view,arch_db:mass_mailing_disable_tracking.res_config_settings_view_form +msgid "" +"Add an invisible tracking image to mass mailing messages to track their " +"opening by the recipient" +msgstr "" +"Aggiungere un'immagine di tracciamento invisibile ai messaggi di posta " +"elettronica inviati in massa per monitorare l'apertura da parte del " +"destinatario" + +#. module: mass_mailing_disable_tracking +#: model:ir.model,name:mass_mailing_disable_tracking.model_res_config_settings +msgid "Config Settings" +msgstr "Impostazioni configurazione" + +#. module: mass_mailing_disable_tracking +#: model_terms:ir.ui.view,arch_db:mass_mailing_disable_tracking.res_config_settings_view_form +msgid "" +"Convert links in mass mailing messages to track link clicks by the recipient" +msgstr "" +"Convertire i link nei messaggi di posta elettronica inviati in massa per " +"monitorare i clic sui link da parte del destinatario" + +#. module: mass_mailing_disable_tracking +#: model:ir.model,name:mass_mailing_disable_tracking.model_mail_render_mixin +msgid "Mail Render Mixin" +msgstr "Mixin resa posta" + +#. module: mass_mailing_disable_tracking +#: model:ir.model,name:mass_mailing_disable_tracking.model_mail_mail +msgid "Outgoing Mails" +msgstr "E-mail in uscita" + +#. module: mass_mailing_disable_tracking +#: model:ir.model.fields,field_description:mass_mailing_disable_tracking.field_res_config_settings__mailing_track_links +msgid "Track Link Clicks" +msgstr "Traccia clic link" + +#. module: mass_mailing_disable_tracking +#: model:ir.model.fields,field_description:mass_mailing_disable_tracking.field_res_config_settings__mailing_track_open +msgid "Track Open" +msgstr "Traccia apertura" diff --git a/mass_mailing_disable_tracking/i18n/mass_mailing_disable_tracking.pot b/mass_mailing_disable_tracking/i18n/mass_mailing_disable_tracking.pot new file mode 100644 index 0000000000..ffce96cd8b --- /dev/null +++ b/mass_mailing_disable_tracking/i18n/mass_mailing_disable_tracking.pot @@ -0,0 +1,52 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mass_mailing_disable_tracking +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: mass_mailing_disable_tracking +#: model_terms:ir.ui.view,arch_db:mass_mailing_disable_tracking.res_config_settings_view_form +msgid "" +"Add an invisible tracking image to mass mailing messages to track their " +"opening by the recipient" +msgstr "" + +#. module: mass_mailing_disable_tracking +#: model:ir.model,name:mass_mailing_disable_tracking.model_res_config_settings +msgid "Config Settings" +msgstr "" + +#. module: mass_mailing_disable_tracking +#: model_terms:ir.ui.view,arch_db:mass_mailing_disable_tracking.res_config_settings_view_form +msgid "" +"Convert links in mass mailing messages to track link clicks by the recipient" +msgstr "" + +#. module: mass_mailing_disable_tracking +#: model:ir.model,name:mass_mailing_disable_tracking.model_mail_render_mixin +msgid "Mail Render Mixin" +msgstr "" + +#. module: mass_mailing_disable_tracking +#: model:ir.model,name:mass_mailing_disable_tracking.model_mail_mail +msgid "Outgoing Mails" +msgstr "" + +#. module: mass_mailing_disable_tracking +#: model:ir.model.fields,field_description:mass_mailing_disable_tracking.field_res_config_settings__mailing_track_links +msgid "Track Link Clicks" +msgstr "" + +#. module: mass_mailing_disable_tracking +#: model:ir.model.fields,field_description:mass_mailing_disable_tracking.field_res_config_settings__mailing_track_open +msgid "Track Open" +msgstr "" diff --git a/mass_mailing_disable_tracking/models/__init__.py b/mass_mailing_disable_tracking/models/__init__.py new file mode 100644 index 0000000000..81c94f99c3 --- /dev/null +++ b/mass_mailing_disable_tracking/models/__init__.py @@ -0,0 +1,7 @@ +# SPDX-FileCopyrightText: 2025 hugues de keyzer +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from . import mail_mail +from . import mail_render_mixin +from . import res_config_settings diff --git a/mass_mailing_disable_tracking/models/mail_mail.py b/mass_mailing_disable_tracking/models/mail_mail.py new file mode 100644 index 0000000000..10f2a49c7f --- /dev/null +++ b/mass_mailing_disable_tracking/models/mail_mail.py @@ -0,0 +1,86 @@ +# SPDX-FileCopyrightText: 2025 hugues de keyzer +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +import re + +import werkzeug.urls +from markupsafe import Markup + +from odoo import api, models, tools + +from .res_config_settings import TRACK_LINKS_PARAMETER, TRACK_OPEN_PARAMETER + +TRACKING_LINK_PREFIX = "/r/" +DO_NOT_REPLACE_PLACEHOLDER = "/__do_not_replace__/" +DUMMY_TRACKING_URL = "https://this.is.a.dummy.tracking.url/" + + +class MailMail(models.Model): + _inherit = "mail.mail" + + def _replace_in_html(self, html, to_replace, value): + # this comes from mail.render.mixin._replace_local_links() from the + # mail module. + if not html: + return html + wrapper = Markup if isinstance(html, Markup) else str + html = tools.ustr(html) + return wrapper(html.replace(to_replace, value)) + + @api.model + def _replace_tracking_like_links(self, body, to_replace, value): + # this is the same mechanism to find and replace links as used in the + # _prepare_outgoing_body() method from the mass_mailing module. + for match in set(re.findall(tools.mail.URL_REGEX, body)): + href = match[0] + url = match[1] + parsed = werkzeug.urls.url_parse(url, scheme="http") + if parsed.scheme.startswith("http") and parsed.path.startswith(to_replace): + new_href = href.replace(url, url.replace(to_replace, value)) + body = self._replace_in_html(body, href, new_href) + return body + + def _get_tracking_url(self): + if self.env["ir.config_parameter"].sudo().get_param(TRACK_OPEN_PARAMETER): + return super()._get_tracking_url() + # return a dummy tracking url that can be replaced afterwards. it must + # be a full url, otherwise it will be considered as a local url and + # converted. + return DUMMY_TRACKING_URL + + def _prepare_outgoing_body(self): + # mail.mail._prepare_outgoing_body() in the mass_mailing module does 2 + # things: + # 1. convert tracking links by appending a mailing.trace id to them. + # 2. add an tracking image at the end of the html body. + # it does these things only if its mailing_id and mailing_trace_ids + # fields are set. + self.ensure_one() + ir_config_parameter_model = self.env["ir.config_parameter"].sudo() + track_open = ir_config_parameter_model.get_param(TRACK_OPEN_PARAMETER) + track_links = ir_config_parameter_model.get_param(TRACK_LINKS_PARAMETER) + if ( + not self.mailing_id + or not self.mailing_trace_ids + or (track_open and track_links) + ): + return super()._prepare_outgoing_body() + body_html = self.body_html + if not track_links: + # ensure that there are no links that look like tracking links to + # avoid them being replaced. + self.body_html = self._replace_tracking_like_links( + self.body_html, TRACKING_LINK_PREFIX, DO_NOT_REPLACE_PLACEHOLDER + ) + body = super()._prepare_outgoing_body() + if not track_links: + self.body_html = body_html + body = self._replace_tracking_like_links( + body, DO_NOT_REPLACE_PLACEHOLDER, TRACKING_LINK_PREFIX + ) + if not track_open: + body = self._replace_in_html( + body, f'\n\n', "" + ) + return body diff --git a/mass_mailing_disable_tracking/models/mail_render_mixin.py b/mass_mailing_disable_tracking/models/mail_render_mixin.py new file mode 100644 index 0000000000..20eb543773 --- /dev/null +++ b/mass_mailing_disable_tracking/models/mail_render_mixin.py @@ -0,0 +1,27 @@ +# SPDX-FileCopyrightText: 2025 hugues de keyzer +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from odoo import api, models + +from .res_config_settings import TRACK_LINKS_PARAMETER + + +class MailRenderMixin(models.AbstractModel): + _inherit = "mail.render.mixin" + + @api.model + def _shorten_links(self, html, link_tracker_vals, blacklist=None, base_url=None): + if self.env["ir.config_parameter"].sudo().get_param(TRACK_LINKS_PARAMETER): + return super()._shorten_links(html, link_tracker_vals, blacklist, base_url) + return html + + @api.model + def _shorten_links_text( + self, content, link_tracker_vals, blacklist=None, base_url=None + ): + if self.env["ir.config_parameter"].sudo().get_param(TRACK_LINKS_PARAMETER): + return super()._shorten_links_text( + content, link_tracker_vals, blacklist, base_url + ) + return content diff --git a/mass_mailing_disable_tracking/models/res_config_settings.py b/mass_mailing_disable_tracking/models/res_config_settings.py new file mode 100644 index 0000000000..0e3a50040d --- /dev/null +++ b/mass_mailing_disable_tracking/models/res_config_settings.py @@ -0,0 +1,19 @@ +# SPDX-FileCopyrightText: 2025 hugues de keyzer +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from odoo import fields, models + +TRACK_OPEN_PARAMETER = "mailing.mailing.track_open" +TRACK_LINKS_PARAMETER = "mailing.mailing.track_links" + + +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + mailing_track_open = fields.Boolean( + "Track Open", config_parameter=TRACK_OPEN_PARAMETER + ) + mailing_track_links = fields.Boolean( + "Track Link Clicks", config_parameter=TRACK_LINKS_PARAMETER + ) diff --git a/mass_mailing_disable_tracking/readme/CONTRIBUTORS.rst b/mass_mailing_disable_tracking/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000000..36e8d00f65 --- /dev/null +++ b/mass_mailing_disable_tracking/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* hugues de keyzer diff --git a/mass_mailing_disable_tracking/readme/DESCRIPTION.rst b/mass_mailing_disable_tracking/readme/DESCRIPTION.rst new file mode 100644 index 0000000000..c3cd30efe5 --- /dev/null +++ b/mass_mailing_disable_tracking/readme/DESCRIPTION.rst @@ -0,0 +1,15 @@ +This module allows to disable open and link click tracking in mass mailing messages. + +Odoo Mass Mailing (aka Email Marketing) includes 2 ways of tracking (spying on, invade the privacy of) the recipients: + +1. Tracking the “opening” of the email message by including a 1-pixel transparent GIF image at the bottom of the message, using a URL to the Odoo instance that uniquely identifies that message sent to that recipient. + As soon as the recipient displays the remote images of the message, their email client downloads the tracking image and the Odoo instance knows that that particular recipient opened that particular message. +2. Tracking the “clicks” on the links included in the message by converting all links of the message to a tracking URL to the Odoo instance. + As soon as the recipient clicks one of those links, their browser will make a request to the Odoo instance, which will record that click on that particular link for that particular recipient before redirecting the browser to the original link address. + +This module allows to disable both of these mechanisms by preventing the original email message to be modified by Odoo to include these tracking mechanisms. + +Another issue that link click tracking causes is that recipients are unable to inspect the links: they cannot know on which website they will land before clicking on them. +This, and the fact that they are tracked, can cause some recipients to not click the links, making the mass mailing actually less effective. + +Statistics can be useful, but respecting your recipients’ privacy is important. diff --git a/mass_mailing_disable_tracking/readme/USAGE.rst b/mass_mailing_disable_tracking/readme/USAGE.rst new file mode 100644 index 0000000000..44fbb348c4 --- /dev/null +++ b/mass_mailing_disable_tracking/readme/USAGE.rst @@ -0,0 +1,5 @@ +By default, just by installing this module, open and link click tracking is disabled for new mass mailings. + +It is still possible to enable each one separately by going to **Settings** > **Email Marketing** and checking the corresponding checkboxes. + +.. note:: This module is incompatible with the ``mail_tracking`` module. diff --git a/mass_mailing_disable_tracking/static/description/icon.png b/mass_mailing_disable_tracking/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1dcc49c24f364e9adf0afbc6fc0bac6dbecdeb11 GIT binary patch literal 10254 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 + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Mass Mailing Disable Tracking

+ +

Beta License: AGPL-3 OCA/social Translate me on Weblate Try me on Runboat

+

This module allows to disable open and link click tracking in mass mailing messages.

+

Odoo Mass Mailing (aka Email Marketing) includes 2 ways of tracking (spying on, invade the privacy of) the recipients:

+
    +
  1. Tracking the “opening” of the email message by including a 1-pixel transparent GIF image at the bottom of the message, using a URL to the Odoo instance that uniquely identifies that message sent to that recipient. +As soon as the recipient displays the remote images of the message, their email client downloads the tracking image and the Odoo instance knows that that particular recipient opened that particular message.
  2. +
  3. Tracking the “clicks” on the links included in the message by converting all links of the message to a tracking URL to the Odoo instance. +As soon as the recipient clicks one of those links, their browser will make a request to the Odoo instance, which will record that click on that particular link for that particular recipient before redirecting the browser to the original link address.
  4. +
+

This module allows to disable both of these mechanisms by preventing the original email message to be modified by Odoo to include these tracking mechanisms.

+

Another issue that link click tracking causes is that recipients are unable to inspect the links: they cannot know on which website they will land before clicking on them. +This, and the fact that they are tracked, can cause some recipients to not click the links, making the mass mailing actually less effective.

+

Statistics can be useful, but respecting your recipients’ privacy is important.

+

Table of contents

+ +
+

Usage

+

By default, just by installing this module, open and link click tracking is disabled for new mass mailings.

+

It is still possible to enable each one separately by going to Settings > Email Marketing and checking the corresponding checkboxes.

+
+

Note

+

This module is incompatible with the mail_tracking module.

+
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • hugues de keyzer
  • +
+
+
+

Contributors

+
    +
  • hugues de keyzer
  • +
+
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

Current maintainer:

+

huguesdk

+

This module is part of the OCA/social project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+
+ + diff --git a/mass_mailing_disable_tracking/tests/__init__.py b/mass_mailing_disable_tracking/tests/__init__.py new file mode 100644 index 0000000000..773b3ba9bc --- /dev/null +++ b/mass_mailing_disable_tracking/tests/__init__.py @@ -0,0 +1,5 @@ +# SPDX-FileCopyrightText: 2025 hugues de keyzer +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from . import test_mass_mailing_disable_tracking diff --git a/mass_mailing_disable_tracking/tests/test_mass_mailing_disable_tracking.py b/mass_mailing_disable_tracking/tests/test_mass_mailing_disable_tracking.py new file mode 100644 index 0000000000..6a499aa5a6 --- /dev/null +++ b/mass_mailing_disable_tracking/tests/test_mass_mailing_disable_tracking.py @@ -0,0 +1,132 @@ +# SPDX-FileCopyrightText: 2025 hugues de keyzer +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from markupsafe import Markup + +from odoo import Command +from odoo.tests.common import TransactionCase + +from odoo.addons.mass_mailing_disable_tracking.models.res_config_settings import ( + TRACK_LINKS_PARAMETER, + TRACK_OPEN_PARAMETER, +) + + +class TestMassMailingDisableTracking(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.test_mailing_list = cls.env["mailing.list"].create( + { + "name": "dummy test mailing list", + } + ) + cls.test_mailing_contact = cls.env["mailing.contact"].create( + { + "name": "dummy test mailing contact", + "email": "test@example.net", + "list_ids": [Command.set([cls.test_mailing_list.id])], + } + ) + cls.markup = Markup( + '

hello, this is a link

' + "

this is not a link: https://odoo-community.org/

" + '

' + "this is a link that looks like a tracking link

" + ) + cls.test_mailing_mailing = cls.env["mailing.mailing"].create( + { + "name": "dummy test mailing mailing", + "subject": "dummy test subject", + "contact_list_ids": [Command.set([cls.test_mailing_list.id])], + "body_html": cls.markup, + "keep_archives": True, + } + ) + cls.base_url = cls.env["ir.config_parameter"].get_param("web.base.url") + + def _get_last_mail_id(self): + return self.env["mail.mail"].search([], order="id desc", limit=1).id + + def _get_new_mail_messages(self, last_mail_id): + return self.env["mail.mail"].search([("id", ">", last_mail_id or 0)]) + + def _send_mail(self): + last_mail_id = self._get_last_mail_id() + self.test_mailing_mailing.action_send_mail() + mail_mail = self._get_new_mail_messages(last_mail_id) + # the tracking image is only added when actually sending the message: + # mail.mail._send_prepare_values() is called and the result is sent + # (but not saved). compute the sent value by ._send_prepare_values() + # directly. + return mail_mail._send_prepare_values() + + def test_disable_tracking(self): + self.env["ir.config_parameter"].set_param(TRACK_OPEN_PARAMETER, False) + self.env["ir.config_parameter"].set_param(TRACK_LINKS_PARAMETER, False) + mail = self._send_mail() + # nothing should be transformed. this includes links starting with /r/ + # that must not get a mailing.track id appended to them. + self.assertRegex(str(mail["body"]), rf"\s*?{str(self.markup)}\s*?") + + def test_disable_tracking_with_special_links(self): + self.env["ir.config_parameter"].set_param(TRACK_OPEN_PARAMETER, False) + self.env["ir.config_parameter"].set_param(TRACK_LINKS_PARAMETER, False) + self.test_mailing_mailing.body_html = Markup( + str(self.markup) + + '

this is an unsubscribe link

' + '

this is a view link

' + '

this is a local link

' + ) + mail = self._send_mail() + # unsubscribe and view links should still be converted and local links + # should become full urls. + self.assertRegex( + str(mail["body"]), + rf"\s*?{str(self.markup)}" + rf'

' + "this is an unsubscribe link

" + rf'

' + "this is a view link

" + f'

' + rf"this is a local link

\s*?", + ) + + def test_enable_open_tracking_only(self): + self.env["ir.config_parameter"].set_param(TRACK_OPEN_PARAMETER, True) + self.env["ir.config_parameter"].set_param(TRACK_LINKS_PARAMETER, False) + mail = self._send_mail() + # check that the tracking image is present. + self.assertRegex( + str(mail["body"]), + rf"\s*?{str(self.markup)}\s*?" + rf'\s*?', + ) + + def test_enable_links_tracking_only(self): + self.env["ir.config_parameter"].set_param(TRACK_OPEN_PARAMETER, False) + self.env["ir.config_parameter"].set_param(TRACK_LINKS_PARAMETER, True) + mail = self._send_mail() + # check that links are correctly converted. + self.assertRegex( + str(mail["body"]), + rf'this is a link.+?' + "this is not a link: https://odoo-community.org/.+?" + rf'this is a link that ' + "looks like a tracking link", + ) + + def test_enable_tracking(self): + self.env["ir.config_parameter"].set_param(TRACK_OPEN_PARAMETER, True) + self.env["ir.config_parameter"].set_param(TRACK_LINKS_PARAMETER, True) + mail = self._send_mail() + # should work as if the module is not installed. + self.assertRegex( + str(mail["body"]), + rf'this is a link.+?' + "this is not a link: https://odoo-community.org/.+?" + rf'this is a link that ' + r"looks like a tracking link.+?\s*?" + rf'\s*?', + ) diff --git a/mass_mailing_disable_tracking/views/res_config_settings_view.xml b/mass_mailing_disable_tracking/views/res_config_settings_view.xml new file mode 100644 index 0000000000..e6fa2b702b --- /dev/null +++ b/mass_mailing_disable_tracking/views/res_config_settings_view.xml @@ -0,0 +1,46 @@ + + + + + + res.config.settings.view.form.inherit.mass.mailing.disable.tracking + res.config.settings + + + +
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +
From a31fa7ccd310e2d4c6224bd468af0a91a2acc03b Mon Sep 17 00:00:00 2001 From: jeet-dreambits Date: Fri, 17 Jul 2026 11:28:57 +0530 Subject: [PATCH 2/5] [18.0]mig_mass_mailing_disable_tracking:Update Files(add pyprojct.toml) --- mass_mailing_disable_tracking/pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 mass_mailing_disable_tracking/pyproject.toml diff --git a/mass_mailing_disable_tracking/pyproject.toml b/mass_mailing_disable_tracking/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/mass_mailing_disable_tracking/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" From af70d3a1a382d218f36051d2fae44aecf46a71bf Mon Sep 17 00:00:00 2001 From: jeet-dreambits Date: Fri, 17 Jul 2026 11:40:26 +0530 Subject: [PATCH 3/5] [18.0]mig_mass_mailing_disable_tracking:Update Files --- mass_mailing_disable_tracking/README.rst | 82 +++++++++++-------- .../readme/CONTRIBUTORS.md | 1 + .../readme/CONTRIBUTORS.rst | 1 - .../readme/DESCRIPTION.md | 32 ++++++++ .../readme/DESCRIPTION.rst | 15 ---- mass_mailing_disable_tracking/readme/USAGE.md | 9 ++ .../readme/USAGE.rst | 5 -- .../static/description/index.html | 74 ++++++++++------- .../views/res_config_settings_view.xml | 2 - 9 files changed, 136 insertions(+), 85 deletions(-) create mode 100644 mass_mailing_disable_tracking/readme/CONTRIBUTORS.md delete mode 100644 mass_mailing_disable_tracking/readme/CONTRIBUTORS.rst create mode 100644 mass_mailing_disable_tracking/readme/DESCRIPTION.md delete mode 100644 mass_mailing_disable_tracking/readme/DESCRIPTION.rst create mode 100644 mass_mailing_disable_tracking/readme/USAGE.md delete mode 100644 mass_mailing_disable_tracking/readme/USAGE.rst diff --git a/mass_mailing_disable_tracking/README.rst b/mass_mailing_disable_tracking/README.rst index 0fc9abee63..11c9b2521f 100644 --- a/mass_mailing_disable_tracking/README.rst +++ b/mass_mailing_disable_tracking/README.rst @@ -1,7 +1,3 @@ -.. image:: https://odoo-community.org/readme-banner-image - :target: https://odoo-community.org/get-involved?utm_source=readme - :alt: Odoo Community Association - ============================= Mass Mailing Disable Tracking ============================= @@ -17,36 +13,53 @@ Mass Mailing Disable Tracking .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsocial-lightgray.png?logo=github - :target: https://github.com/OCA/social/tree/16.0/mass_mailing_disable_tracking + :target: https://github.com/OCA/social/tree/18.0/mass_mailing_disable_tracking :alt: OCA/social .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/social-16-0/social-16-0-mass_mailing_disable_tracking + :target: https://translation.odoo-community.org/projects/social-18-0/social-18-0-mass_mailing_disable_tracking :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/social&target_branch=16.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/social&target_branch=18.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| -This module allows to disable open and link click tracking in mass mailing messages. - -Odoo Mass Mailing (aka Email Marketing) includes 2 ways of tracking (spying on, invade the privacy of) the recipients: - -1. Tracking the “opening” of the email message by including a 1-pixel transparent GIF image at the bottom of the message, using a URL to the Odoo instance that uniquely identifies that message sent to that recipient. - As soon as the recipient displays the remote images of the message, their email client downloads the tracking image and the Odoo instance knows that that particular recipient opened that particular message. -2. Tracking the “clicks” on the links included in the message by converting all links of the message to a tracking URL to the Odoo instance. - As soon as the recipient clicks one of those links, their browser will make a request to the Odoo instance, which will record that click on that particular link for that particular recipient before redirecting the browser to the original link address. - -This module allows to disable both of these mechanisms by preventing the original email message to be modified by Odoo to include these tracking mechanisms. - -Another issue that link click tracking causes is that recipients are unable to inspect the links: they cannot know on which website they will land before clicking on them. -This, and the fact that they are tracked, can cause some recipients to not click the links, making the mass mailing actually less effective. - -Statistics can be useful, but respecting your recipients’ privacy is important. +This module allows to disable open and link click tracking in mass +mailing messages. + +Odoo Mass Mailing (aka Email Marketing) includes 2 ways of tracking +(spying on, invade the privacy of) the recipients: + +1. Tracking the “opening” of the email message by including a 1-pixel + transparent GIF image at the bottom of the message, using a URL to + the Odoo instance that uniquely identifies that message sent to that + recipient. As soon as the recipient displays the remote images of the + message, their email client downloads the tracking image and the Odoo + instance knows that that particular recipient opened that particular + message. +2. Tracking the “clicks” on the links included in the message by + converting all links of the message to a tracking URL to the Odoo + instance. As soon as the recipient clicks one of those links, their + browser will make a request to the Odoo instance, which will record + that click on that particular link for that particular recipient + before redirecting the browser to the original link address. + +This module allows to disable both of these mechanisms by preventing the +original email message to be modified by Odoo to include these tracking +mechanisms. + +Another issue that link click tracking causes is that recipients are +unable to inspect the links: they cannot know on which website they will +land before clicking on them. This, and the fact that they are tracked, +can cause some recipients to not click the links, making the mass +mailing actually less effective. + +Statistics can be useful, but respecting your recipients’ privacy is +important. **Table of contents** @@ -56,11 +69,16 @@ Statistics can be useful, but respecting your recipients’ privacy is important Usage ===== -By default, just by installing this module, open and link click tracking is disabled for new mass mailings. +By default, just by installing this module, open and link click tracking +is disabled for new mass mailings. -It is still possible to enable each one separately by going to **Settings** > **Email Marketing** and checking the corresponding checkboxes. +It is still possible to enable each one separately by going to +**Settings** > **Email Marketing** and checking the corresponding +checkboxes. -.. note:: This module is incompatible with the ``mail_tracking`` module. +.. note:: + + This module is incompatible with the ``mail_tracking`` module. Bug Tracker =========== @@ -68,7 +86,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -76,17 +94,17 @@ Credits ======= Authors -~~~~~~~ +------- * hugues de keyzer Contributors -~~~~~~~~~~~~ +------------ -* hugues de keyzer +- hugues de keyzer Maintainers -~~~~~~~~~~~ +----------- This module is maintained by the OCA. @@ -106,6 +124,6 @@ Current `maintainer `__: |maintainer-huguesdk| -This module is part of the `OCA/social `_ project on GitHub. +This module is part of the `OCA/social `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/mass_mailing_disable_tracking/readme/CONTRIBUTORS.md b/mass_mailing_disable_tracking/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..1d728f7db1 --- /dev/null +++ b/mass_mailing_disable_tracking/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +- hugues de keyzer diff --git a/mass_mailing_disable_tracking/readme/CONTRIBUTORS.rst b/mass_mailing_disable_tracking/readme/CONTRIBUTORS.rst deleted file mode 100644 index 36e8d00f65..0000000000 --- a/mass_mailing_disable_tracking/readme/CONTRIBUTORS.rst +++ /dev/null @@ -1 +0,0 @@ -* hugues de keyzer diff --git a/mass_mailing_disable_tracking/readme/DESCRIPTION.md b/mass_mailing_disable_tracking/readme/DESCRIPTION.md new file mode 100644 index 0000000000..be1afa357e --- /dev/null +++ b/mass_mailing_disable_tracking/readme/DESCRIPTION.md @@ -0,0 +1,32 @@ +This module allows to disable open and link click tracking in mass +mailing messages. + +Odoo Mass Mailing (aka Email Marketing) includes 2 ways of tracking +(spying on, invade the privacy of) the recipients: + +1. Tracking the “opening” of the email message by including a 1-pixel + transparent GIF image at the bottom of the message, using a URL to + the Odoo instance that uniquely identifies that message sent to that + recipient. As soon as the recipient displays the remote images of + the message, their email client downloads the tracking image and the + Odoo instance knows that that particular recipient opened that + particular message. +2. Tracking the “clicks” on the links included in the message by + converting all links of the message to a tracking URL to the Odoo + instance. As soon as the recipient clicks one of those links, their + browser will make a request to the Odoo instance, which will record + that click on that particular link for that particular recipient + before redirecting the browser to the original link address. + +This module allows to disable both of these mechanisms by preventing the +original email message to be modified by Odoo to include these tracking +mechanisms. + +Another issue that link click tracking causes is that recipients are +unable to inspect the links: they cannot know on which website they will +land before clicking on them. This, and the fact that they are tracked, +can cause some recipients to not click the links, making the mass +mailing actually less effective. + +Statistics can be useful, but respecting your recipients’ privacy is +important. diff --git a/mass_mailing_disable_tracking/readme/DESCRIPTION.rst b/mass_mailing_disable_tracking/readme/DESCRIPTION.rst deleted file mode 100644 index c3cd30efe5..0000000000 --- a/mass_mailing_disable_tracking/readme/DESCRIPTION.rst +++ /dev/null @@ -1,15 +0,0 @@ -This module allows to disable open and link click tracking in mass mailing messages. - -Odoo Mass Mailing (aka Email Marketing) includes 2 ways of tracking (spying on, invade the privacy of) the recipients: - -1. Tracking the “opening” of the email message by including a 1-pixel transparent GIF image at the bottom of the message, using a URL to the Odoo instance that uniquely identifies that message sent to that recipient. - As soon as the recipient displays the remote images of the message, their email client downloads the tracking image and the Odoo instance knows that that particular recipient opened that particular message. -2. Tracking the “clicks” on the links included in the message by converting all links of the message to a tracking URL to the Odoo instance. - As soon as the recipient clicks one of those links, their browser will make a request to the Odoo instance, which will record that click on that particular link for that particular recipient before redirecting the browser to the original link address. - -This module allows to disable both of these mechanisms by preventing the original email message to be modified by Odoo to include these tracking mechanisms. - -Another issue that link click tracking causes is that recipients are unable to inspect the links: they cannot know on which website they will land before clicking on them. -This, and the fact that they are tracked, can cause some recipients to not click the links, making the mass mailing actually less effective. - -Statistics can be useful, but respecting your recipients’ privacy is important. diff --git a/mass_mailing_disable_tracking/readme/USAGE.md b/mass_mailing_disable_tracking/readme/USAGE.md new file mode 100644 index 0000000000..1ec8ab45bb --- /dev/null +++ b/mass_mailing_disable_tracking/readme/USAGE.md @@ -0,0 +1,9 @@ +By default, just by installing this module, open and link click tracking +is disabled for new mass mailings. + +It is still possible to enable each one separately by going to +**Settings** \> **Email Marketing** and checking the corresponding +checkboxes. + +> [!NOTE] +> This module is incompatible with the `mail_tracking` module. diff --git a/mass_mailing_disable_tracking/readme/USAGE.rst b/mass_mailing_disable_tracking/readme/USAGE.rst deleted file mode 100644 index 44fbb348c4..0000000000 --- a/mass_mailing_disable_tracking/readme/USAGE.rst +++ /dev/null @@ -1,5 +0,0 @@ -By default, just by installing this module, open and link click tracking is disabled for new mass mailings. - -It is still possible to enable each one separately by going to **Settings** > **Email Marketing** and checking the corresponding checkboxes. - -.. note:: This module is incompatible with the ``mail_tracking`` module. diff --git a/mass_mailing_disable_tracking/static/description/index.html b/mass_mailing_disable_tracking/static/description/index.html index c99f501f30..e01d4c0775 100644 --- a/mass_mailing_disable_tracking/static/description/index.html +++ b/mass_mailing_disable_tracking/static/description/index.html @@ -3,7 +3,7 @@ -README.rst +Mass Mailing Disable Tracking -
+
+

Mass Mailing Disable Tracking

- - -Odoo Community Association - -
-

Mass Mailing Disable Tracking

-

Beta License: AGPL-3 OCA/social Translate me on Weblate Try me on Runboat

-

This module allows to disable open and link click tracking in mass mailing messages.

-

Odoo Mass Mailing (aka Email Marketing) includes 2 ways of tracking (spying on, invade the privacy of) the recipients:

+

Beta License: AGPL-3 OCA/social Translate me on Weblate Try me on Runboat

+

This module allows to disable open and link click tracking in mass +mailing messages.

+

Odoo Mass Mailing (aka Email Marketing) includes 2 ways of tracking +(spying on, invade the privacy of) the recipients:

    -
  1. Tracking the “opening” of the email message by including a 1-pixel transparent GIF image at the bottom of the message, using a URL to the Odoo instance that uniquely identifies that message sent to that recipient. -As soon as the recipient displays the remote images of the message, their email client downloads the tracking image and the Odoo instance knows that that particular recipient opened that particular message.
  2. -
  3. Tracking the “clicks” on the links included in the message by converting all links of the message to a tracking URL to the Odoo instance. -As soon as the recipient clicks one of those links, their browser will make a request to the Odoo instance, which will record that click on that particular link for that particular recipient before redirecting the browser to the original link address.
  4. +
  5. Tracking the “opening” of the email message by including a 1-pixel +transparent GIF image at the bottom of the message, using a URL to +the Odoo instance that uniquely identifies that message sent to that +recipient. As soon as the recipient displays the remote images of the +message, their email client downloads the tracking image and the Odoo +instance knows that that particular recipient opened that particular +message.
  6. +
  7. Tracking the “clicks” on the links included in the message by +converting all links of the message to a tracking URL to the Odoo +instance. As soon as the recipient clicks one of those links, their +browser will make a request to the Odoo instance, which will record +that click on that particular link for that particular recipient +before redirecting the browser to the original link address.
-

This module allows to disable both of these mechanisms by preventing the original email message to be modified by Odoo to include these tracking mechanisms.

-

Another issue that link click tracking causes is that recipients are unable to inspect the links: they cannot know on which website they will land before clicking on them. -This, and the fact that they are tracked, can cause some recipients to not click the links, making the mass mailing actually less effective.

-

Statistics can be useful, but respecting your recipients’ privacy is important.

+

This module allows to disable both of these mechanisms by preventing the +original email message to be modified by Odoo to include these tracking +mechanisms.

+

Another issue that link click tracking causes is that recipients are +unable to inspect the links: they cannot know on which website they will +land before clicking on them. This, and the fact that they are tracked, +can cause some recipients to not click the links, making the mass +mailing actually less effective.

+

Statistics can be useful, but respecting your recipients’ privacy is +important.

Table of contents

    @@ -401,38 +413,41 @@

    Mass Mailing Disable Tracking

-

Usage

-

By default, just by installing this module, open and link click tracking is disabled for new mass mailings.

-

It is still possible to enable each one separately by going to Settings > Email Marketing and checking the corresponding checkboxes.

+

Usage

+

By default, just by installing this module, open and link click tracking +is disabled for new mass mailings.

+

It is still possible to enable each one separately by going to +Settings > Email Marketing and checking the corresponding +checkboxes.

Note

This module is incompatible with the mail_tracking module.

-

Bug Tracker

+

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -feedback.

+feedback.

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • hugues de keyzer
-

Contributors

+

Contributors

  • hugues de keyzer
-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -442,11 +457,10 @@

Maintainers

promote its widespread use.

Current maintainer:

huguesdk

-

This module is part of the OCA/social project on GitHub.

+

This module is part of the OCA/social project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

-
diff --git a/mass_mailing_disable_tracking/views/res_config_settings_view.xml b/mass_mailing_disable_tracking/views/res_config_settings_view.xml index e6fa2b702b..d0f1473064 100644 --- a/mass_mailing_disable_tracking/views/res_config_settings_view.xml +++ b/mass_mailing_disable_tracking/views/res_config_settings_view.xml @@ -5,7 +5,6 @@ SPDX-FileCopyrightText: 2025 hugues de keyzer SPDX-License-Identifier: AGPL-3.0-or-later --> - - From 59bfd52a517edc59c404cc60a9874766fe03182e Mon Sep 17 00:00:00 2001 From: jeet-dreambits Date: Fri, 17 Jul 2026 13:38:40 +0530 Subject: [PATCH 4/5] [18.0]mig_mass_mailing_disable_tracking:Update Tests Cases File --- .../models/mail_mail.py | 2 +- .../test_mass_mailing_disable_tracking.py | 31 ++++++++++--------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/mass_mailing_disable_tracking/models/mail_mail.py b/mass_mailing_disable_tracking/models/mail_mail.py index 10f2a49c7f..04c0bee2ea 100644 --- a/mass_mailing_disable_tracking/models/mail_mail.py +++ b/mass_mailing_disable_tracking/models/mail_mail.py @@ -25,7 +25,7 @@ def _replace_in_html(self, html, to_replace, value): if not html: return html wrapper = Markup if isinstance(html, Markup) else str - html = tools.ustr(html) + html = str(html or '') return wrapper(html.replace(to_replace, value)) @api.model diff --git a/mass_mailing_disable_tracking/tests/test_mass_mailing_disable_tracking.py b/mass_mailing_disable_tracking/tests/test_mass_mailing_disable_tracking.py index 6a499aa5a6..087a064152 100644 --- a/mass_mailing_disable_tracking/tests/test_mass_mailing_disable_tracking.py +++ b/mass_mailing_disable_tracking/tests/test_mass_mailing_disable_tracking.py @@ -2,6 +2,8 @@ # # SPDX-License-Identifier: AGPL-3.0-or-later +import re + from markupsafe import Markup from odoo import Command @@ -56,11 +58,10 @@ def _send_mail(self): last_mail_id = self._get_last_mail_id() self.test_mailing_mailing.action_send_mail() mail_mail = self._get_new_mail_messages(last_mail_id) - # the tracking image is only added when actually sending the message: - # mail.mail._send_prepare_values() is called and the result is sent - # (but not saved). compute the sent value by ._send_prepare_values() - # directly. - return mail_mail._send_prepare_values() + # the tracking image and link replacement are added while preparing + # the outgoing body. compute the sent body by calling + # _prepare_outgoing_body() directly. + return mail_mail.ensure_one()._prepare_outgoing_body() def test_disable_tracking(self): self.env["ir.config_parameter"].set_param(TRACK_OPEN_PARAMETER, False) @@ -68,7 +69,7 @@ def test_disable_tracking(self): mail = self._send_mail() # nothing should be transformed. this includes links starting with /r/ # that must not get a mailing.track id appended to them. - self.assertRegex(str(mail["body"]), rf"\s*?{str(self.markup)}\s*?") + self.assertRegex(str(mail), rf"\s*?{str(self.markup)}\s*?") def test_disable_tracking_with_special_links(self): self.env["ir.config_parameter"].set_param(TRACK_OPEN_PARAMETER, False) @@ -83,14 +84,14 @@ def test_disable_tracking_with_special_links(self): # unsubscribe and view links should still be converted and local links # should become full urls. self.assertRegex( - str(mail["body"]), - rf"\s*?{str(self.markup)}" - rf'

' + str(mail), + rf"(?s).*?{re.escape(str(self.markup))}" + rf".*?

" "this is an unsubscribe link

" - rf'

' + rf".*?

" "this is a view link

" - f'

' - rf"this is a local link

\s*?", + rf".*?

" + "this is a local link

.*?", ) def test_enable_open_tracking_only(self): @@ -99,7 +100,7 @@ def test_enable_open_tracking_only(self): mail = self._send_mail() # check that the tracking image is present. self.assertRegex( - str(mail["body"]), + str(mail), rf"\s*?{str(self.markup)}\s*?" rf'\s*?', ) @@ -110,7 +111,7 @@ def test_enable_links_tracking_only(self): mail = self._send_mail() # check that links are correctly converted. self.assertRegex( - str(mail["body"]), + str(mail), rf'this is a link.+?' "this is not a link: https://odoo-community.org/.+?" rf'this is a link that ' @@ -123,7 +124,7 @@ def test_enable_tracking(self): mail = self._send_mail() # should work as if the module is not installed. self.assertRegex( - str(mail["body"]), + str(mail), rf'this is a link.+?' "this is not a link: https://odoo-community.org/.+?" rf'this is a link that ' From 312088048700f839e352b8c4abb4ce340b54c040 Mon Sep 17 00:00:00 2001 From: jeet-dreambits Date: Fri, 17 Jul 2026 13:43:14 +0530 Subject: [PATCH 5/5] [18.0]mig_mass_mailing_disable_tracking:Update mail_mail.py file code --- mass_mailing_disable_tracking/models/mail_mail.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mass_mailing_disable_tracking/models/mail_mail.py b/mass_mailing_disable_tracking/models/mail_mail.py index 04c0bee2ea..0088c8bd27 100644 --- a/mass_mailing_disable_tracking/models/mail_mail.py +++ b/mass_mailing_disable_tracking/models/mail_mail.py @@ -25,7 +25,7 @@ def _replace_in_html(self, html, to_replace, value): if not html: return html wrapper = Markup if isinstance(html, Markup) else str - html = str(html or '') + html = str(html or "") return wrapper(html.replace(to_replace, value)) @api.model