Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
106 commits
Select commit Hold shift + click to select a range
a149d78
[8.0][ADD] mail_tracking addon (#67)
antespi Jun 14, 2016
da3517a
[8.0][IMP][mail_tracking] Speed installation time and discard concurr…
antespi Sep 9, 2016
fe85410
[FIX] Update email_score when email changes
antespi Sep 9, 2016
72706f4
[MIG] mail_tracking
antespi Sep 9, 2016
e795a03
[FIX] mail_tracking: Typo
pedrobaeza Sep 29, 2016
c1221bd
[MIG] Make modules uninstallable
pedrobaeza Oct 6, 2016
fd35461
[MIG] mail_tracking: Migrated to 10.0
bouvyd Oct 14, 2016
f3843ef
[IMP] mail_tracking performance and bounce process (#103)
antespi Oct 14, 2016
05674a7
[IMP] mail_tracking: Allow to define a custom mail_tracking base url
antespi Oct 14, 2016
32bdda8
Add access to portal/public user to his own email trackings
antespi Oct 24, 2016
a3c3731
[8.0][FIX][mail_tracking] Use event recipient address to find partner…
antespi Nov 25, 2016
46a53c5
[9.0][FIX][mail_tracking] Control exception when mail_message was rem…
antespi Nov 22, 2016
18b84e4
[FIX] Sender label is repeated in search fields
antespi Nov 2, 2016
c4fb673
[FIX][9.0] partner buttons view on enterprise
jjscarafia Dec 14, 2016
335d54d
[FIX] mail_tracking: Obtain outgoing server with sudo
pedrobaeza Feb 10, 2017
147e0a1
[IMP] Shut mock exceptions up
chienandalu Jul 14, 2017
cc8e43f
[9.0][IMP] mail_tracking: Improve view with error details
carlosdauden Feb 8, 2017
45f66d2
[FIX] mail_tracking: bugfixes (#199)
antespi Oct 10, 2017
71936ef
IMP mail_tracking performances
eLBati Feb 21, 2018
52233d1
[FIX] mail_tracking js could break other modules using chat_manager
ecino Apr 13, 2018
7475a1a
[MIG] mail_tracking: Migration to 11.0
chienandalu Mar 19, 2018
bb5b038
Translated using Weblate (French) [ci skip]
didierdonze Jun 18, 2018
d64daab
[IMP] mail_tracking: email score performance (#299)
chienandalu Sep 6, 2018
7bc8908
Fix README.rst images not visible in GitHub and Odoo
bitroniq Sep 18, 2018
df2472a
[IMP] mail_tracking: Put button box at the end of the view
pedrobaeza Sep 24, 2018
b88e8cf
Translated using Weblate (Catalan)
eduardgm Oct 10, 2018
c2b058c
[MIG] mail_tracking: Migration to 12.0
ernestotejeda Nov 5, 2018
072a49c
[FIX] mail_tracking: Don't call write inside other write
pedrobaeza Jun 26, 2019
ec9776f
[IMP] mail_tracking: Cc
Tardo Jul 3, 2019
682c813
[MIG] mail_tracking: Adapt Cc to 12.0
Tardo Jul 3, 2019
69d7b5d
[FIX] Bug {TypeError: dict.message.hasEmailCc is not a function} duri…
EgorSummer Jul 22, 2019
a50963d
[FIX] mail_tracking: Repeated suggested cc emails
Tardo Jul 22, 2019
092cc68
[IMP] mail_tracking: Adapt test to set (not order preserved)
Tardo Jul 22, 2019
a08d8dc
[FIX] mail_tracking: Show correctly blank image
pedrobaeza Jul 24, 2019
3781b2f
Translated using Weblate (Spanish)
eduardgm Aug 4, 2019
df3711a
[IMP] mail_tracking: mail.thread filter for tracking errors
chienandalu Jul 5, 2019
32416c8
[IMP] mail_tracking: Cc name & check if mail is Cc
Tardo Jul 23, 2019
0a0c11f
[IMP] mail_tracking: Convert 'partner_trackings' to dict
Tardo Aug 12, 2019
e133c31
[IMP] mail_tracking: translations
Tardo Aug 12, 2019
ce8315e
[IMP] mail_tracking: Failed Messages to 12.0
Tardo Oct 17, 2019
77c12ba
[FIX] mail_tracking: Refresh thread widget when sets a message as rev…
Tardo Nov 14, 2019
ef4a6bf
[IMP] mail_tracking: black, isort
Tardo Nov 18, 2019
74a9603
[MIG] mail_tracking: Migration to 13.0
Tardo Nov 18, 2019
18ee631
[FIX] mail_tracking: Changed injection method for 'failed_message_ids…
Tardo Nov 28, 2019
066be6e
[FIX] mail_tracking: do not warn not found if already opened
ruuter Mar 30, 2020
b4b0902
[IMP] mail_tracking: Store To recipients and omit aliases
Tardo Mar 19, 2020
2a53e0d
[IMP] mail_tracking: Test 'to' and named emails
Tardo Mar 26, 2020
f1de1c5
[IMP] mail_tracking: Ignore catchall
Tardo Apr 16, 2020
40a59f7
[FIX] re.search will return None when nothing found. So we have to ch…
wpichler Oct 23, 2020
fc03571
[FIX] mail_tracking
nmadhoc Jan 21, 2021
27a46dc
[IMP] Apply pre-commit changes: Resolve conflicts
Tardo Jan 26, 2021
73879b1
[IMP] mail_tracking: Discuss failed messages: Button and domain + Onl…
Tardo Oct 2, 2020
c083f43
[FIX] mail_tracking: Store cc
Tardo Mar 1, 2021
08f7930
[IMP] mail_tracking: black, isort, prettier
AreebSiddiqiIR May 3, 2021
a859959
[MIG] mail_tracking: Migration to 14.0
AreebSiddiqiIR May 3, 2021
098d1e9
[14.0][MIG] mail_tracking
SimoneVagile Jun 25, 2021
2c32149
[FIX] mail_tracking: Modification in unitest.
angelJuaGar Jun 29, 2021
25d5629
[FIX] mail_tracking: reduce spammy score
Jul 9, 2021
1a7a496
[FIX] mail_tracking: Added restriction on email search.
angelJuaGar Aug 13, 2021
978955b
[FIX] Change operator to 'ilike'
JorgeQuinteros Sep 22, 2021
9fcac86
[PORT] porting js code to comply with OWL
houssine78 Oct 27, 2021
aea13c7
[FIX] mail_tracking: use recipient_address to search emails
fernandahf Nov 24, 2021
c51ccc9
[FIX] mail_tracking: change order of inheritance and use return
fernandahf Jan 12, 2022
73dfb34
[IMP] mail_tracking: black, isort, prettier
JasminSForgeFlow Mar 24, 2022
42711dd
[MIG] mail_tracking: Migration to 15.0
JasminSForgeFlow Mar 25, 2022
ca1f755
[FIX] mail_tracking: mixed classes
chienandalu Jan 30, 2023
a246f53
[IMP] mail_tracking_mailgun: mass mailing manual tracking
chienandalu Jan 12, 2023
bf9c822
[FIX] mail_tracking: process sent events
Oct 11, 2021
9d26c76
[FIX] mail_tracking: error when filtering by "Sent"
sugapablo Feb 17, 2022
ec9dc1c
[FIX] mail_tracking: permissions
chienandalu Sep 7, 2022
5a6d1f9
[IMP] mail_tracking: remove legacy hooks
Jul 27, 2022
187e6d4
[FIX] mail_tracking: js linter warnings
chienandalu Jan 31, 2023
2427a36
use keyword arguments in build_email to comply with portal tests
jonasbuchholz Feb 9, 2023
c303abd
[FIX] mail_tracking: Crash to add malformed emails to recipients sugg…
sergio-teruel Feb 23, 2023
b409a34
[UPD] Update mail_tracking.pot
Mar 23, 2023
8ff452c
Fix mail tracking bounce notification not logged
TDu May 3, 2023
4745e25
[FIX] mail_tracking: thread permissions
chienandalu May 9, 2023
79c9609
[FIX] mail_tracking: allowed trackings compute
chienandalu May 22, 2023
723780e
[IMP] mail_tracking: New config parameter to disable the tracking image
dhx May 29, 2023
3f1fe26
[FIX] mail_tracking: failed messages in thread
chienandalu Aug 9, 2023
78b4c55
[MIG] mail_tracking: Migration to 16.0
filoquin Mar 2, 2023
5f20bb5
[MIG] mail_tracking: Completed migration to 16.0
payen000 Sep 4, 2023
a02dbfe
[FIX] mail_tracking: validated mailbox when computing isInFailedDiscuss
payen000 Oct 16, 2023
3d50871
[16.0][FIX] mail_tracking debug mode error
NiChrDeuse Dec 15, 2023
966e591
[IMP] mail_tracking: Give example that actually works in readme
hbrunn Mar 18, 2024
4c366a7
[FIX] mail_tracking: be closer to what Odoo does in a nodb environment
hbrunn Mar 18, 2024
29e1156
[IMP] mail_tracking: pre-commit auto fixes
pedrobaeza Jun 11, 2024
c52d8d0
[MIG] mail_tracking: Migration to 17.0
chienandalu May 14, 2024
5d63edb
[IMP] Add option to keep aliases in mail tracking
cvinh Jul 26, 2022
aefee65
mail_tracking: add garbage collection
henrybackman Aug 14, 2024
dc39529
[FW] port missing commits from 14.0 to 17.0
trisdoan Oct 3, 2024
0d7f3ec
[IMP] mail_tracking: pre-commit auto fixes
trisdoan Oct 3, 2024
edc0664
[MIG] mail_tracking: Migration to 18.0
trisdoan Sep 27, 2024
05e6ef5
[FIX] mail_tracking: python warning deprecated utcfromtimestamp
augusto-weiss May 21, 2025
8dd6416
[FIX] mail_tracking: Apply read restrictions to everyone not being su…
grindtildeath Jun 30, 2025
4526774
[FIX] mail_tracking: missing onUpdate prop
ivantodorovich Sep 4, 2025
e103387
[IMP] mail_tracking: remove dead `failure_count` code
ivantodorovich Sep 8, 2025
74fd98d
[IMP] mail_tracking: create all mail.tracking.email at once
ivantodorovich Sep 8, 2025
e42ac63
[IMP] mail_tracking: remove dead mail.tracking.email.event_process me…
ivantodorovich Sep 8, 2025
94379eb
[IMP] mail_tracking: use env-aware gettext self.env._ everywhere
ivantodorovich Sep 8, 2025
4e44b7c
[IMP] mail_tracking: remove redundant ui FailedMessagePanel
ivantodorovich Sep 8, 2025
2e87b83
[FIX] mail_tracking: ACL verification
remi-filament Oct 22, 2025
b2fda33
[FIX] mail_tracking: Prevent error when the SQL result is empty.
carlos-lopez-tecnativa Nov 25, 2025
311a7e2
[FIX] mail_tracking: Error on tabs without thread open when marking a…
CarlosRoca13 Dec 23, 2025
8ab08a4
[IMP] mail_tracking: pre-commit auto fixes
quoc-pn Feb 3, 2026
468d3ca
[MIG] mail_tracking: Migration to 19.0
quoc-pn Feb 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
203 changes: 203 additions & 0 deletions mail_tracking/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association

==============
Email tracking
==============

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:db328da6c6862a0a974ae2259d6ec0106efc220892bb703f7429abf16f8f7851
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |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%2Fmail-lightgray.png?logo=github
:target: https://github.com/OCA/mail/tree/19.0/mail_tracking
:alt: OCA/mail
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/mail-19-0/mail-19-0-mail_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/mail&target_branch=19.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module shows email notification tracking status for any messages in
mail thread (chatter). Each notified partner will have an intuitive icon
just right to his name.

**Table of contents**

.. contents::
:local:

Installation
============

If you're using a multi-database installation (with or without dbfilter
option) where /web/databse/selector returns a list of more than one
database, then you need to add ``mail_tracking`` addon to wide load
addons list (by default, only ``web`` addon), setting ``--load`` option.
For example, ``--load=web,mail,mail_tracking``

Configuration
=============

As there can be scenarios where sending a tracking img in the email body
is not desired, there is a global system parameter
"mail_tracking.tracking_img_disabled" that can be set to True to remove
the tracking img from all outgoing emails. Note that the **Opened**
status will not be available in this case.

Usage
=====

When user sends a message in mail_thread (chatter), for instance in
partner form, then an email tracking is created for each email
notification. Then a status icon will appear just right to name of
notified partner.

These are all available status icons:

|unknown| **Unknown**: No email tracking info available. Maybe this
notified partner has 'Receive Inbox Notifications by Email' == 'Never'

|waiting| **Waiting**: Waiting to be sent

|error| **Error**: Error while sending

|sent| **Sent**: Sent to SMTP server configured

|delivered| **Delivered**: Delivered to final MX server

|opened| **Opened**: Opened by partner

|cc| **Cc**: It's a Carbon-Copy recipient. Can't know the status so is
'Unknown'

|noemail| **No Email**: The partner doesn't have a defined email

|anonuser| **No Partner**: The recipient doesn't have a defined partner

If you want to see all tracking emails and events you can go to

- Settings > Technical > Email > Tracking emails
- Settings > Technical > Email > Tracking events

When the message generates an 'error' status, it will apear on discuss
'Failed' channel. Any view with chatter can show the failed messages
too.

- Discuss

|image|

- Chatter

|image1|

You can use "Failed sent messages" filter present in all views to show
records with messages in failed status and that needs an user action.

- Filter

|image2|

.. |unknown| image:: https://raw.githubusercontent.com/OCA/mail/19.0/mail_tracking/static/src/img/unknown.png
.. |waiting| image:: https://raw.githubusercontent.com/OCA/mail/19.0/mail_tracking/static/src/img/waiting.png
.. |error| image:: https://raw.githubusercontent.com/OCA/mail/19.0/mail_tracking/static/src/img/error.png
.. |sent| image:: https://raw.githubusercontent.com/OCA/mail/19.0/mail_tracking/static/src/img/sent.png
.. |delivered| image:: https://raw.githubusercontent.com/OCA/mail/19.0/mail_tracking/static/src/img/delivered.png
.. |opened| image:: https://raw.githubusercontent.com/OCA/mail/19.0/mail_tracking/static/src/img/opened.png
.. |cc| image:: https://raw.githubusercontent.com/OCA/mail/19.0/mail_tracking/static/src/img/cc.png
.. |noemail| image:: https://raw.githubusercontent.com/OCA/mail/19.0/mail_tracking/static/src/img/no_email.png
.. |anonuser| image:: https://raw.githubusercontent.com/OCA/mail/19.0/mail_tracking/static/src/img/anon_user.png
.. |image| image:: https://raw.githubusercontent.com/OCA/mail/19.0/mail_tracking/static/img/failed_message_discuss.png
.. |image1| image:: https://raw.githubusercontent.com/OCA/mail/19.0/mail_tracking/static/img/failed_message_widget.png
.. |image2| image:: https://raw.githubusercontent.com/OCA/mail/19.0/mail_tracking/static/img/failed_message_filter.png

Known issues / Roadmap
======================

- Integrate with the core ``mail.notification`` model as it overlaps
with what the ``mail.tracking`` model does. We could add the existing
features on top of that model and save lots of code lines.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/mail/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 <https://github.com/OCA/mail/issues/new?body=module:%20mail_tracking%0Aversion:%2019.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

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

Credits
=======

Authors
-------

* Tecnativa

Contributors
------------

- `Tecnativa <https://www.tecnativa.com>`__:

- Pedro M. Baeza
- Antonio Espinosa
- David Vidal
- Ernesto Tejeda
- Rafael Blasco
- Alexandre Díaz

- `Eezee-IT <https://www.eezee-it.com>`__:

- Asma Elferkhsi

- `Vauxoo <https://www.vauxoo.com>`__:

- Agustín Payen Sandoval

- `Trobz <https://www.trobz.com>`__:

- Tris Doan

- `Komit <https://komit-consulting.com>`__:

- Quoc Pham Ngoc

Other credits
-------------

The migration of this module from 17.0 to 18.0 was financially supported
by Camptocamp.

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.

This module is part of the `OCA/mail <https://github.com/OCA/mail/tree/19.0/mail_tracking>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
2 changes: 2 additions & 0 deletions mail_tracking/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import controllers
from . import models
40 changes: 40 additions & 0 deletions mail_tracking/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright 2016 Tecnativa - Antonio Espinosa
# Copyright 2018 Tecnativa - David Vidal
# Copyright 2018 Tecnativa - Ernesto Tejeda
# Copyright 2019 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

{
"name": "Email tracking",
"summary": "Email tracking system for all mails sent",
"version": "19.0.1.0.0",
"category": "Social Network",
"website": "https://github.com/OCA/mail",
"author": ("Tecnativa, Odoo Community Association (OCA)"),
"license": "AGPL-3",
"application": False,
"installable": True,
"depends": ["mail"],
"data": [
"data/tracking_data.xml",
"security/mail_tracking_email_security.xml",
"security/ir.model.access.csv",
"views/mail_tracking_email_view.xml",
"views/mail_tracking_event_view.xml",
"views/mail_message_view.xml",
"views/res_partner_view.xml",
"views/res_config_settings.xml",
],
"assets": {
"web.assets_backend": [
"mail_tracking/static/src/core/chatter/*",
"mail_tracking/static/src/core/message/*",
"mail_tracking/static/src/core/discuss/*",
"mail_tracking/static/src/services/*",
"mail_tracking/static/src/components/message_tracking/*",
"mail_tracking/static/src/components/failed_message/*",
"mail_tracking/static/src/components/failed_message_review/*",
],
},
"demo": ["demo/demo.xml"],
}
2 changes: 2 additions & 0 deletions mail_tracking/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import main
from . import mailbox
28 changes: 28 additions & 0 deletions mail_tracking/controllers/mailbox.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright 2024 Tecnativa - David Vidal
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from odoo.http import request, route

from odoo.addons.mail.controllers.mailbox import MailboxController
from odoo.addons.mail.tools.discuss import Store


class MailTrackingMailBoxController(MailboxController):
@route("/mail/failed/messages", methods=["POST"], type="jsonrpc", auth="user")
def discuss_failed_messages(
self, search_term=None, before=None, after=None, limit=30, around=None
):
"""Fetch failed messages for discuss"""
res = request.env["mail.message"]._message_fetch(
[("is_failed_message", "=", True)],
search_term=search_term,
before=before,
after=after,
around=around,
limit=limit,
)
messages = res.pop("messages")
return {
**res,
"data": Store().add(messages).get_result(),
"messages": messages.ids,
}
76 changes: 76 additions & 0 deletions mail_tracking/controllers/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

import base64
import logging
from contextlib import contextmanager

import werkzeug

import odoo
from odoo import SUPERUSER_ID, api, http

from odoo.addons.mail.controllers.mail import MailController

_logger = logging.getLogger(__name__)

BLANK = "R0lGODlhAQABAIAAANvf7wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="


@contextmanager
def db_env(dbname):
if not http.db_filter([dbname]):
raise werkzeug.exceptions.BadRequest()
cr = None
if dbname == http.request.db:
cr = http.request.cr
if not cr:
cr = odoo.sql_db.db_connect(dbname).cursor()
yield api.Environment(cr, SUPERUSER_ID, {})


class MailTrackingController(MailController):
def _request_metadata(self):
"""Prepare remote info metadata"""
request = http.request.httprequest
return {
"ip": request.remote_addr or False,
"user_agent": request.user_agent or False,
"os_family": request.user_agent.platform or False,
"ua_family": request.user_agent.browser or False,
}

@http.route(
[
"/mail/tracking/open/<string:db>/<int:tracking_email_id>/blank.gif",
"/mail/tracking/open/<string:db>"
"/<int:tracking_email_id>/<string:token>/blank.gif",
],
type="http",
auth="none",
methods=["GET"],
)
def mail_tracking_open(self, db, tracking_email_id, token=False, **kw):
"""Route used to track mail openned (With & Without Token)"""
metadata = self._request_metadata()
with db_env(db) as env:
try:
tracking_email = (
env["mail.tracking.email"]
.sudo()
.search([("id", "=", tracking_email_id), ("token", "=", token)])
)
if not tracking_email:
_logger.warning(
"MailTracking email '%s' not found", tracking_email_id
)
elif tracking_email.state in ("sent", "delivered"):
tracking_email.event_create("open", metadata)
except Exception as e:
_logger.warning(e)

# Always return GIF blank image
response = werkzeug.wrappers.Response()
response.mimetype = "image/gif"
response.data = base64.b64decode(BLANK)
return response
13 changes: 13 additions & 0 deletions mail_tracking/data/tracking_data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
<odoo>
<record
forcecreate="True"
id="decimal_tracking_timestamp"
model="decimal.precision"
>
<field name="name">MailTracking Timestamp</field>
<field name="digits">6</field>
</record>
</odoo>
Loading