[IMP] website_livechat : enable chat request on all livechat enabled pages

Before this commit, only the tracked page can start the chat request at visitor
side. Which is a bit sad as the operator can send the visitor a chat request
but if the visitor goes on a non tracked page but has the opportunity to start
a livechat, the chat request won't reach the visitor.

This commit refactor the way a chat request is sent to the client side.
Instead of looking for a opened chat request on every page request,
the chat request information (if any opened) is added to the channel info
that are given to the Livechat button widget.

If the widget receives chat request infos, the widget set himself, before
starting, the cookie of the livechat session using the chat request
informations. Then, the conversation (from chat request) is automatically
loaded as any other opened chat session.

Task ID: 2081550
PR #40274

Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
David Beguin
2020-01-02 15:14:47 +00:00
committed by Thibault Delavallée
parent 12eb45301f
commit 5b62f6e0b6
3 changed files with 43 additions and 53 deletions
+38 -1
View File
@@ -16,5 +16,42 @@ class Website(models.Model):
"""
self.ensure_one()
if self.channel_id:
return self.channel_id.sudo().get_livechat_info()
livechat_info = self.channel_id.sudo().get_livechat_info()
if livechat_info['available']:
livechat_request_session = self._get_livechat_request_session()
if livechat_request_session:
livechat_info['options']['chat_request_session'] = livechat_request_session
return livechat_info
return {}
def _get_livechat_request_session(self):
"""
Check if there is an opened chat request for the website livechat channel and the current visitor (from request).
If so, prepare the livechat session information that will be stored in visitor's cookies
and used by livechat widget to directly open this session instead of allowing the visitor to
initiate a new livechat session.
:param {int} channel_id: channel
:return: {dict} livechat request session information
"""
visitor = self.env['website.visitor']._get_visitor_from_request()
if visitor:
# get active chat_request linked to visitor
chat_request_channel = self.env['mail.channel'].sudo().search([
('livechat_visitor_id', '=', visitor.id),
('livechat_channel_id', '=', self.channel_id.id),
('livechat_active', '=', True),
('channel_message_ids', '!=', False)
], order='create_date desc', limit=1)
if chat_request_channel:
return {
"folded": False,
"id": chat_request_channel.id,
"operator_pid": [
chat_request_channel.livechat_operator_id.id,
chat_request_channel.livechat_operator_id.display_name
],
"name": chat_request_channel.name,
"uuid": chat_request_channel.uuid,
"type": "chat_request"
}
return {}
@@ -74,32 +74,3 @@ class WebsiteVisitor(models.Model):
mail_channels_info = mail_channels.channel_info('channel_minimize')
for mail_channel_info in mail_channels_info:
self.env['bus.bus'].sendone((self._cr.dbname, 'res.partner', operator.partner_id.id), mail_channel_info)
def _handle_website_page_visit(self, response, website_page, visitor_sudo):
""" Called when the visitor navigates to a website page.
This checks if there is a chat request for the visitor.
It will set the livechat session cookie of the visitor with the mail channel information
to make the usual livechat mechanism do the rest.
(opening the chatter if a livechat session exist for the visitor)
This will only happen if the mail channel linked to the chat request already has a message.
So that empty livechat channel won't pop up at client side. """
super(WebsiteVisitor, self)._handle_website_page_visit(response, website_page, visitor_sudo)
visitor_id = visitor_sudo.id or self.env['website.visitor']._get_visitor_from_request().id
if visitor_id:
# get active chat_request linked to visitor
chat_request_channel = self.env['mail.channel'].sudo().search([('livechat_visitor_id', '=', visitor_id), ('livechat_active', '=', True)], order='create_date desc', limit=1)
if chat_request_channel and chat_request_channel.channel_message_ids:
livechat_session = json.dumps({
"folded": False,
"id": chat_request_channel.id,
"message_unread_counter": 0,
"operator_pid": [
chat_request_channel.livechat_operator_id.id,
chat_request_channel.livechat_operator_id.display_name
],
"name": chat_request_channel.name,
"uuid": chat_request_channel.uuid,
"type": "chat_request"
})
expiration_date = datetime.now() + timedelta(days=100 * 365) # never expire
response.set_cookie('im_livechat_session', livechat_session, expires=expiration_date.timestamp())
@@ -10,18 +10,15 @@ LivechatButton.include({
/**
* @override
* This will will correctly format the livechat session cookie
* that comes from server side (and that is not properly formatted)
* Check if a chat request is opened for this visitor
* if yes, replace the session cookie and start the conversation immediately.
* Do this before calling super to have everything ready before executing existing start logic.
* This is used for chat request mechanism, when an operator send a chat request
* from backend to a website visitor.
*/
willStart: function () {
var self = this;
var cookie = utils.get_cookie('im_livechat_session');
var ready;
if (cookie) {
var cleanedLivechatSessionCookie = this.decode_server_cookie(cookie);
utils.set_cookie('im_livechat_session', cleanedLivechatSessionCookie, 60*60);
if (this.options.chat_request_session) {
utils.set_cookie('im_livechat_session', JSON.stringify(this.options.chat_request_session), 60*60);
}
return this._super();
},
@@ -45,21 +42,6 @@ LivechatButton.include({
this._super();
}
},
/**
* Utils to correctly re-encode json string sent by server.
* Copied from StackOverflow.
*/
decode_server_cookie: function (val) {
if (val.indexOf('\\') === -1) {
return val; // not encoded
}
val = val.slice(1, -1).replace(/\\"/g, '"');
val = val.replace(/\\(\d{3})/g, function(match, octal) {
return String.fromCharCode(parseInt(octal, 8));
});
return val.replace(/\\\\/g, '\\');
},
});
return {