mirror of
https://github.com/bringout/oca-ocb-mail.git
synced 2026-04-22 00:22:05 +02:00
145 lines
6.8 KiB
Python
145 lines
6.8 KiB
Python
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from odoo import fields, http
|
|
from odoo.http import request
|
|
from odoo.addons.mail.tools.discuss import add_guest_to_context, Store
|
|
|
|
|
|
class LivechatChatbotScriptController(http.Controller):
|
|
@http.route("/chatbot/restart", type="jsonrpc", auth="public")
|
|
@add_guest_to_context
|
|
def chatbot_restart(self, channel_id, chatbot_script_id):
|
|
discuss_channel = request.env["discuss.channel"].search([("id", "=", channel_id)])
|
|
chatbot = request.env['chatbot.script'].browse(chatbot_script_id)
|
|
if not discuss_channel or not chatbot.exists():
|
|
return None
|
|
chatbot_language = chatbot._get_chatbot_language()
|
|
message = discuss_channel.with_context(lang=chatbot_language)._chatbot_restart(chatbot)
|
|
return {
|
|
"message_id": message.id,
|
|
"store_data": Store().add(message).get_result(),
|
|
}
|
|
|
|
@http.route("/chatbot/answer/save", type="jsonrpc", auth="public")
|
|
@add_guest_to_context
|
|
def chatbot_save_answer(self, channel_id, message_id, selected_answer_id):
|
|
discuss_channel = request.env["discuss.channel"].search([("id", "=", channel_id)])
|
|
chatbot_message = request.env['chatbot.message'].sudo().search([
|
|
('mail_message_id', '=', message_id),
|
|
('discuss_channel_id', '=', discuss_channel.id),
|
|
], limit=1)
|
|
selected_answer = request.env['chatbot.script.answer'].sudo().browse(selected_answer_id)
|
|
|
|
if not discuss_channel or not chatbot_message or not selected_answer.exists():
|
|
return
|
|
|
|
if selected_answer in chatbot_message.script_step_id.answer_ids:
|
|
chatbot_message.write({'user_script_answer_id': selected_answer_id})
|
|
|
|
@http.route("/chatbot/step/trigger", type="jsonrpc", auth="public")
|
|
@add_guest_to_context
|
|
def chatbot_trigger_step(self, channel_id, chatbot_script_id=None, data_id=None):
|
|
chatbot_language = self.env["chatbot.script"]._get_chatbot_language()
|
|
discuss_channel = request.env["discuss.channel"].with_context(lang=chatbot_language).search([("id", "=", channel_id)])
|
|
if not discuss_channel:
|
|
return None
|
|
|
|
next_step = False
|
|
# sudo: chatbot.script.step - visitor can access current step of the script
|
|
if current_step := discuss_channel.sudo().chatbot_current_step_id:
|
|
if (
|
|
current_step.is_forward_operator
|
|
and discuss_channel.livechat_operator_id
|
|
!= current_step.chatbot_script_id.operator_partner_id
|
|
):
|
|
return None
|
|
chatbot = current_step.chatbot_script_id
|
|
domain = [
|
|
("author_id", "!=", chatbot.operator_partner_id.id),
|
|
("model", "=", "discuss.channel"),
|
|
("res_id", "=", channel_id),
|
|
]
|
|
# sudo: mail.message - accessing last message to process answer is allowed
|
|
user_answer = self.env["mail.message"].sudo().search(domain, order="id desc", limit=1)
|
|
next_step = current_step._process_answer(discuss_channel, user_answer.body)
|
|
elif chatbot_script_id: # when restarting, we don't have a "current step" -> set "next" as first step of the script
|
|
chatbot = request.env['chatbot.script'].sudo().browse(chatbot_script_id).with_context(lang=chatbot_language)
|
|
if chatbot.exists():
|
|
next_step = chatbot.script_step_ids[:1]
|
|
partner, guest = self.env["res.partner"]._get_current_persona()
|
|
store = Store(bus_channel=partner or guest)
|
|
store.data_id = data_id
|
|
if not next_step:
|
|
# sudo - discuss.channel: marking the channel as closed as part of the chat bot flow
|
|
discuss_channel.sudo().livechat_end_dt = fields.Datetime.now()
|
|
store.resolve_data_request()
|
|
store.bus_send()
|
|
return None
|
|
# sudo: discuss.channel - updating current step on the channel is allowed
|
|
discuss_channel.sudo().chatbot_current_step_id = next_step.id
|
|
posted_message = next_step._process_step(discuss_channel)
|
|
store.add(posted_message).add(next_step)
|
|
store.resolve_data_request(
|
|
chatbot_step={"scriptStep": next_step.id, "message": posted_message.id}
|
|
)
|
|
chatbot_next_step_id = (next_step.id, posted_message.id)
|
|
store.add_model_values(
|
|
"ChatbotStep",
|
|
{
|
|
"id": chatbot_next_step_id,
|
|
"isLast": next_step._is_last_step(discuss_channel),
|
|
"message": posted_message.id,
|
|
"operatorFound": next_step.is_forward_operator
|
|
and discuss_channel.livechat_operator_id != chatbot.operator_partner_id,
|
|
"scriptStep": next_step.id,
|
|
},
|
|
)
|
|
store.add_model_values(
|
|
"Chatbot",
|
|
{
|
|
"currentStep": {
|
|
"id": chatbot_next_step_id,
|
|
"scriptStep": next_step.id,
|
|
"message": posted_message.id,
|
|
},
|
|
"id": (chatbot.id, discuss_channel.id),
|
|
"script": chatbot.id,
|
|
"thread": Store.One(discuss_channel, [], as_thread=True),
|
|
"steps": [("ADD", [{
|
|
"scriptStep": chatbot_next_step_id[0],
|
|
"message": chatbot_next_step_id[1]
|
|
}])],
|
|
},
|
|
)
|
|
store.bus_send()
|
|
|
|
@http.route("/chatbot/step/validate_email", type="jsonrpc", auth="public")
|
|
@add_guest_to_context
|
|
def chatbot_validate_email(self, channel_id):
|
|
discuss_channel = (
|
|
request.env["discuss.channel"]
|
|
.search([("id", "=", channel_id)])
|
|
.with_context(lang=self.env["chatbot.script"]._get_chatbot_language())
|
|
)
|
|
if not discuss_channel or not discuss_channel.chatbot_current_step_id:
|
|
return None
|
|
|
|
# sudo: chatbot.script - visitor can access chatbot script of their channel
|
|
chatbot = discuss_channel.sudo().chatbot_current_step_id.chatbot_script_id
|
|
domain = [
|
|
("author_id", "!=", chatbot.operator_partner_id.id),
|
|
("model", "=", "discuss.channel"),
|
|
("res_id", "=", channel_id),
|
|
]
|
|
# sudo: mail.message - accessing last message to validate email is allowed
|
|
last_user_message = self.env["mail.message"].sudo().search(domain, order="id desc", limit=1)
|
|
result = {}
|
|
if last_user_message:
|
|
result = chatbot._validate_email(last_user_message.body, discuss_channel)
|
|
if posted_message := result.pop("posted_message"):
|
|
store = Store().add(posted_message)
|
|
store.add(discuss_channel, {
|
|
"messages": Store.Many(posted_message, mode="ADD")
|
|
})
|
|
result["data"] = store.get_result()
|
|
return result
|