From fdce0f0d41236cc653f86ff1422732e8053d8b7c Mon Sep 17 00:00:00 2001 From: tsm-odoo Date: Wed, 10 Apr 2024 10:59:06 +0200 Subject: [PATCH] [FIX] im_livechat: chat bot redirection on pages without chat bot Before this PR, the chatbot script would hang when redirected to a page where the chatbot is not enabled. When such a scenario occurs, we should restore the chatbot's state to where it stopped, and the script should continue. This PR fixes this issue. task-3625853 closes odoo/odoo#161121 Signed-off-by: Matthieu Stockbauer (tsm) --- .../embed/common/chatbot/chatbot_service.js | 3 -- .../src/embed/common/thread_model_patch.js | 48 ++++++++++++------- .../src/embed/common/thread_service_patch.js | 3 ++ .../static/src/tour_service/tour_service.js | 9 ++-- .../src/embed/common/thread_model_patch.js | 4 ++ .../website_livechat_chatbot_redirect.js | 17 +++---- .../website_livechat/tests/test_chatbot_ui.py | 6 +-- 7 files changed, 49 insertions(+), 41 deletions(-) diff --git a/addons/im_livechat/static/src/embed/common/chatbot/chatbot_service.js b/addons/im_livechat/static/src/embed/common/chatbot/chatbot_service.js index 01f62497276..d94c37608e5 100644 --- a/addons/im_livechat/static/src/embed/common/chatbot/chatbot_service.js +++ b/addons/im_livechat/static/src/embed/common/chatbot/chatbot_service.js @@ -87,9 +87,6 @@ export class ChatBotService { await this.postWelcomeSteps(); this.save(); } - if (this.savedState) { - this._restore(); - } if (!this.currentStep?.expectAnswer) { this._triggerNextStep(); } else if (this.livechatService.thread?.isLastMessageFromCustomer) { diff --git a/addons/im_livechat/static/src/embed/common/thread_model_patch.js b/addons/im_livechat/static/src/embed/common/thread_model_patch.js index f858d68d57e..341fd67aa88 100644 --- a/addons/im_livechat/static/src/embed/common/thread_model_patch.js +++ b/addons/im_livechat/static/src/embed/common/thread_model_patch.js @@ -31,22 +31,6 @@ patch(Thread, { } } ); - if (this.env.services["im_livechat.chatbot"].isChatbotThread(thread)) { - thread.chatbotTypingMessage = { - id: this.env.services["mail.message"].getNextTemporaryId(), - res_id: thread.id, - model: thread.model, - author: thread.operator, - }; - } else { - thread.livechatWelcomeMessage = { - id: this.env.services["mail.message"].getNextTemporaryId(), - body: livechatService.options.default_message, - res_id: thread.id, - model: thread.model, - author: thread.operator, - }; - } } return thread; }, @@ -55,8 +39,32 @@ patch(Thread, { patch(Thread.prototype, { setup() { super.setup(); - this.chatbotTypingMessage = Record.one("Message"); - this.livechatWelcomeMessage = Record.one("Message"); + this.chatbotTypingMessage = Record.one("Message", { + compute() { + if (this._store.env.services["im_livechat.chatbot"].isChatbotThread(this)) { + return { + id: Number.isInteger(this.id) ? -0.1 - this.id : -0.1, + res_id: this.id, + model: this.model, + author: this.operator, + }; + } + }, + }); + this.livechatWelcomeMessage = Record.one("Message", { + compute() { + if (this.displayWelcomeMessage) { + const livechatService = this._store.env.services["im_livechat.livechat"]; + return { + id: Number.isInteger(this.id) ? -0.2 - this.id : -0.2, + body: livechatService.options.default_message, + res_id: this.id, + model: this.model, + author: this.operator, + }; + } + }, + }); this.chatbotScriptId = null; /** * Indicates whether this thread was just created (i.e. no reload occurs @@ -82,4 +90,8 @@ patch(Thread.prototype, { get isTransient() { return super.isTransient || this.id === LivechatService.TEMPORARY_ID; }, + + get displayWelcomeMessage() { + return !this._store.env.services["im_livechat.chatbot"].isChatbotThread(this); + }, }); diff --git a/addons/im_livechat/static/src/embed/common/thread_service_patch.js b/addons/im_livechat/static/src/embed/common/thread_service_patch.js index f09ad38082a..9fa164cb6ff 100644 --- a/addons/im_livechat/static/src/embed/common/thread_service_patch.js +++ b/addons/im_livechat/static/src/embed/common/thread_service_patch.js @@ -44,6 +44,9 @@ patch(ThreadService.prototype, { folded: thread.state === "folded", }); chatWindow.autofocus++; + if (this.chatbotService.savedState) { + this.chatbotService._restore(); + } if (this.chatbotService.active) { this.chatbotService.start(); } diff --git a/addons/web_tour/static/src/tour_service/tour_service.js b/addons/web_tour/static/src/tour_service/tour_service.js index ef2c1c0fe1d..8659675bd46 100644 --- a/addons/web_tour/static/src/tour_service/tour_service.js +++ b/addons/web_tour/static/src/tour_service/tour_service.js @@ -299,12 +299,9 @@ export const tourService = { * @param {Tour} tour */ function setupShadowObservers(tour) { - const shadowDOMs = tour.steps.reduce((acc, step) => { - if (step.shadow_dom) { - acc.add(step.shadow_dom); - } - return acc; - }, new Set()); + const shadowDOMs = new Set( + tour.steps.filter((step) => step.shadow_dom).map((step) => step.shadow_dom) + ); if (shadowDOMs.size > 0) { observeShadows(shadowDOMs); } diff --git a/addons/website_livechat/static/src/embed/common/thread_model_patch.js b/addons/website_livechat/static/src/embed/common/thread_model_patch.js index eff4fb4be89..fab28ffd6cc 100644 --- a/addons/website_livechat/static/src/embed/common/thread_model_patch.js +++ b/addons/website_livechat/static/src/embed/common/thread_model_patch.js @@ -9,4 +9,8 @@ patch(Thread.prototype, { super.update(data); assignDefined(this, data, ["requested_by_operator"]); }, + + get displayWelcomeMessage() { + return super.displayWelcomeMessage && !this.requested_by_operator; + }, }); diff --git a/addons/website_livechat/static/tests/tours/website_livechat_chatbot_redirect.js b/addons/website_livechat/static/tests/tours/website_livechat_chatbot_redirect.js index 12957a581e6..6c544d8638d 100644 --- a/addons/website_livechat/static/tests/tours/website_livechat_chatbot_redirect.js +++ b/addons/website_livechat/static/tests/tours/website_livechat_chatbot_redirect.js @@ -1,12 +1,11 @@ /* @odoo-module */ import { registry } from "@web/core/registry"; -import { contains } from "@web/../tests/utils"; registry.category("web_tour.tours").add("website_livechat.chatbot_redirect", { shadow_dom: ".o-livechat-root", test: true, - url: "/", + url: "/contactus", steps: () => [ { trigger: ".o-livechat-LivechatButton", @@ -21,7 +20,7 @@ registry.category("web_tour.tours").add("website_livechat.chatbot_redirect", { trigger: ".o-mail-Message:contains(Tadam, we are on the page you asked for!)", run() { const url = new URL(location.href); - if (url.pathname !== "/" || url.hash !== "#chatbot-redirect") { + if (url.pathname !== "/contactus" || url.hash !== "#chatbot-redirect") { throw new Error( "Chatbot should have redirected to the #chatbot-redirect anchor." ); @@ -32,16 +31,12 @@ registry.category("web_tour.tours").add("website_livechat.chatbot_redirect", { trigger: "button[title='Restart Conversation']", }, { - trigger: "li:contains(Go to the /chabtot-redirect page)", + trigger: "li:contains(Go to the /chatbot-redirect page)", }, { - trigger: ".o-mail-Message:contains(Tadam, we are on the page you asked for!)", - async run() { - await contains(".o-mail-Message", { - text: "Tadam, we are on the page you asked for!", - target: this.$anchor[0], - count: 2, - }); + trigger: + ".o-mail-Message:contains('Go to the /chatbot-redirect page') + .o-mail-Message:contains('Tadam')", + run() { const url = new URL(location.href); if (url.pathname !== "/chatbot-redirect") { throw new Error( diff --git a/addons/website_livechat/tests/test_chatbot_ui.py b/addons/website_livechat/tests/test_chatbot_ui.py index 2057a67dc18..f94cb8f2251 100644 --- a/addons/website_livechat/tests/test_chatbot_ui.py +++ b/addons/website_livechat/tests/test_chatbot_ui.py @@ -123,7 +123,7 @@ class TestLivechatChatbotUI(TestLivechatCommon, ChatbotCase): "script_step_id": question_step.id, }, { - "name": "Go to the /chabtot-redirect page", + "name": "Go to the /chatbot-redirect page", "redirect_link": "/chatbot-redirect", "script_step_id": question_step.id, }, @@ -131,11 +131,11 @@ class TestLivechatChatbotUI(TestLivechatCommon, ChatbotCase): livechat_channel = self.env["im_livechat.channel"].create({ 'name': 'Redirection Channel', 'rule_ids': [Command.create({ - 'regex_url': '/', + 'regex_url': '/contactus', 'chatbot_script_id': chatbot_redirect_script.id, })] }) default_website = self.env.ref("website.default_website") default_website.channel_id = livechat_channel.id self.env.ref("website.default_website").channel_id = livechat_channel.id - self.start_tour("/", "website_livechat.chatbot_redirect") + self.start_tour("/contactus", "website_livechat.chatbot_redirect")