summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAurélien Warnon <awa@odoo.com>2019-01-09 13:26:25 +0000
committerjem-odoo <jem@openerp.com>2019-04-01 07:03:11 +0000
commit594c6e8a2a78d4592db62345194ca9b7e1575272 (patch)
tree017d29266b5656e4221f3d19aeef4b75129ff34e
parent9b867cd12dbc8cca5da1e3d6426b5cadf8a0ec33 (diff)
[IMP] im_livechat: ensure that visitors always gets the same operator
Task #1919871 Purpose ======= If a visitor comes on the website and launches a livechat, it will be randomly assigned operator A. If he comes the next day and opens a livechat again, we want him to have the same operator if he's available. To handle that use case, we added a cookie that stores the "previous operator id" information for 7 days.
-rw-r--r--addons/im_livechat/controllers/main.py8
-rw-r--r--addons/im_livechat/models/im_livechat_channel.py18
-rw-r--r--addons/im_livechat/static/src/js/im_livechat.js26
3 files changed, 48 insertions, 4 deletions
diff --git a/addons/im_livechat/controllers/main.py b/addons/im_livechat/controllers/main.py
index d87cf2329cb..5703563e95d 100644
--- a/addons/im_livechat/controllers/main.py
+++ b/addons/im_livechat/controllers/main.py
@@ -80,7 +80,7 @@ class LivechatController(http.Controller):
}
@http.route('/im_livechat/get_session', type="json", auth='public', cors="*")
- def get_session(self, channel_id, anonymous_name, **kwargs):
+ def get_session(self, channel_id, anonymous_name, previous_operator_id=None, **kwargs):
user_id = None
country_id = None
# if the user is identifiy (eg: portal user on the frontend), don't use the anonymous name. The user will be added to session.
@@ -94,7 +94,11 @@ class LivechatController(http.Controller):
country = request.env['res.country'].sudo().search([('code', '=', country_code)], limit=1) if country_code else None
if country:
anonymous_name, country_id = _("%s (%s)") % (anonymous_name, country.name), country.id
- return request.env["im_livechat.channel"].with_context(lang=False).sudo().browse(channel_id)._get_mail_channel(anonymous_name, user_id, country_id)
+
+ if previous_operator_id:
+ previous_operator_id = int(previous_operator_id)
+
+ return request.env["im_livechat.channel"].with_context(lang=False).sudo().browse(channel_id)._get_mail_channel(anonymous_name, previous_operator_id, user_id, country_id)
@http.route('/im_livechat/feedback', type='json', auth='public', cors="*")
def feedback(self, uuid, rate, reason=None, **kwargs):
diff --git a/addons/im_livechat/models/im_livechat_channel.py b/addons/im_livechat/models/im_livechat_channel.py
index 4a682c912f1..6a568bbb269 100644
--- a/addons/im_livechat/models/im_livechat_channel.py
+++ b/addons/im_livechat/models/im_livechat_channel.py
@@ -132,19 +132,33 @@ class ImLivechatChannel(models.Model):
return self.user_ids.filtered(lambda user: user.im_status == 'online')
@api.multi
- def _get_mail_channel(self, anonymous_name, user_id=None, country_id=None):
+ def _get_mail_channel(self, anonymous_name, previous_operator_id=None, user_id=None, country_id=None):
""" Return a mail.channel given a livechat channel. It creates one with a connected operator, or return false otherwise
:param anonymous_name : the name of the anonymous person of the channel
+ :param previous_operator_id : partner_id.id of the previous operator that this visitor had in the past
:param user_id : the id of the logged in visitor, if any
:param country_code : the country of the anonymous person of the channel
:type anonymous_name : str
:return : channel header
:rtype : dict
+
+ If this visitor already had an operator within the last 7 days (information stored with the 'im_livechat_previous_operator_pid' cookie),
+ the system will first try to assign that operator if he's available (to improve user experience).
"""
self.ensure_one()
- operator = self._get_random_operator()
+
+ operator = False
+ if previous_operator_id:
+ available_users = self._get_available_users()
+ # previous_operator_id is the partner_id of the previous operator, need to convert to user
+ if previous_operator_id in available_users.mapped('partner_id').ids:
+ operator = next(available_user for available_user in available_users if available_user.partner_id.id == previous_operator_id)
if not operator:
+ operator = self._get_random_operator()
+ if not operator:
+ # no one available
return False
+
operator_partner_id = operator.partner_id.id
# partner to add to the mail.channel
channel_partner_to_add = [(4, operator_partner_id)]
diff --git a/addons/im_livechat/static/src/js/im_livechat.js b/addons/im_livechat/static/src/js/im_livechat.js
index 4e0a48f4325..086f02daa32 100644
--- a/addons/im_livechat/static/src/js/im_livechat.js
+++ b/addons/im_livechat/static/src/js/im_livechat.js
@@ -215,6 +215,7 @@ var LivechatButton = Widget.extend({
def = session.rpc('/im_livechat/get_session', {
channel_id : this.options.channel_id,
anonymous_name : this.options.default_username,
+ previous_operator_id: this._get_previous_operator_id(),
}, {shadow: true});
}
def.then(function (livechatData) {
@@ -233,6 +234,13 @@ var LivechatButton = Widget.extend({
utils.set_cookie('im_livechat_session', JSON.stringify(self._livechat.toData()), 60*60);
utils.set_cookie('im_livechat_auto_popup', JSON.stringify(false), 60*60);
+ if (livechatData.operator_pid[0]) {
+ // livechatData.operator_pid contains a tuple (id, name)
+ // we are only interested in the id
+ var operatorPidId = livechatData.operator_pid[0];
+ var oneWeek = 7*24*60*60;
+ utils.set_cookie('im_livechat_previous_operator_pid', operatorPidId, oneWeek);
+ }
});
}
}).then(function () {
@@ -242,6 +250,24 @@ var LivechatButton = Widget.extend({
});
}, 200, true),
/**
+ * Will try to get a previous operator for this visitor.
+ * If the visitor already had visitor A, it's better for his user experience
+ * to get operator A again.
+ *
+ * The information is stored in the 'im_livechat_previous_operator_pid' cookie.
+ *
+ * @private
+ * @return {integer} operator_id.partner_id.id if the cookie is set
+ */
+ _get_previous_operator_id: function () {
+ var cookie = utils.get_cookie('im_livechat_previous_operator_pid');
+ if (cookie) {
+ return cookie;
+ }
+
+ return null;
+ },
+ /**
* @private
* @return {Promise}
*/