Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
60 changes: 60 additions & 0 deletions mail_channel_notify_tag/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
.. image:: https://img.shields.io/badge/licence-LGPL--3-blue.svg
:alt: License: LGPL-3

Mail Channel Notify Tag
=======================

This module re-enables sending messages to channels and their members
when the channels are mentioned in the messages of the records.

Message in the record:

.. image:: ../mail_channel_notify_tag/static/description/record.png
:alt: Message in the record
:width: 1200px

Message in the channel:

.. image:: ../mail_channel_notify_tag/static/description/channel.png
:alt: Message in the channel
:width: 1200px

Email:

.. image:: ../mail_channel_notify_tag/static/description/email.png
:alt: Email
:width: 1200px

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

Bugs are tracked on `GitHub Issues
<https://github.com/Vauxoo/addons-vauxoo/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smashing it by providing a detailed and welcomed `feedback
<https://github.com/vauxoo/
addons-vauxoo/issues/new?body=module:%20
mail_channel_notify_tag%0Aversion:%20
16.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

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

* Luis González <lgonzalez@vauxoo.com>
* Rolando Duarte <rolando@vauxoo.com>

Maintainer
----------

.. image:: https://www.vauxoo.com/logo.png
:alt: Vauxoo
:target: https://vauxoo.com

This module is maintained by Vauxoo.

A latinamerican company that provides training, coaching,
development and implementation of enterprise management
systems and bases its entire operation strategy in the use
of Open Source Software and its main product is odoo.

To contribute to this module, please visit https://www.vauxoo.com.
1 change: 1 addition & 0 deletions mail_channel_notify_tag/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
26 changes: 26 additions & 0 deletions mail_channel_notify_tag/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "Mail Channel Notify Tag",
"summary": "Module to notify the channels when they are mentioned in the chatter",
"author": "Vauxoo",
"website": "https://www.vauxoo.com",
"license": "LGPL-3",
"category": "Productivity/Discuss",
"version": "19.0.1.0.0",
"depends": [
"mail",
],
"data": [
"views/mail_templates.xml",
],
"assets": {
"web.assets_backend": [
"mail_channel_notify_tag/static/src/core/store_service_patch.js",
],
"mail.assets_discuss_public": [
"mail_channel_notify_tag/static/src/core/store_service_patch.js",
],
},
"installable": True,
"auto_install": False,
"application": False,
}
43 changes: 43 additions & 0 deletions mail_channel_notify_tag/i18n/es.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * mail_channel_notify_tag
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 19.0+e\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-29 04:37+0000\n"
"PO-Revision-Date: 2026-04-29 04:37+0000\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: mail_channel_notify_tag
#: model:ir.model.fields,field_description:mail_channel_notify_tag.field_mail_followers__display_name
#: model:ir.model.fields,field_description:mail_channel_notify_tag.field_mail_thread__display_name
msgid "Display Name"
msgstr "Nombre para mostrar"

#. module: mail_channel_notify_tag
#: model:ir.model,name:mail_channel_notify_tag.model_mail_followers
msgid "Document Followers"
msgstr "Seguidores del documento"

#. module: mail_channel_notify_tag
#: model:ir.model,name:mail_channel_notify_tag.model_mail_thread
msgid "Email Thread"
msgstr "Hilo de correo electrónico"

#. module: mail_channel_notify_tag
#: model:ir.model.fields,field_description:mail_channel_notify_tag.field_mail_followers__id
#: model:ir.model.fields,field_description:mail_channel_notify_tag.field_mail_thread__id
msgid "ID"
msgstr ""

#. module: mail_channel_notify_tag
#: model_terms:ir.ui.view,arch_db:mail_channel_notify_tag.mail_channel_message_repost
msgid "on"
msgstr "en"
2 changes: 2 additions & 0 deletions mail_channel_notify_tag/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import mail_followers
from . import mail_thread
14 changes: 14 additions & 0 deletions mail_channel_notify_tag/models/mail_followers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from odoo import models


class MailFollowers(models.Model):
_inherit = "mail.followers"

def _get_recipient_data(self, records, message_type, subtype_id, pids=None):
"""Add channel members as email recipients when channels are mentioned."""
channel_ids = self.env.context.get("mentioned_channel_ids")
if not channel_ids:
return super()._get_recipient_data(records, message_type, subtype_id, pids)
pids = set(pids) if pids else set()
pids |= set(self.env["discuss.channel"].sudo().browse(channel_ids).channel_partner_ids.ids)
return super()._get_recipient_data(records, message_type, subtype_id, pids)
40 changes: 40 additions & 0 deletions mail_channel_notify_tag/models/mail_thread.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from odoo import models


