[FIX] mail: fix temporary_id not supported as message_post parameter

Since [1], the `temporary_id` of a message is passed to the
`message_post` route in order to renconciliate the temporary
message on the client side and the real message created by the
server.

This led to crashes when sending message on the chatter because
this parameter was not allowed as a `_notify_thread` parameter.

Since this parameter is highly specific and isn't linked to any
business/model code, this parameter is now passed via the context
thus solving this issue.

[1]: https://github.com/odoo/odoo/pull/116085

closes odoo/odoo#116333

Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
This commit is contained in:
tsm-odoo
2023-03-24 07:45:01 +01:00
parent 7b368df0fe
commit b34d0fd7c9
6 changed files with 20 additions and 20 deletions
+2 -2
View File
@@ -34,12 +34,12 @@ class MailChannel(models.Model):
if record.channel_type == 'livechat':
record.is_chat = True
def _channel_message_notifications(self, message, message_format=False, temporary_id=None):
def _channel_message_notifications(self, message, message_format=False):
""" When a anonymous user create a mail.channel, the operator is not notify (to avoid massive polling when
clicking on livechat button). So when the anonymous person is sending its FIRST message, the channel header
should be added to the notification, since the user cannot be listining to the channel.
"""
notifications = super()._channel_message_notifications(message=message, message_format=message_format, temporary_id=temporary_id)
notifications = super()._channel_message_notifications(message=message, message_format=message_format)
for channel in self:
# add uuid to allow anonymous to listen
if channel.channel_type == 'livechat':
+3 -3
View File
@@ -229,7 +229,7 @@ class DiscussController(http.Controller):
# --------------------------------------------------------------------------
def _get_allowed_message_post_params(self):
return {'attachment_ids', 'body', 'message_type', 'partner_ids', 'subtype_xmlid', 'temporary_id', 'parent_id'}
return {'attachment_ids', 'body', 'message_type', 'partner_ids', 'subtype_xmlid', 'parent_id'}
@http.route('/mail/message/post', methods=['POST'], type='json', auth='public')
def mail_message_post(self, thread_model, thread_id, post_data, **kwargs):
@@ -239,8 +239,8 @@ class DiscussController(http.Controller):
else:
thread = request.env[thread_model].browse(int(thread_id)).exists()
message_data = thread.message_post(**{key: value for key, value in post_data.items() if key in self._get_allowed_message_post_params()}).message_format()[0]
if 'temporary_id' in post_data:
message_data['temporary_id'] = post_data['temporary_id']
if 'temporary_id' in request.context:
message_data['temporary_id'] = request.context['temporary_id']
return message_data
@http.route('/mail/message/update_content', methods=['POST'], type='json', auth='public')
+5 -6
View File
@@ -558,12 +558,12 @@ class Channel(models.Model):
groups[index] = (group_name, lambda partner: False, group_data)
return groups
def _notify_thread(self, message, msg_vals=False, temporary_id=None, **kwargs):
def _notify_thread(self, message, msg_vals=False, **kwargs):
# link message to channel
rdata = super(Channel, self)._notify_thread(message, msg_vals=msg_vals, **kwargs)
message_format_values = message.message_format()[0]
bus_notifications = self._channel_message_notifications(message, message_format_values, temporary_id)
bus_notifications = self._channel_message_notifications(message, message_format_values)
# Last interest and is_pinned are updated for a chat when posting a message.
# So a notification is needed to update UI, and it should come before the
# notification of the message itself to ensure the channel automatically opens.
@@ -717,15 +717,14 @@ class Channel(models.Model):
notifications.append((partner, 'mail.channel/legacy_insert', channel_info))
return notifications
def _channel_message_notifications(self, message, message_format=False, temporary_id=None):
def _channel_message_notifications(self, message, message_format=False):
""" Generate the bus notifications for the given message
:param message : the mail.message to sent
:param temporary_id: temporary id of the message on the client side.
:returns list of bus notifications (tuple (bus_channe, message_content))
"""
message_format = dict(message_format or message.message_format()[0])
if temporary_id:
message_format['temporary_id'] = temporary_id
if 'temporary_id' in self.env.context:
message_format['temporary_id'] = self.env.context['temporary_id']
notifications = []
for channel in self:
payload = {
@@ -680,13 +680,15 @@ export class ThreadService {
const lastMessageId = this.messageService.getLastMessageId();
const tmpId = lastMessageId + 0.01;
const params = {
context: {
temporary_id: tmpId,
},
post_data: {
body: await prettifyMessageContent(body, validMentions),
attachment_ids: attachments.map(({ id }) => id),
message_type: "comment",
partner_ids,
subtype_xmlid: subtype,
temporary_id: tmpId,
},
thread_id: thread.id,
thread_model: thread.model,
@@ -175,8 +175,7 @@ patch(MockServer.prototype, "mail/models/mail_thread", {
kwargs.email_from,
context
);
const { temporary_id, ...postData } = kwargs;
const values = Object.assign({}, postData, {
const values = Object.assign({}, kwargs, {
author_id,
email_from,
is_discussion: subtype_xmlid === "mail.mt_comment",
@@ -186,8 +185,10 @@ patch(MockServer.prototype, "mail/models/mail_thread", {
});
delete values.subtype_xmlid;
const messageId = this.pyEnv["mail.message"].create(values);
this._mockMailThread_NotifyThread(model, ids, messageId, temporary_id);
return Object.assign(this._mockMailMessageMessageFormat([messageId])[0], { temporary_id });
this._mockMailThread_NotifyThread(model, ids, messageId, context?.temporary_id);
return Object.assign(this._mockMailMessageMessageFormat([messageId])[0], {
temporary_id: context?.temporary_id,
});
},
/**
* Simulates `message_subscribe` on `mail.thread`.
@@ -57,14 +57,13 @@ QUnit.test("can post a message on a record thread", async (assert) => {
if (route === "/mail/message/post") {
assert.step(route);
const expected = {
context: args.context,
post_data: {
body: "hey",
attachment_ids: [],
message_type: "comment",
partner_ids: [],
subtype_xmlid: "mail.mt_comment",
// cannot predict which temporary id will be passed.
temporary_id: args.post_data.temporary_id,
},
thread_id: partnerId,
thread_model: "res.partner",
@@ -95,14 +94,13 @@ QUnit.test("can post a note on a record thread", async (assert) => {
if (route === "/mail/message/post") {
assert.step(route);
const expected = {
context: args.context,
post_data: {
attachment_ids: [],
body: "hey",
message_type: "comment",
partner_ids: [],
subtype_xmlid: "mail.mt_note",
// cannot predict which temporary id will be passed.
temporary_id: args.post_data.temporary_id,
},
thread_id: partnerId,
thread_model: "res.partner",