Files
odoo_source/addons/website_livechat/models/mail_channel.py
T
Didier (did) 1afcc9c368 [IMP] bus, mail, *: improve longpolling bus notification format
* = auth_signup, calendar, im_livechat, snailmail_account, survey, test_mail,
    web_editor, website_crm_iap_reveal, website_livechat

The aim of this PR is to improve/fix various flaws and limitation of the current
API, to make it easier to use and more efficient.

Notification are now defined with 3 distinct parts:

- the channel determines which client(s) should receive it
- the type determines how it should be handled
- the payload determines any extra information helpful for handling it

Channel
=======

Business code
-------------

- Record channel is introduced for ease of subscribing to and sending
  notifications to specific partners, channels, documents, ...
- String channel is still supported (but it is converted internally to the tuple
  channel).
- Tuple channel is still supported without any change (but should be avoided
  whenever possible due to its complex syntax).

The channel is no longer sent to the client. When the channel was used for
business purpose, the information it contained has been moved into either the
new type, or the payload itself.

Technical note
--------------

All channels are now internally converted to the tuple (db, ...) channel, which
is necessary for the platform code (saas/sh).

Internally, the bus.bus table is not changed, type and payload are grouped
together into what was (and still is) called message.

Type
====

Type is introduced to uniformize the way notifications are sent and handled.
All existing notifications already had some kind of manually-built type in them.
This is now officially supported at the bus API.

In client code this will allow (to be done in future commits) to register one
handler per specific type, instead of having to iterate and to filter all
received notifications on every handler.

Payload
=======

Payload (ex message) did not change, it can still be anything depending on
business needs.

Few adaptations:
- When the type was included on the payload, the type has been moved to the new
  type parameter.
- When the channel was used in business code, its data has been copied into the
  payload.

task-1891151

closes odoo/odoo#79201

X-original-commit: 543af27c7d6836ffac9e80ff8490b6ddbd849221
Related: odoo/enterprise#21998
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2021-10-29 16:05:23 +00:00

78 lines
3.7 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models, _
class MailChannel(models.Model):
_inherit = 'mail.channel'
livechat_visitor_id = fields.Many2one('website.visitor', string='Visitor')
def _execute_channel_pin(self, pinned=False):
""" Override to clean an empty livechat channel.
This is typically called when the operator send a chat request to a website.visitor
but don't speak to him and closes the chatter.
This allows operators to send the visitor a new chat request.
If active empty livechat channel,
delete mail_channel as not useful to keep empty chat
"""
super(MailChannel, self)._execute_channel_pin(pinned)
if self.livechat_active and not self.message_ids:
self.unlink()
def channel_info(self):
"""
Override to add visitor information on the mail channel infos.
This will be used to display a banner with visitor informations
at the top of the livechat channel discussion view in discuss module.
"""
channel_infos = super().channel_info()
channel_infos_dict = dict((c['id'], c) for c in channel_infos)
for channel in self:
visitor = channel.livechat_visitor_id
if visitor:
channel_infos_dict[channel.id]['visitor'] = {
'display_name': visitor.display_name,
'country_code': visitor.country_id.code.lower() if visitor.country_id else False,
'country_id': visitor.country_id.id,
'id': visitor.id,
'is_connected': visitor.is_connected,
'history': self.sudo()._get_visitor_history(visitor),
'website_name': visitor.website_id.name,
'lang_name': visitor.lang_id.name,
'partner_id': visitor.partner_id.id,
}
return list(channel_infos_dict.values())
def _get_visitor_history(self, visitor):
"""
Prepare history string to render it in the visitor info div on discuss livechat channel view.
:param visitor: website.visitor of the channel
:return: arrow separated string containing navigation history information
"""
recent_history = self.env['website.track'].search([('page_id', '!=', False), ('visitor_id', '=', visitor.id)], limit=3)
return ' → '.join(visit.page_id.name + ' (' + visit.visit_datetime.strftime('%H:%M') + ')' for visit in reversed(recent_history))
def _get_visitor_leave_message(self, operator=False, cancel=False):
name = _('The visitor') if not self.livechat_visitor_id else self.livechat_visitor_id.display_name
if cancel:
message = _("""%s has started a conversation with %s.
The chat request has been canceled.""") % (name, operator or _('an operator'))
else:
message = _('%s has left the conversation.', name)
return message
@api.returns('mail.message', lambda value: value.id)
def message_post(self, **kwargs):
"""Override to mark the visitor as still connected.
If the message sent is not from the operator (so if it's the visitor or
odoobot sending closing chat notification, the visitor last action date is updated."""
message = super(MailChannel, self).message_post(**kwargs)
message_author_id = message.author_id
visitor = self.livechat_visitor_id
if len(self) == 1 and visitor and message_author_id != self.livechat_operator_id:
visitor._update_visitor_last_visit()
return message