class MailThread(models.AbstractModel):
_inherit = "mail.thread"

def _get_allowed_message_params(self):
"""Allow channel_ids to pass through the controller whitelist."""
return super()._get_allowed_message_params() | {"channel_ids"}

def message_post(self, *, body="", **kwargs):
"""Extract channel_ids before they reach the parent validation."""
channel_ids = kwargs.pop("channel_ids", [])
self = self.with_context(mentioned_channel_ids=channel_ids)
return super().message_post(body=body, **kwargs)

def _message_post_after_hook(self, message, msg_values):
"""Repost message to mentioned channels after the message is created."""
result = super()._message_post_after_hook(message, msg_values)
channel_ids = self.env.context.get("mentioned_channel_ids")
if channel_ids:
self._notify_mentioned_channels(message, channel_ids)
return result

def _notify_mentioned_channels(self, message, channel_ids):
"""Repost the message to mentioned channels for Discuss visibility.

Email notifications to channel members are handled separately by
mail_followers._get_recipient_data on the source record.
"""
channels = self.env["discuss.channel"].sudo().browse(channel_ids).exists()
if not channels:
return
template = self.env.ref("mail_channel_notify_tag.mail_channel_message_repost")
channels.message_post_with_source(
template,
render_values={"message": message, "source": self},
message_type="comment",
subtype_xmlid="mail.mt_comment",
)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions mail_channel_notify_tag/static/src/core/store_service_patch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {Store} from "@mail/core/common/store_service";
import {patch} from "@web/core/utils/patch";

patch(Store.prototype, {
async getMessagePostParams({postData}) {
const params = await super.getMessagePostParams(...arguments);
const channelIds = (postData.mentionedChannels || []).map((channel) => channel.id);
if (channelIds.length) {
params.post_data.channel_ids = channelIds;
}
return params;
},
});
1 change: 1 addition & 0 deletions mail_channel_notify_tag/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import test_mail_thread
55 changes: 55 additions & 0 deletions mail_channel_notify_tag/tests/test_mail_thread.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from odoo.tests import TransactionCase, tagged


@tagged("mail_thread")
class TestMailThread(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.member_user = (
cls.env["res.users"]
.with_context(mail_create_nolog=True)
.create(
{
"name": "Channel Member",
"login": "channel_member_test",
"email": "member@test.com",
"notification_type": "email",
}
)
)
cls.member_partner = cls.member_user.partner_id
cls.channel = cls.env["discuss.channel"].create(
{
"name": "Test Notify Channel",
"channel_type": "channel",
}
)
cls.channel.add_members(partner_ids=cls.member_partner.ids)
cls.partner = cls.env.user.partner_id

def test_01_message_post_without_channel_ids(self):
"""Messages without channel_ids should not appear in the channel."""
initial_count = len(self.channel.message_ids)
self.partner.message_post(subject="No Channel", body="No repost expected")
self.assertEqual(len(self.channel.message_ids), initial_count)

def test_02_message_post_with_channel_ids(self):
"""Messages with channel_ids should be reposted to the mentioned channel."""
self.partner.message_post(
subject="Test Channel IDs",
body="Test Message",
channel_ids=self.channel.ids,
)
msg = self.channel.message_ids[0]
self.assertIn("Test Message", msg.body)

def test_03_email_notification_queued(self):
"""Channel members with email preference should get a queued mail.mail."""
self.partner.message_post(
subject="Email Test",
body="Email Notification",
channel_ids=self.channel.ids,
)
mail = self.env["mail.mail"].search([("recipient_ids", "in", self.member_partner.ids)])
self.assertTrue(mail, "Email notification should be queued for channel member")
15 changes: 15 additions & 0 deletions mail_channel_notify_tag/views/mail_templates.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>

<template id="mail_channel_message_repost" name="Mail Channel Message Repost">
<div style="width: 100%; margin: 0 auto;">
<div style="font-size: 0.8em;margin: 5px 0;">
on
<a t-attf-href="/odoo/{{source._name}}/{{source.id}}" target="_blank" t-out="source.display_name" />
</div>
<br />
<div t-out="message.body" />
</div>
</template>

</odoo>
Loading