Skip to content

Commit

Permalink
[ADD] mail_chatter_statistics
Browse files Browse the repository at this point in the history
  • Loading branch information
unaiberis committed Oct 23, 2024
1 parent 54f3a48 commit 0905137
Show file tree
Hide file tree
Showing 12 changed files with 205 additions and 0 deletions.
2 changes: 2 additions & 0 deletions mail_chatter_statistics/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import controllers
from . import models
16 changes: 16 additions & 0 deletions mail_chatter_statistics/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "Mail Chatter Statistics",
"version": "14.0.1.0.0",
"author": "Avanzosc",
"summary": "Add email tracking functionality to Odoo chatter.",
"website": "https://github.com/avanzosc/odoo-addons",
"license": "LGPL-3",
"depends": ["mail", "mass_mailing"],
"data": [
"views/mailing_trace_views.xml",
"views/mail_mail_views.xml",
],
"qweb": ["views/chatter_inherit.xml"],
"installable": True,
"application": False,
}
1 change: 1 addition & 0 deletions mail_chatter_statistics/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import mail_track
16 changes: 16 additions & 0 deletions mail_chatter_statistics/controllers/mail_track.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from odoo.http import Controller, request, route


class MailTrackController(Controller):
@route("/mail/track/click/<int:trace_id>", type="http", auth="public", website=True)
def track_click(self, trace_id, redirect_url=None, **kwargs):
"""
Logs the click event and redirects the user to the original URL
"""
trace = request.env["mailing.trace"].sudo().browse(trace_id)
if trace:
trace.write({"status": "clicked"})

if redirect_url:
return request.redirect(redirect_url)
return request.redirect("/")
2 changes: 2 additions & 0 deletions mail_chatter_statistics/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import mail_mail
from . import mailing_trace
46 changes: 46 additions & 0 deletions mail_chatter_statistics/models/mail_mail.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from bs4 import BeautifulSoup
from werkzeug.urls import url_quote

from odoo import models


class MailMail(models.Model):
_inherit = "mail.mail"

def send(self, auto_commit=False, raise_exception=False):
res = super().send(auto_commit=auto_commit, raise_exception=raise_exception)

for mail in self:
if not mail.email_to: # Check if email_to is not empty
continue # Skip creating a trace if there's no email address

trace = self.env["mailing.trace"].create(
{
"mail_message_id": mail.id,
"email": mail.email_to,
"message_id": mail.message_id,
}
)
mail.body_html = self._add_tracking(mail.body_html, trace.id)
trace.write({"status": "tracking_added"})

return res

def _add_tracking(self, body_html, trace_id):
tracking_pixel = f'<img src="/mail/track/open/{trace_id}" \
width="1" height="1" style="display:none"/>'
body_html = body_html.replace("</body>", f"{tracking_pixel}</body>")
body_html = self._replace_links_with_tracked(body_html, trace_id)
return body_html

def _replace_links_with_tracked(self, body_html, trace_id):
soup = BeautifulSoup(body_html, "html.parser")

for a_tag in soup.find_all("a", href=True):
original_url = a_tag["href"]
tracked_url = (
f"/mail/track/click/{trace_id}?redirect_url={url_quote(original_url)}"
)
a_tag["href"] = tracked_url

return str(soup)
52 changes: 52 additions & 0 deletions mail_chatter_statistics/models/mailing_trace.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from odoo import api, fields, models


class MailingTrace(models.Model):
_inherit = "mailing.trace"

mail_message_id = fields.Many2one(
"mail.message",
string="Chatter Message",
help="The chatter message related to this email trace.",
)

mail_message_id_int = fields.Integer(
string="Chatter ID (tech)",
help="ID of the related mail_message. This field is an integer field because "
"the related mail_message can be deleted separately from its statistics. "
"However the ID is needed for several action and controllers.",
index=True,
)

email = fields.Char(string="Email", required=True)
message_id = fields.Char(string="Message ID", required=True)
status = fields.Selection(
[
("draft", "Draft"),
("tracking_added", "Tracking Added"),
("sent", "Sent"),
],
string="Status",
default="draft",
)

@api.model_create_multi
def create(self, values_list):
for values in values_list:
if "mail_message_id" in values:
values["mail_message_id_int"] = values["mail_message_id"]
return super(MailingTrace, self).create(values_list)

def _get_records(self, mail_mail_ids=None, mail_message_ids=None, domain=None):
base_domain = []
if not self.ids and mail_mail_ids:
base_domain = [("mail_mail_id_int", "in", mail_mail_ids)]
elif not self.ids and mail_message_ids:
base_domain = [("mail_message_id_int", "in", mail_message_ids)]
else:
base_domain = [("id", "in", self.ids)]

if domain:
base_domain = ["&"] + domain + base_domain

return self.search(base_domain)
36 changes: 36 additions & 0 deletions mail_chatter_statistics/views/chatter_inherit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="mail_chatter_statistics.ChatterContainer" t-inherit="mail.ChatterContainer" t-extension-mode="extension" owl="1">
<xpath expr="//div[hasclass('o_ChatterContainer')]" position="after">
<div>
<p>PRUEBAAA - ChatterContainer después</p>
</div>
</xpath>
<xpath expr="//h2[contains(@class, 'o_ChatterTitle')]" position="inside">
<span>Nueva Sección en el Título</span>
</xpath>
<xpath expr="//div[@class='o_ChatterFooter']" position="before">
<div>
<p>PRUEBAAA - Antes del pie de ChatterContainer</p>
</div>
</xpath>
</t>

<t t-name="mail_chatter_statistics.Chatter" t-inherit="mail.Chatter" owl="1">
<xpath expr="//div[hasclass('o_Chatter')]" position="after">
<div>
<p>PRUEBAAA - Chatter después</p>
</div>
</xpath>
<xpath expr="//div[@class='o_ChatterHeader']" position="inside">
<div>
<p>Contenido en el encabezado de Chatter</p>
</div>
</xpath>
<xpath expr="//button[@class='o_send']" position="before">
<div>
<p>PRUEBAAA - Antes del botón Enviar</p>
</div>
</xpath>
</t>
</templates>
18 changes: 18 additions & 0 deletions mail_chatter_statistics/views/mail_mail_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="view_mail_form_inherit_chatter_stats" model="ir.ui.view">
<field name="name">mail.mail.form.view.stats</field>
<field name="model">mail.mail</field>
<field name="inherit_id" ref="mail.view_mail_form" />
<field name="arch" type="xml">
<xpath expr="//header" position="inside">
<button
name="%(action_show_tracking)d"
string="Show Email Tracking"
type="action"
class="btn-primary"
/>
</xpath>
</field>
</record>
</odoo>
9 changes: 9 additions & 0 deletions mail_chatter_statistics/views/mailing_trace_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="action_show_tracking" model="ir.actions.act_window">
<field name="name">Email Tracking</field>
<field name="res_model">mailing.trace</field>
<field name="view_mode">tree,form</field>
<field name="target">new</field>
</record>
</odoo>
6 changes: 6 additions & 0 deletions setup/mail_chatter_statistics/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import setuptools

setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)

0 comments on commit 0905137

Please sign in to comment.