Начальное наполнение
This commit is contained in:
parent
82b74d3ff4
commit
a76ab7f777
6
__init__.py
Normal file
6
__init__.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from . import controllers
|
||||||
|
from . import models
|
||||||
|
from . import report
|
||||||
|
from . import demo
|
||||||
|
from . import tools
|
145
__manifest__.py
Normal file
145
__manifest__.py
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
{
|
||||||
|
'name': 'Live Chat',
|
||||||
|
'version': '1.0',
|
||||||
|
'sequence': 210,
|
||||||
|
'summary': 'Chat with your website visitors',
|
||||||
|
'category': 'Website/Live Chat',
|
||||||
|
'website': 'https://www.odoo.com/app/live-chat',
|
||||||
|
'description':
|
||||||
|
"""
|
||||||
|
Live Chat Support
|
||||||
|
==========================
|
||||||
|
|
||||||
|
Allow to drop instant messaging widgets on any web page that will communicate
|
||||||
|
with the current server and dispatch visitors request amongst several live
|
||||||
|
chat operators.
|
||||||
|
Help your customers with this chat, and analyse their feedback.
|
||||||
|
|
||||||
|
""",
|
||||||
|
'data': [
|
||||||
|
"security/im_livechat_channel_security.xml",
|
||||||
|
"security/ir.model.access.csv",
|
||||||
|
"data/discuss_shortcode_data.xml",
|
||||||
|
"data/mail_templates.xml",
|
||||||
|
"data/im_livechat_channel_data.xml",
|
||||||
|
"data/im_livechat_chatbot_data.xml",
|
||||||
|
'data/digest_data.xml',
|
||||||
|
'views/chatbot_script_answer_views.xml',
|
||||||
|
'views/chatbot_script_step_views.xml',
|
||||||
|
'views/chatbot_script_views.xml',
|
||||||
|
"views/rating_rating_views.xml",
|
||||||
|
"views/discuss_channel_views.xml",
|
||||||
|
"views/im_livechat_channel_views.xml",
|
||||||
|
"views/im_livechat_channel_templates.xml",
|
||||||
|
"views/im_livechat_chatbot_templates.xml",
|
||||||
|
"views/res_users_views.xml",
|
||||||
|
"views/digest_views.xml",
|
||||||
|
"views/webclient_templates.xml",
|
||||||
|
"report/im_livechat_report_channel_views.xml",
|
||||||
|
"report/im_livechat_report_operator_views.xml"
|
||||||
|
],
|
||||||
|
'demo': [
|
||||||
|
"demo/im_livechat_channel/im_livechat_channel.xml",
|
||||||
|
"demo/im_livechat_channel/im_livechat_session_1.xml",
|
||||||
|
"demo/im_livechat_channel/im_livechat_session_2.xml",
|
||||||
|
"demo/im_livechat_channel/im_livechat_session_3.xml",
|
||||||
|
"demo/im_livechat_channel/im_livechat_session_4.xml",
|
||||||
|
"demo/im_livechat_channel/im_livechat_session_5.xml",
|
||||||
|
"demo/im_livechat_channel/im_livechat_session_6.xml",
|
||||||
|
"demo/im_livechat_channel/im_livechat_session_7.xml",
|
||||||
|
"demo/im_livechat_channel/im_livechat_session_8.xml",
|
||||||
|
"demo/im_livechat_channel/im_livechat_session_9.xml",
|
||||||
|
"demo/im_livechat_channel/im_livechat_session_10.xml",
|
||||||
|
"demo/im_livechat_channel/im_livechat_session_11.xml",
|
||||||
|
"demo/discuss_shortcode/discuss_shortcode_demo.xml",
|
||||||
|
],
|
||||||
|
'depends': ["mail", "rating", "digest", "utm"],
|
||||||
|
'installable': True,
|
||||||
|
'application': True,
|
||||||
|
'assets': {
|
||||||
|
'web._assets_primary_variables': [
|
||||||
|
'im_livechat/static/src/primary_variables.scss',
|
||||||
|
],
|
||||||
|
'web.assets_frontend': [
|
||||||
|
'web/static/src/views/fields/file_handler.*',
|
||||||
|
'web/static/src/views/fields/formatters.js',
|
||||||
|
('include', 'im_livechat.assets_embed_core'),
|
||||||
|
'im_livechat/static/src/embed/frontend/**/*',
|
||||||
|
],
|
||||||
|
'web.assets_backend': [
|
||||||
|
'im_livechat/static/src/js/colors_reset_button/*',
|
||||||
|
'im_livechat/static/src/js/im_livechat_chatbot_steps_one2many.js',
|
||||||
|
'im_livechat/static/src/js/im_livechat_chatbot_script_answers_m2m.js',
|
||||||
|
'im_livechat/static/src/views/**/*',
|
||||||
|
'im_livechat/static/src/scss/im_livechat_history.scss',
|
||||||
|
'im_livechat/static/src/scss/im_livechat_form.scss',
|
||||||
|
'im_livechat/static/src/core/common/**/*',
|
||||||
|
'im_livechat/static/src/core/web/**/*',
|
||||||
|
],
|
||||||
|
'web.tests_assets': [
|
||||||
|
'im_livechat/static/tests/helpers/**/*.js',
|
||||||
|
],
|
||||||
|
'web.qunit_suite_tests': [
|
||||||
|
'im_livechat/static/tests/**/*',
|
||||||
|
('remove', 'im_livechat/static/tests/embed/**/*'),
|
||||||
|
('remove', 'im_livechat/static/tests/tours/**/*'),
|
||||||
|
('remove', 'im_livechat/static/tests/helpers/**/*.js'),
|
||||||
|
],
|
||||||
|
'web.assets_tests': [
|
||||||
|
'im_livechat/static/tests/tours/**/*',
|
||||||
|
],
|
||||||
|
'im_livechat.assets_embed_core': [
|
||||||
|
'web/static/lib/odoo_ui_icons/style.css',
|
||||||
|
'web/static/src/scss/ui.scss',
|
||||||
|
('remove', 'web/static/src/core/browser/title_service.js'),
|
||||||
|
'mail/static/src/core/common/**/*',
|
||||||
|
'mail/static/src/discuss/core/common/*',
|
||||||
|
'mail/static/src/discuss/call/common/**',
|
||||||
|
'mail/static/src/discuss/typing/**/*',
|
||||||
|
'mail/static/src/utils/common/**/*',
|
||||||
|
('remove', 'mail/static/src/**/*.dark.scss'),
|
||||||
|
'im_livechat/static/src/core/common/**/*',
|
||||||
|
'im_livechat/static/src/embed/common/**/*',
|
||||||
|
],
|
||||||
|
'im_livechat.assets_embed_external': [
|
||||||
|
'web/static/src/libs/fontawesome/css/font-awesome.css',
|
||||||
|
'im_livechat/static/src/embed/common/scss/bootstrap_overridden.scss',
|
||||||
|
('include', 'web._assets_helpers'),
|
||||||
|
('include', 'web._assets_backend_helpers'),
|
||||||
|
'web/static/src/scss/pre_variables.scss',
|
||||||
|
'web/static/lib/bootstrap/scss/_variables.scss',
|
||||||
|
('include', 'web._assets_bootstrap_backend'),
|
||||||
|
'web/static/src/scss/bootstrap_overridden.scss',
|
||||||
|
'web/static/src/webclient/webclient.scss',
|
||||||
|
('include', 'web._assets_core'),
|
||||||
|
'web/static/src/libs/pdfjs.js',
|
||||||
|
'web/static/src/views/fields/formatters.js',
|
||||||
|
'web/static/src/views/fields/file_handler.*',
|
||||||
|
'web/static/src/scss/mimetypes.scss',
|
||||||
|
'bus/static/src/*.js',
|
||||||
|
'bus/static/src/services/**/*.js',
|
||||||
|
'bus/static/src/workers/websocket_worker.js',
|
||||||
|
'bus/static/src/workers/websocket_worker_utils.js',
|
||||||
|
('remove', 'bus/static/src/services/assets_watchdog_service.js'),
|
||||||
|
('remove', 'bus/static/src/simple_notification_service.js'),
|
||||||
|
('include', 'im_livechat.assets_embed_core'),
|
||||||
|
'im_livechat/static/src/embed/external/**/*',
|
||||||
|
],
|
||||||
|
'im_livechat.assets_embed_cors': [
|
||||||
|
('include', 'im_livechat.assets_embed_external'),
|
||||||
|
'im_livechat/static/src/embed/cors/**/*',
|
||||||
|
],
|
||||||
|
'im_livechat.embed_test_assets': [
|
||||||
|
('include', 'web.tests_assets'),
|
||||||
|
('remove', 'web/static/tests/mock_server_tests.js'),
|
||||||
|
('remove', 'im_livechat/static/**'),
|
||||||
|
'im_livechat/static/tests/helpers/**',
|
||||||
|
('include', 'im_livechat.assets_embed_core'),
|
||||||
|
],
|
||||||
|
'im_livechat.qunit_embed_suite': [
|
||||||
|
'im_livechat/static/tests/embed/**/*',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'license': 'LGPL-3',
|
||||||
|
}
|
8
controllers/__init__.py
Normal file
8
controllers/__init__.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from . import attachment
|
||||||
|
from . import chatbot
|
||||||
|
from . import main
|
||||||
|
from . import webclient
|
||||||
|
from . import cors
|
26
controllers/attachment.py
Normal file
26
controllers/attachment.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from werkzeug.exceptions import NotFound
|
||||||
|
|
||||||
|
from odoo import _
|
||||||
|
from odoo.http import route, request
|
||||||
|
from odoo.addons.mail.controllers.attachment import AttachmentController
|
||||||
|
from odoo.exceptions import AccessError
|
||||||
|
from odoo.addons.mail.models.discuss.mail_guest import add_guest_to_context
|
||||||
|
|
||||||
|
|
||||||
|
class LivechatAttachmentController(AttachmentController):
|
||||||
|
@route()
|
||||||
|
@add_guest_to_context
|
||||||
|
def mail_attachment_upload(self, ufile, thread_id, thread_model, is_pending=False, **kwargs):
|
||||||
|
thread = request.env[thread_model].with_context(active_test=False).search([("id", "=", thread_id)])
|
||||||
|
if not thread:
|
||||||
|
raise NotFound()
|
||||||
|
if (
|
||||||
|
thread_model == "discuss.channel"
|
||||||
|
and thread.channel_type == "livechat"
|
||||||
|
and not thread.livechat_active
|
||||||
|
and not request.env.user._is_internal()
|
||||||
|
):
|
||||||
|
raise AccessError(_("You are not allowed to upload attachments on this channel."))
|
||||||
|
return super().mail_attachment_upload(ufile, thread_id, thread_model, is_pending, **kwargs)
|
106
controllers/chatbot.py
Normal file
106
controllers/chatbot.py
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from odoo import http
|
||||||
|
from odoo.http import request
|
||||||
|
from odoo.tools import get_lang, is_html_empty, plaintext2html
|
||||||
|
|
||||||
|
|
||||||
|
class LivechatChatbotScriptController(http.Controller):
|
||||||
|
@http.route('/chatbot/restart', type="json", auth="public", cors="*")
|
||||||
|
def chatbot_restart(self, channel_uuid, chatbot_script_id):
|
||||||
|
discuss_channel = request.env['discuss.channel'].sudo().search([('uuid', '=', channel_uuid)], limit=1)
|
||||||
|
chatbot = request.env['chatbot.script'].browse(chatbot_script_id)
|
||||||
|
if not discuss_channel or not chatbot.exists():
|
||||||
|
return None
|
||||||
|
chatbot_language = self._get_chatbot_language()
|
||||||
|
return discuss_channel.with_context(lang=chatbot_language)._chatbot_restart(chatbot).message_format()[0]
|
||||||
|
|
||||||
|
@http.route('/chatbot/post_welcome_steps', type="json", auth="public", cors="*")
|
||||||
|
def chatbot_post_welcome_steps(self, channel_uuid, chatbot_script_id):
|
||||||
|
discuss_channel = request.env['discuss.channel'].sudo().search([('uuid', '=', channel_uuid)], limit=1)
|
||||||
|
chatbot = request.env['chatbot.script'].sudo().browse(chatbot_script_id)
|
||||||
|
if not discuss_channel or not chatbot.exists():
|
||||||
|
return None
|
||||||
|
chatbot_language = self._get_chatbot_language()
|
||||||
|
return chatbot.with_context(lang=chatbot_language)._post_welcome_steps(discuss_channel).message_format()
|
||||||
|
|
||||||
|
@http.route('/chatbot/answer/save', type="json", auth="public", cors="*")
|
||||||
|
def chatbot_save_answer(self, channel_uuid, message_id, selected_answer_id):
|
||||||
|
discuss_channel = request.env['discuss.channel'].sudo().search([('uuid', '=', channel_uuid)], limit=1)
|
||||||
|
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="json", auth="public", cors="*")
|
||||||
|
def chatbot_trigger_step(self, channel_uuid, chatbot_script_id=None):
|
||||||
|
chatbot_language = self._get_chatbot_language()
|
||||||
|
discuss_channel = request.env['discuss.channel'].with_context(lang=chatbot_language).sudo().search([('uuid', '=', channel_uuid)], limit=1)
|
||||||
|
if not discuss_channel:
|
||||||
|
return None
|
||||||
|
|
||||||
|
next_step = False
|
||||||
|
if discuss_channel.chatbot_current_step_id:
|
||||||
|
chatbot = discuss_channel.chatbot_current_step_id.chatbot_script_id
|
||||||
|
user_messages = discuss_channel.message_ids.filtered(
|
||||||
|
lambda message: message.author_id != chatbot.operator_partner_id
|
||||||
|
)
|
||||||
|
user_answer = request.env['mail.message'].sudo()
|
||||||
|
if user_messages:
|
||||||
|
user_answer = user_messages.sorted(lambda message: message.id)[-1]
|
||||||
|
next_step = discuss_channel.chatbot_current_step_id._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)
|
||||||
|
if chatbot.exists():
|
||||||
|
next_step = chatbot.script_step_ids[:1]
|
||||||
|
|
||||||
|
if not next_step:
|
||||||
|
return None
|
||||||
|
|
||||||
|
posted_message = next_step._process_step(discuss_channel)
|
||||||
|
return {
|
||||||
|
'chatbot_posted_message': posted_message.message_format()[0] if posted_message else None,
|
||||||
|
'chatbot_step': {
|
||||||
|
'operatorFound': next_step.step_type == 'forward_operator' and len(
|
||||||
|
discuss_channel.channel_member_ids) > 2,
|
||||||
|
'id': next_step.id,
|
||||||
|
'answers': [{
|
||||||
|
'id': answer.id,
|
||||||
|
'label': answer.name,
|
||||||
|
'redirectLink': answer.redirect_link,
|
||||||
|
} for answer in next_step.answer_ids],
|
||||||
|
'isLast': next_step._is_last_step(discuss_channel),
|
||||||
|
'message': plaintext2html(next_step.message) if not is_html_empty(next_step.message) else False,
|
||||||
|
'type': next_step.step_type,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@http.route('/chatbot/step/validate_email', type="json", auth="public", cors="*")
|
||||||
|
def chatbot_validate_email(self, channel_uuid):
|
||||||
|
discuss_channel = request.env['discuss.channel'].sudo().search([('uuid', '=', channel_uuid)], limit=1)
|
||||||
|
if not discuss_channel or not discuss_channel.chatbot_current_step_id:
|
||||||
|
return None
|
||||||
|
|
||||||
|
chatbot = discuss_channel.chatbot_current_step_id.chatbot_script_id
|
||||||
|
user_messages = discuss_channel.message_ids.filtered(
|
||||||
|
lambda message: message.author_id != chatbot.operator_partner_id
|
||||||
|
)
|
||||||
|
|
||||||
|
if user_messages:
|
||||||
|
user_answer = user_messages.sorted(lambda message: message.id)[-1]
|
||||||
|
result = chatbot._validate_email(user_answer.body, discuss_channel)
|
||||||
|
|
||||||
|
if result['posted_message']:
|
||||||
|
result['posted_message'] = result['posted_message'].message_format()[0]
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def _get_chatbot_language(self):
|
||||||
|
return request.httprequest.cookies.get('frontend_lang', request.env.user.lang or get_lang(request.env).code)
|
11
controllers/cors/__init__.py
Normal file
11
controllers/cors/__init__.py
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from . import attachment
|
||||||
|
from . import binary
|
||||||
|
from . import channel
|
||||||
|
from . import link_preview
|
||||||
|
from . import main
|
||||||
|
from . import message_reaction
|
||||||
|
from . import rtc
|
||||||
|
from . import thread
|
||||||
|
from . import webclient
|
15
controllers/cors/attachment.py
Normal file
15
controllers/cors/attachment.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
from odoo.http import route
|
||||||
|
from odoo.addons.mail.controllers.attachment import AttachmentController
|
||||||
|
from odoo.addons.im_livechat.tools.misc import force_guest_env
|
||||||
|
|
||||||
|
|
||||||
|
class LivechatAttachmentController(AttachmentController):
|
||||||
|
@route("/im_livechat/cors/attachment/upload", auth="public", cors="*", csrf=False)
|
||||||
|
def im_livechat_attachment_upload(self, guest_token, ufile, thread_id, thread_model, is_pending=False, **kwargs):
|
||||||
|
force_guest_env(guest_token)
|
||||||
|
return self.mail_attachment_upload(ufile, thread_id, thread_model, is_pending, **kwargs)
|
||||||
|
|
||||||
|
@route("/im_livechat/cors/attachment/delete", methods=["POST"], type="json", auth="public", cors="*")
|
||||||
|
def im_livechat_attachment_delete(self, guest_token, attachment_id, access_token=None):
|
||||||
|
force_guest_env(guest_token)
|
||||||
|
return self.mail_attachment_delete(attachment_id, access_token)
|
55
controllers/cors/binary.py
Normal file
55
controllers/cors/binary.py
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
|
||||||
|
from odoo.http import route
|
||||||
|
from odoo.addons.mail.controllers.discuss.binary import BinaryController
|
||||||
|
from odoo.addons.im_livechat.tools.misc import force_guest_env
|
||||||
|
|
||||||
|
|
||||||
|
class LivechatBinaryController(BinaryController):
|
||||||
|
@route(
|
||||||
|
"/im_livechat/cors/channel/<int:channel_id>/attachment/<int:attachment_id>",
|
||||||
|
methods=["GET"],
|
||||||
|
type="http",
|
||||||
|
auth="public",
|
||||||
|
cors="*",
|
||||||
|
)
|
||||||
|
def livechat_channel_attachment(self, guest_token, channel_id, attachment_id, download=None, **kwargs):
|
||||||
|
force_guest_env(guest_token)
|
||||||
|
return self.discuss_channel_attachment(channel_id, attachment_id, download, **kwargs)
|
||||||
|
|
||||||
|
@route(
|
||||||
|
[
|
||||||
|
"/im_livechat/cors/channel/<int:channel_id>/image/<int:attachment_id>",
|
||||||
|
"/im_livechat/cors/channel/<int:channel_id>/image/<int:attachment_id>/<int:width>x<int:height>",
|
||||||
|
],
|
||||||
|
methods=["GET"],
|
||||||
|
type="http",
|
||||||
|
auth="public",
|
||||||
|
cors="*"
|
||||||
|
)
|
||||||
|
def livechat_fetch_image(self, guest_token, channel_id, attachment_id, width=0, height=0, **kwargs):
|
||||||
|
force_guest_env(guest_token)
|
||||||
|
return self.fetch_image(channel_id, attachment_id, width, height, **kwargs)
|
||||||
|
|
||||||
|
@route(
|
||||||
|
"/im_livechat/cors/channel/<int:channel_id>/partner/<int:partner_id>/avatar_128",
|
||||||
|
methods=["GET"],
|
||||||
|
type="http",
|
||||||
|
auth="public",
|
||||||
|
cors="*",
|
||||||
|
)
|
||||||
|
def livechat_channel_partner_avatar_128(self, guest_token, channel_id, partner_id, unique=False):
|
||||||
|
force_guest_env(guest_token)
|
||||||
|
return self.discuss_channel_partner_avatar_128(channel_id, partner_id, unique=unique)
|
||||||
|
|
||||||
|
@route(
|
||||||
|
"/im_livechat/cors/channel/<int:channel_id>/guest/<int:guest_id>/avatar_128",
|
||||||
|
methods=["GET"],
|
||||||
|
type="http",
|
||||||
|
auth="public",
|
||||||
|
cors="*",
|
||||||
|
)
|
||||||
|
def livechat_channel_guest_avatar_128(self, guest_token, channel_id, guest_id, unique=False):
|
||||||
|
force_guest_env(guest_token)
|
||||||
|
return self.discuss_channel_guest_avatar_128(channel_id, guest_id, unique=unique)
|
17
controllers/cors/channel.py
Normal file
17
controllers/cors/channel.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from odoo.http import route
|
||||||
|
from odoo.addons.mail.controllers.discuss.channel import ChannelController
|
||||||
|
from odoo.addons.im_livechat.tools.misc import force_guest_env
|
||||||
|
|
||||||
|
|
||||||
|
class LivechatChannelController(ChannelController):
|
||||||
|
@route("/im_livechat/cors/channel/messages", methods=["POST"], type="json", auth="public", cors="*")
|
||||||
|
def livechat_channel_messages(self, guest_token, channel_id, before=None, after=None, limit=30, around=None):
|
||||||
|
force_guest_env(guest_token)
|
||||||
|
return self.discuss_channel_messages(channel_id, before, after, limit, around)
|
||||||
|
|
||||||
|
@route("/im_livechat/cors/channel/set_last_seen_message", methods=["POST"], type="json", auth="public", cors="*")
|
||||||
|
def livechat_channel_mark_as_seen(self, guest_token, channel_id, last_message_id, allow_older=False):
|
||||||
|
force_guest_env(guest_token)
|
||||||
|
return self.discuss_channel_mark_as_seen(channel_id, last_message_id, allow_older)
|
17
controllers/cors/link_preview.py
Normal file
17
controllers/cors/link_preview.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from odoo.http import route
|
||||||
|
from odoo.addons.mail.controllers.link_preview import LinkPreviewController
|
||||||
|
from odoo.addons.im_livechat.tools.misc import force_guest_env
|
||||||
|
|
||||||
|
|
||||||
|
class LivechatLinkPreviewController(LinkPreviewController):
|
||||||
|
@route("/im_livechat/cors/link_preview", methods=["POST"], type="json", auth="public", cors="*")
|
||||||
|
def livechat_link_preview(self, guest_token, message_id, clear=None):
|
||||||
|
force_guest_env(guest_token)
|
||||||
|
self.mail_link_preview(message_id, clear)
|
||||||
|
|
||||||
|
@route("/im_livechat/cors/link_preview/delete", methods=["POST"], type="json", auth="public", cors="*")
|
||||||
|
def livechat_link_preview_delete(self, guest_token, link_preview_ids):
|
||||||
|
force_guest_env(guest_token)
|
||||||
|
self.mail_link_preview_delete(link_preview_ids)
|
21
controllers/cors/main.py
Normal file
21
controllers/cors/main.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from odoo.http import route
|
||||||
|
from odoo.addons.im_livechat.controllers.main import LivechatController
|
||||||
|
from odoo.addons.im_livechat.tools.misc import force_guest_env
|
||||||
|
|
||||||
|
|
||||||
|
class CorsLivechatController(LivechatController):
|
||||||
|
@route("/im_livechat/cors/visitor_leave_session", type="json", auth="public", cors="*")
|
||||||
|
def cors_visitor_leave_session(self, guest_token, uuid):
|
||||||
|
force_guest_env(guest_token)
|
||||||
|
self.visitor_leave_session(uuid)
|
||||||
|
|
||||||
|
@route("/im_livechat/cors/get_session", methods=["POST"], type="json", auth="public", cors="*")
|
||||||
|
def cors_get_session(
|
||||||
|
self, channel_id, anonymous_name, previous_operator_id=None, chatbot_script_id=None, persisted=True, **kwargs
|
||||||
|
):
|
||||||
|
force_guest_env(kwargs.get("guest_token", ""), raise_if_not_found=False)
|
||||||
|
return self.get_session(
|
||||||
|
channel_id, anonymous_name, previous_operator_id, chatbot_script_id, persisted, **kwargs
|
||||||
|
)
|
12
controllers/cors/message_reaction.py
Normal file
12
controllers/cors/message_reaction.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from odoo.http import route
|
||||||
|
from odoo.addons.mail.controllers.message_reaction import MessageReactionController
|
||||||
|
from odoo.addons.im_livechat.tools.misc import force_guest_env
|
||||||
|
|
||||||
|
|
||||||
|
class LivechatMessageReactionController(MessageReactionController):
|
||||||
|
@route("/im_livechat/cors/message/reaction", methods=["POST"], type="json", auth="public", cors="*")
|
||||||
|
def livechat_message_add_reaction(self, guest_token, message_id, content, action):
|
||||||
|
force_guest_env(guest_token)
|
||||||
|
return self.mail_message_add_reaction(message_id, content, action)
|
32
controllers/cors/rtc.py
Normal file
32
controllers/cors/rtc.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from odoo.http import route
|
||||||
|
from odoo.addons.mail.controllers.discuss.rtc import RtcController
|
||||||
|
from odoo.addons.im_livechat.tools.misc import force_guest_env
|
||||||
|
|
||||||
|
|
||||||
|
class LivechatRtcController(RtcController):
|
||||||
|
@route("/im_livechat/cors/rtc/channel/join_call", methods=["POST"], type="json", auth="public", cors="*")
|
||||||
|
def livechat_channel_call_join(self, guest_token, channel_id, check_rtc_session_ids=None):
|
||||||
|
force_guest_env(guest_token)
|
||||||
|
return self.channel_call_join(channel_id, check_rtc_session_ids)
|
||||||
|
|
||||||
|
@route("/im_livechat/cors/rtc/channel/leave_call", methods=["POST"], type="json", auth="public", cors="*")
|
||||||
|
def livechat_channel_call_leave(self, guest_token, channel_id):
|
||||||
|
force_guest_env(guest_token)
|
||||||
|
return self.channel_call_leave(channel_id)
|
||||||
|
|
||||||
|
@route("/im_livechat/cors/rtc/session/update_and_broadcast", methods=["POST"], type="json", auth="public", cors="*")
|
||||||
|
def livechat_session_update_and_broadcast(self, guest_token, session_id, values):
|
||||||
|
force_guest_env(guest_token)
|
||||||
|
self.session_update_and_broadcast(session_id, values)
|
||||||
|
|
||||||
|
@route("/im_livechat/cors/rtc/session/notify_call_members", methods=["POST"], type="json", auth="public", cors="*")
|
||||||
|
def livechat_session_call_notify(self, guest_token, peer_notifications):
|
||||||
|
force_guest_env(guest_token)
|
||||||
|
self.session_call_notify(peer_notifications)
|
||||||
|
|
||||||
|
@route("/im_livechat/cors/channel/ping", methods=["POST"], type="json", auth="public", cors="*")
|
||||||
|
def livechat_channel_ping(self, guest_token, channel_id, rtc_session_id=None, check_rtc_session_ids=None):
|
||||||
|
force_guest_env(guest_token)
|
||||||
|
return self.channel_ping(channel_id, rtc_session_id, check_rtc_session_ids)
|
19
controllers/cors/thread.py
Normal file
19
controllers/cors/thread.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from odoo.http import route
|
||||||
|
from odoo.addons.mail.controllers.thread import ThreadController
|
||||||
|
from odoo.addons.im_livechat.tools.misc import force_guest_env
|
||||||
|
|
||||||
|
|
||||||
|
class LivechatThreadController(ThreadController):
|
||||||
|
@route("/im_livechat/cors/message/post", methods=["POST"], type="json", auth="public", cors="*")
|
||||||
|
def livechat_message_post(self, guest_token, thread_model, thread_id, post_data, context=None):
|
||||||
|
force_guest_env(guest_token)
|
||||||
|
return self.mail_message_post(thread_model, thread_id, post_data, context)
|
||||||
|
|
||||||
|
@route("/im_livechat/cors/message/update_content", methods=["POST"], type="json", auth="public", cors="*")
|
||||||
|
def livechat_message_update_content(
|
||||||
|
self, guest_token, message_id, body, attachment_ids, attachment_tokens=None, partner_ids=None
|
||||||
|
):
|
||||||
|
force_guest_env(guest_token)
|
||||||
|
return self.mail_message_update_content(message_id, body, attachment_ids, attachment_tokens, partner_ids)
|
12
controllers/cors/webclient.py
Normal file
12
controllers/cors/webclient.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from odoo.http import route
|
||||||
|
from odoo.addons.mail.controllers.webclient import WebclientController
|
||||||
|
from odoo.addons.im_livechat.tools.misc import force_guest_env
|
||||||
|
|
||||||
|
|
||||||
|
class WebClient(WebclientController):
|
||||||
|
@route("/im_livechat/cors/init_messaging", methods=["POST"], type="json", auth="public", cors="*")
|
||||||
|
def livechat_init_messaging(self, guest_token):
|
||||||
|
force_guest_env(guest_token)
|
||||||
|
return self.mail_init_messaging()
|
287
controllers/main.py
Normal file
287
controllers/main.py
Normal file
@ -0,0 +1,287 @@
|
|||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from markupsafe import Markup
|
||||||
|
import re
|
||||||
|
from werkzeug.exceptions import NotFound
|
||||||
|
from urllib.parse import urlsplit
|
||||||
|
|
||||||
|
from odoo import http, tools, _, release
|
||||||
|
from odoo.exceptions import UserError
|
||||||
|
from odoo.http import request
|
||||||
|
from odoo.tools import replace_exceptions
|
||||||
|
from odoo.addons.base.models.assetsbundle import AssetsBundle
|
||||||
|
from odoo.addons.mail.models.discuss.mail_guest import add_guest_to_context
|
||||||
|
|
||||||
|
|
||||||
|
class LivechatController(http.Controller):
|
||||||
|
|
||||||
|
# Note: the `cors` attribute on many routes is meant to allow the livechat
|
||||||
|
# to be embedded in an external website.
|
||||||
|
|
||||||
|
@http.route('/im_livechat/external_lib.<any(css,js):ext>', type='http', auth='public', cors='*')
|
||||||
|
def external_lib(self, ext, **kwargs):
|
||||||
|
""" Preserve compatibility with legacy livechat imports. Only
|
||||||
|
serves javascript since the css will be fetched by the shadow
|
||||||
|
DOM of the livechat to avoid conflicts.
|
||||||
|
"""
|
||||||
|
if ext == 'css':
|
||||||
|
raise request.not_found()
|
||||||
|
return self.assets_embed(ext, **kwargs)
|
||||||
|
|
||||||
|
@http.route('/im_livechat/assets_embed.<any(css, js):ext>', type='http', auth='public', cors='*')
|
||||||
|
def assets_embed(self, ext, **kwargs):
|
||||||
|
# If the request comes from a different origin, we must provide the CORS
|
||||||
|
# assets to enable the redirection of routes to the CORS controller.
|
||||||
|
headers = request.httprequest.headers
|
||||||
|
origin_url = urlsplit(headers.get('referer'))
|
||||||
|
bundle = 'im_livechat.assets_embed_external'
|
||||||
|
if origin_url.netloc != headers.get('host') or origin_url.scheme != request.httprequest.scheme:
|
||||||
|
bundle = 'im_livechat.assets_embed_cors'
|
||||||
|
asset = request.env["ir.qweb"]._get_asset_bundle(bundle)
|
||||||
|
if ext not in ('css', 'js'):
|
||||||
|
raise request.not_found()
|
||||||
|
stream = request.env['ir.binary']._get_stream_from(getattr(asset, ext)())
|
||||||
|
return stream.get_response()
|
||||||
|
|
||||||
|
@http.route('/im_livechat/font-awesome', type='http', auth='none', cors="*")
|
||||||
|
def fontawesome(self, **kwargs):
|
||||||
|
return http.Stream.from_path('web/static/src/libs/fontawesome/fonts/fontawesome-webfont.woff2').get_response()
|
||||||
|
|
||||||
|
@http.route('/im_livechat/odoo_ui_icons', type='http', auth='none', cors="*")
|
||||||
|
def odoo_ui_icons(self, **kwargs):
|
||||||
|
return http.Stream.from_path('web/static/lib/odoo_ui_icons/fonts/odoo_ui_icons.woff2').get_response()
|
||||||
|
|
||||||
|
@http.route('/im_livechat/emoji_bundle', type='http', auth='public', cors='*')
|
||||||
|
def get_emoji_bundle(self):
|
||||||
|
bundle = 'web.assets_emoji'
|
||||||
|
asset = request.env["ir.qweb"]._get_asset_bundle(bundle)
|
||||||
|
stream = request.env['ir.binary']._get_stream_from(asset.js())
|
||||||
|
return stream.get_response()
|
||||||
|
|
||||||
|
@http.route('/im_livechat/load_templates', type='json', auth='none', cors="*")
|
||||||
|
def load_templates(self, **kwargs):
|
||||||
|
templates = self._livechat_templates_get()
|
||||||
|
return [tools.file_open(tmpl, 'rb').read() for tmpl in templates]
|
||||||
|
|
||||||
|
def _livechat_templates_get(self):
|
||||||
|
return [
|
||||||
|
'im_livechat/static/src/legacy/widgets/feedback/feedback.xml',
|
||||||
|
'im_livechat/static/src/legacy/widgets/public_livechat_window/public_livechat_window.xml',
|
||||||
|
'im_livechat/static/src/legacy/widgets/public_livechat_view/public_livechat_view.xml',
|
||||||
|
'im_livechat/static/src/legacy/public_livechat_chatbot.xml',
|
||||||
|
]
|
||||||
|
|
||||||
|
@http.route('/im_livechat/support/<int:channel_id>', type='http', auth='public')
|
||||||
|
def support_page(self, channel_id, **kwargs):
|
||||||
|
channel = request.env['im_livechat.channel'].sudo().browse(channel_id)
|
||||||
|
return request.render('im_livechat.support_page', {'channel': channel})
|
||||||
|
|
||||||
|
@http.route('/im_livechat/loader/<int:channel_id>', type='http', auth='public')
|
||||||
|
def loader(self, channel_id, **kwargs):
|
||||||
|
username = kwargs.get("username", _("Visitor"))
|
||||||
|
channel = request.env['im_livechat.channel'].sudo().browse(channel_id)
|
||||||
|
info = channel.get_livechat_info(username=username)
|
||||||
|
return request.render('im_livechat.loader', {'info': info}, headers=[('Content-Type', 'application/javascript')])
|
||||||
|
|
||||||
|
@http.route('/im_livechat/init', type='json', auth="public", cors="*")
|
||||||
|
def livechat_init(self, channel_id):
|
||||||
|
operator_available = len(request.env['im_livechat.channel'].sudo().browse(channel_id).available_operator_ids)
|
||||||
|
rule = {}
|
||||||
|
# find the country from the request
|
||||||
|
country_id = False
|
||||||
|
if request.geoip.country_code:
|
||||||
|
country_id = request.env['res.country'].sudo().search([('code', '=', request.geoip.country_code)], limit=1).id
|
||||||
|
# extract url
|
||||||
|
url = request.httprequest.headers.get('Referer')
|
||||||
|
# find the first matching rule for the given country and url
|
||||||
|
matching_rule = request.env['im_livechat.channel.rule'].sudo().match_rule(channel_id, url, country_id)
|
||||||
|
if matching_rule and (not matching_rule.chatbot_script_id or matching_rule.chatbot_script_id.script_step_ids):
|
||||||
|
frontend_lang = request.httprequest.cookies.get('frontend_lang', request.env.user.lang or 'en_US')
|
||||||
|
matching_rule = matching_rule.with_context(lang=frontend_lang)
|
||||||
|
rule = {
|
||||||
|
'action': matching_rule.action,
|
||||||
|
'auto_popup_timer': matching_rule.auto_popup_timer,
|
||||||
|
'regex_url': matching_rule.regex_url,
|
||||||
|
}
|
||||||
|
if matching_rule.chatbot_script_id.active and (not matching_rule.chatbot_only_if_no_operator or
|
||||||
|
(not operator_available and matching_rule.chatbot_only_if_no_operator)) and matching_rule.chatbot_script_id.script_step_ids:
|
||||||
|
chatbot_script = matching_rule.chatbot_script_id
|
||||||
|
rule.update({'chatbot': chatbot_script._format_for_frontend()})
|
||||||
|
return {
|
||||||
|
'odoo_version': release.version,
|
||||||
|
'available_for_me': (rule and rule.get('chatbot'))
|
||||||
|
or operator_available and (not rule or rule['action'] != 'hide_button'),
|
||||||
|
'rule': rule,
|
||||||
|
}
|
||||||
|
|
||||||
|
@http.route('/im_livechat/operator/<int:operator_id>/avatar',
|
||||||
|
type='http', auth="public", cors="*")
|
||||||
|
def livechat_operator_get_avatar(self, operator_id):
|
||||||
|
""" Custom route allowing to retrieve an operator's avatar.
|
||||||
|
|
||||||
|
This is done to bypass more complicated rules, notably 'website_published' when the website
|
||||||
|
module is installed.
|
||||||
|
|
||||||
|
Here, we assume that if you are a member of at least one im_livechat.channel, then it's ok
|
||||||
|
to make your avatar publicly available.
|
||||||
|
|
||||||
|
We also make the chatbot operator avatars publicly available. """
|
||||||
|
|
||||||
|
is_livechat_member = False
|
||||||
|
operator = request.env['res.partner'].sudo().browse(operator_id)
|
||||||
|
if operator.exists():
|
||||||
|
is_livechat_member = bool(request.env['im_livechat.channel'].sudo().search_count([
|
||||||
|
('user_ids', 'in', operator.user_ids.ids)
|
||||||
|
]))
|
||||||
|
|
||||||
|
if not is_livechat_member:
|
||||||
|
# we don't put chatbot operators as livechat members (because we don't have a user_id for them)
|
||||||
|
is_livechat_member = bool(request.env['chatbot.script'].sudo().search_count([
|
||||||
|
('operator_partner_id', 'in', operator.ids)
|
||||||
|
]))
|
||||||
|
|
||||||
|
return request.env['ir.binary']._get_image_stream_from(
|
||||||
|
operator if is_livechat_member else request.env['res.partner'],
|
||||||
|
field_name='avatar_128',
|
||||||
|
placeholder='mail/static/src/img/smiley/avatar.jpg',
|
||||||
|
).get_response()
|
||||||
|
|
||||||
|
def _get_guest_name(self):
|
||||||
|
return _("Visitor")
|
||||||
|
|
||||||
|
@http.route('/im_livechat/get_session', methods=["POST"], type="json", auth='public')
|
||||||
|
@add_guest_to_context
|
||||||
|
def get_session(self, channel_id, anonymous_name, previous_operator_id=None, chatbot_script_id=None, persisted=True, **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.
|
||||||
|
if request.session.uid:
|
||||||
|
user_id = request.env.user.id
|
||||||
|
country_id = request.env.user.country_id.id
|
||||||
|
else:
|
||||||
|
# if geoip, add the country name to the anonymous name
|
||||||
|
if request.geoip.country_code:
|
||||||
|
# get the country of the anonymous person, if any
|
||||||
|
country = request.env['res.country'].sudo().search([('code', '=', request.geoip.country_code)], limit=1)
|
||||||
|
if country:
|
||||||
|
country_id = country.id
|
||||||
|
|
||||||
|
if previous_operator_id:
|
||||||
|
previous_operator_id = int(previous_operator_id)
|
||||||
|
|
||||||
|
chatbot_script = False
|
||||||
|
if chatbot_script_id:
|
||||||
|
frontend_lang = request.httprequest.cookies.get('frontend_lang', request.env.user.lang or 'en_US')
|
||||||
|
chatbot_script = request.env['chatbot.script'].sudo().with_context(lang=frontend_lang).browse(chatbot_script_id)
|
||||||
|
channel_vals = request.env["im_livechat.channel"].with_context(lang=False).sudo().browse(channel_id)._get_livechat_discuss_channel_vals(
|
||||||
|
anonymous_name,
|
||||||
|
previous_operator_id=previous_operator_id,
|
||||||
|
chatbot_script=chatbot_script,
|
||||||
|
user_id=user_id,
|
||||||
|
country_id=country_id,
|
||||||
|
lang=request.httprequest.cookies.get('frontend_lang')
|
||||||
|
)
|
||||||
|
if not channel_vals:
|
||||||
|
return False
|
||||||
|
if not persisted:
|
||||||
|
operator_partner = request.env['res.partner'].sudo().browse(channel_vals['livechat_operator_id'])
|
||||||
|
display_name = operator_partner.user_livechat_username or operator_partner.display_name
|
||||||
|
return {
|
||||||
|
'name': channel_vals['name'],
|
||||||
|
'chatbot_current_step_id': channel_vals['chatbot_current_step_id'],
|
||||||
|
'state': 'open',
|
||||||
|
'operator_pid': (operator_partner.id, display_name.replace(',', '')),
|
||||||
|
'chatbot_script_id': chatbot_script.id if chatbot_script else None
|
||||||
|
}
|
||||||
|
channel = request.env['discuss.channel'].with_context(mail_create_nosubscribe=False).sudo().create(channel_vals)
|
||||||
|
with replace_exceptions(UserError, by=NotFound()):
|
||||||
|
# sudo: mail.guest - creating a guest and their member in a dedicated channel created from livechat
|
||||||
|
__, guest = channel.sudo()._find_or_create_persona_for_channel(
|
||||||
|
guest_name=self._get_guest_name(),
|
||||||
|
country_code=request.geoip.country_code,
|
||||||
|
timezone=request.env['mail.guest']._get_timezone_from_request(request),
|
||||||
|
post_joined_message=False
|
||||||
|
)
|
||||||
|
channel = channel.with_context(guest=guest) # a new guest was possibly created
|
||||||
|
if not chatbot_script or chatbot_script.operator_partner_id != channel.livechat_operator_id:
|
||||||
|
channel._broadcast([channel.livechat_operator_id.id])
|
||||||
|
channel_info = channel._channel_info()[0]
|
||||||
|
if guest:
|
||||||
|
channel_info['guest_token'] = guest._format_auth_cookie()
|
||||||
|
return channel_info
|
||||||
|
|
||||||
|
def _post_feedback_message(self, channel, rating, reason):
|
||||||
|
reason = Markup("<br>" + re.sub(r'\r\n|\r|\n', "<br>", reason) if reason else "")
|
||||||
|
body = Markup('''
|
||||||
|
<div class="o_mail_notification o_hide_author">
|
||||||
|
%(rating)s: <img class="o_livechat_emoji_rating" src="%(rating_url)s" alt="rating"/>%(reason)s
|
||||||
|
</div>
|
||||||
|
''') % {
|
||||||
|
'rating': _('Rating'),
|
||||||
|
'rating_url': rating.rating_image_url,
|
||||||
|
'reason': reason,
|
||||||
|
}
|
||||||
|
channel.message_post(body=body, message_type='notification', subtype_xmlid='mail.mt_comment')
|
||||||
|
|
||||||
|
@http.route('/im_livechat/feedback', type='json', auth='public', cors="*")
|
||||||
|
def feedback(self, uuid, rate, reason=None, **kwargs):
|
||||||
|
channel = request.env['discuss.channel'].sudo().search([('uuid', '=', uuid)], limit=1)
|
||||||
|
if channel:
|
||||||
|
# limit the creation : only ONE rating per session
|
||||||
|
values = {
|
||||||
|
'rating': rate,
|
||||||
|
'consumed': True,
|
||||||
|
'feedback': reason,
|
||||||
|
'is_internal': False,
|
||||||
|
}
|
||||||
|
if not channel.rating_ids:
|
||||||
|
values.update({
|
||||||
|
'res_id': channel.id,
|
||||||
|
'res_model_id': request.env['ir.model']._get_id('discuss.channel'),
|
||||||
|
})
|
||||||
|
# find the partner (operator)
|
||||||
|
if channel.channel_partner_ids:
|
||||||
|
values['rated_partner_id'] = channel.channel_partner_ids[0].id
|
||||||
|
# if logged in user, set its partner on rating
|
||||||
|
values['partner_id'] = request.env.user.partner_id.id if request.session.uid else False
|
||||||
|
# create the rating
|
||||||
|
rating = request.env['rating.rating'].sudo().create(values)
|
||||||
|
else:
|
||||||
|
rating = channel.rating_ids[0]
|
||||||
|
rating.write(values)
|
||||||
|
self._post_feedback_message(channel, rating, reason)
|
||||||
|
return rating.id
|
||||||
|
return False
|
||||||
|
|
||||||
|
@http.route('/im_livechat/history', type="json", auth="public", cors="*")
|
||||||
|
def history_pages(self, pid, channel_uuid, page_history=None):
|
||||||
|
partner_ids = (pid, request.env.user.partner_id.id)
|
||||||
|
channel = request.env['discuss.channel'].sudo().search([('uuid', '=', channel_uuid), ('channel_partner_ids', 'in', partner_ids)])
|
||||||
|
if channel:
|
||||||
|
channel._send_history_message(pid, page_history)
|
||||||
|
return True
|
||||||
|
|
||||||
|
@http.route('/im_livechat/email_livechat_transcript', type='json', auth='public', cors="*")
|
||||||
|
def email_livechat_transcript(self, uuid, email):
|
||||||
|
channel = request.env['discuss.channel'].sudo().search([
|
||||||
|
('channel_type', '=', 'livechat'),
|
||||||
|
('uuid', '=', uuid)], limit=1)
|
||||||
|
if channel:
|
||||||
|
channel._email_livechat_transcript(email)
|
||||||
|
|
||||||
|
@http.route("/im_livechat/visitor_leave_session", type="json", auth="public")
|
||||||
|
@add_guest_to_context
|
||||||
|
def visitor_leave_session(self, uuid):
|
||||||
|
"""Called when the livechat visitor leaves the conversation.
|
||||||
|
This will clean the chat request and warn the operator that the conversation is over.
|
||||||
|
This allows also to re-send a new chat request to the visitor, as while the visitor is
|
||||||
|
in conversation with an operator, it's not possible to send the visitor a chat request."""
|
||||||
|
# sudo: channel access is validated with uuid
|
||||||
|
channel_sudo = request.env["discuss.channel"].sudo().search([("uuid", "=", uuid)])
|
||||||
|
if not channel_sudo:
|
||||||
|
return
|
||||||
|
domain = [("channel_id", "=", channel_sudo.id), ("is_self", "=", True)]
|
||||||
|
member = request.env["discuss.channel.member"].search(domain)
|
||||||
|
# sudo: discuss.channel.rtc.session - member of current user can leave call
|
||||||
|
member.sudo()._rtc_leave_call()
|
||||||
|
channel_sudo._close_livechat_session()
|
13
controllers/webclient.py
Normal file
13
controllers/webclient.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from odoo.http import request, route
|
||||||
|
from odoo.addons.mail.controllers.webclient import WebclientController
|
||||||
|
from odoo.addons.mail.models.discuss.mail_guest import add_guest_to_context
|
||||||
|
|
||||||
|
|
||||||
|
class WebClient(WebclientController):
|
||||||
|
@route("/web/tests/livechat", type="http", auth="user")
|
||||||
|
def test_external_livechat(self, **kwargs):
|
||||||
|
return request.render("im_livechat.qunit_embed_suite", {
|
||||||
|
"server_url": request.env["ir.config_parameter"].get_base_url(),
|
||||||
|
})
|
25
data/digest_data.xml
Normal file
25
data/digest_data.xml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<odoo>
|
||||||
|
<data noupdate="1">
|
||||||
|
<record id="digest.digest_digest_default" model="digest.digest">
|
||||||
|
<field name="kpi_livechat_rating">True</field>
|
||||||
|
<field name="kpi_livechat_conversations">True</field>
|
||||||
|
<field name="kpi_livechat_response">True</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
<data>
|
||||||
|
<record id="digest_tip_im_livechat_0" model="digest.tip">
|
||||||
|
<field name="name">Tip: Use canned responses to chat faster</field>
|
||||||
|
<field name="sequence">2900</field>
|
||||||
|
<field name="group_id" ref="im_livechat.im_livechat_group_manager" />
|
||||||
|
<field name="tip_description" type="html">
|
||||||
|
<div>
|
||||||
|
<p class="tip_title">Tip: Use canned responses to chat faster</p>
|
||||||
|
<p class="tip_content">Use canned responses to define templates of messages in the livechat app. To load a canned response, start your sentence with ':' and select the template.</p>
|
||||||
|
<img src="https://download.odoocdn.com/digests/im_livechat/static/src/img/canned-responses.gif" width="540" class="illustration_border" />
|
||||||
|
</div>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
11
data/discuss_shortcode_data.xml
Normal file
11
data/discuss_shortcode_data.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data noupdate="1">
|
||||||
|
|
||||||
|
<record id="mail_shortcode_data_hello" model="mail.shortcode">
|
||||||
|
<field name="source">hello</field>
|
||||||
|
<field name="substitution">Hello, how may I help you?</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</odoo>
|
9
data/im_livechat_channel_data.xml
Normal file
9
data/im_livechat_channel_data.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<odoo>
|
||||||
|
<data noupdate="1">
|
||||||
|
<record id="im_livechat_channel_data" model="im_livechat.channel">
|
||||||
|
<field name="name">YourWebsite.com</field>
|
||||||
|
<field name="default_message">Hello, how may I help you?</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
103
data/im_livechat_chatbot_data.xml
Normal file
103
data/im_livechat_chatbot_data.xml
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<odoo><data noupdate="1">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This provides a working chatbot for people to work with.
|
||||||
|
It's placed into 'data' to give them a starting point.
|
||||||
|
From that record, they can duplicate / adapt / delete / ...
|
||||||
|
-->
|
||||||
|
|
||||||
|
<record id="chatbot_script_welcome_bot" model="chatbot.script">
|
||||||
|
<field name="title">Welcome Bot</field>
|
||||||
|
<field name="image_1920" type="base64" file="mail/static/src/img/odoobot.png"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="chatbot_script_welcome_step_welcome" model="chatbot.script.step">
|
||||||
|
<field name="message">Welcome to CompanyName! 👋</field>
|
||||||
|
<field name="sequence">1</field>
|
||||||
|
<field name="step_type">text</field>
|
||||||
|
<field name="chatbot_script_id" ref="chatbot_script_welcome_bot"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="chatbot_script_welcome_step_dispatch" model="chatbot.script.step">
|
||||||
|
<field name="message">What are you looking for?</field>
|
||||||
|
<field name="sequence">2</field>
|
||||||
|
<field name="step_type">question_selection</field>
|
||||||
|
<field name="chatbot_script_id" ref="chatbot_script_welcome_bot"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="chatbot_script_welcome_step_dispatch_answer_pricing" model="chatbot.script.answer">
|
||||||
|
<field name="name">I have a pricing question</field>
|
||||||
|
<field name="sequence">1</field>
|
||||||
|
<field name="script_step_id" ref="chatbot_script_welcome_step_dispatch"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="chatbot_script_welcome_step_dispatch_answer_documentation" model="chatbot.script.answer">
|
||||||
|
<field name="name">I am looking for your documentation</field>
|
||||||
|
<field name="redirect_link">/</field>
|
||||||
|
<field name="sequence">2</field>
|
||||||
|
<field name="script_step_id" ref="chatbot_script_welcome_step_dispatch"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="chatbot_script_welcome_step_dispatch_answer_just_looking" model="chatbot.script.answer">
|
||||||
|
<field name="name">I am just looking around</field>
|
||||||
|
<field name="sequence">3</field>
|
||||||
|
<field name="script_step_id" ref="chatbot_script_welcome_step_dispatch"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="chatbot_script_welcome_step_pricing" model="chatbot.script.step">
|
||||||
|
<field name="message">Hmmm, let me check if I can find someone that could help you with that...</field>
|
||||||
|
<field name="sequence">3</field>
|
||||||
|
<field name="step_type">text</field>
|
||||||
|
<field name="chatbot_script_id" ref="chatbot_script_welcome_bot"/>
|
||||||
|
<field name="triggering_answer_ids" eval="[(4, ref('chatbot_script_welcome_step_dispatch_answer_pricing'))]"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="chatbot_script_welcome_step_pricing_forward_operator" model="chatbot.script.step">
|
||||||
|
<field name="sequence">4</field>
|
||||||
|
<field name="step_type">forward_operator</field>
|
||||||
|
<field name="chatbot_script_id" ref="chatbot_script_welcome_bot"/>
|
||||||
|
<field name="triggering_answer_ids" eval="[(4, ref('chatbot_script_welcome_step_dispatch_answer_pricing'))]"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="chatbot_script_welcome_step_pricing_noone_available" model="chatbot.script.step">
|
||||||
|
<field name="message">Hu-ho, it looks like none of our operators are available 🙁</field>
|
||||||
|
<field name="sequence">5</field>
|
||||||
|
<field name="step_type">text</field>
|
||||||
|
<field name="chatbot_script_id" ref="chatbot_script_welcome_bot"/>
|
||||||
|
<field name="triggering_answer_ids" eval="[(4, ref('chatbot_script_welcome_step_dispatch_answer_pricing'))]"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="chatbot_script_welcome_step_pricing_email" model="chatbot.script.step">
|
||||||
|
<field name="message">Would you mind leaving your email address so that we can reach you back?</field>
|
||||||
|
<field name="sequence">6</field>
|
||||||
|
<field name="step_type">question_email</field>
|
||||||
|
<field name="chatbot_script_id" ref="chatbot_script_welcome_bot"/>
|
||||||
|
<field name="triggering_answer_ids" eval="[(4, ref('chatbot_script_welcome_step_dispatch_answer_pricing'))]"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="chatbot_script_welcome_step_documentation_redirect" model="chatbot.script.step">
|
||||||
|
<field name="message">And tadaaaa here you go! 🌟</field>
|
||||||
|
<field name="sequence">7</field>
|
||||||
|
<field name="step_type">text</field>
|
||||||
|
<field name="chatbot_script_id" ref="chatbot_script_welcome_bot"/>
|
||||||
|
<field name="triggering_answer_ids" eval="[(4, ref('chatbot_script_welcome_step_dispatch_answer_documentation'))]"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="chatbot_script_welcome_step_documentation_exit" model="chatbot.script.step">
|
||||||
|
<field name="message">If you need anything else, feel free to get back in touch</field>
|
||||||
|
<field name="sequence">8</field>
|
||||||
|
<field name="step_type">text</field>
|
||||||
|
<field name="chatbot_script_id" ref="chatbot_script_welcome_bot"/>
|
||||||
|
<field name="triggering_answer_ids" eval="[(4, ref('chatbot_script_welcome_step_dispatch_answer_documentation'))]"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="chatbot_script_welcome_step_just_looking" model="chatbot.script.step">
|
||||||
|
<field name="message">Please do! If there is anything we can help with, let us know</field>
|
||||||
|
<field name="sequence">9</field>
|
||||||
|
<field name="step_type">text</field>
|
||||||
|
<field name="chatbot_script_id" ref="chatbot_script_welcome_bot"/>
|
||||||
|
<field name="triggering_answer_ids" eval="[(4, ref('chatbot_script_welcome_step_dispatch_answer_just_looking'))]"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</data></odoo>
|
96
data/mail_templates.xml
Normal file
96
data/mail_templates.xml
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data noupdate="1">
|
||||||
|
<template id="livechat_email_template">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" style="padding-top: 16px; background-color: #F1F1F1; font-family:Verdana, Arial,sans-serif; color: #454748; width: 100%; border-collapse:separate;"><tr><td align="center">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" width="590" style="padding: 24px; background-color: white; color: #454748; border-collapse:separate;">
|
||||||
|
<tbody>
|
||||||
|
<!-- HEADER -->
|
||||||
|
<tr>
|
||||||
|
<td align="center" style="min-width: 590px;">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="background-color: white; padding: 0; border-collapse:separate;">
|
||||||
|
<tr><td valign="middle">
|
||||||
|
<span style="font-size: 10px;">Livechat Conversation</span><br/>
|
||||||
|
<span style="font-size: 20px; font-weight: bold;">
|
||||||
|
<t t-esc="company.name"/>
|
||||||
|
</span>
|
||||||
|
</td><td valign="middle" align="right" t-if="not company.uses_default_logo">
|
||||||
|
<img t-att-src="'/logo.png?company=%s' % company.id" style="padding: 0px; margin: 0px; height: 48px;" t-att-alt="'%s' % company.name"/>
|
||||||
|
</td></tr>
|
||||||
|
<tr><td colspan="2" style="text-align:center;">
|
||||||
|
<hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin:4px 0px 32px 0px;"/>
|
||||||
|
</td></tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<!-- CONTENT -->
|
||||||
|
<t t-set="top" t-value="'border-top: thin solid #dee2e6;'" />
|
||||||
|
<t t-set="bottom" t-value="'border-bottom: thin solid #dee2e6;'" />
|
||||||
|
<t t-set="right" t-value="'border-right: thin solid #dee2e6;'" />
|
||||||
|
<t t-set="left" t-value="'border-left: thin solid #dee2e6;'" />
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 0 50px;">
|
||||||
|
<div style="font-size: 13px; padding: 10px 0;">
|
||||||
|
<span>Hello,</span><br />Here's a copy of your conversation with
|
||||||
|
<span t-esc="channel.livechat_operator_id.user_livechat_username or channel.livechat_operator_id.name"/>, on the
|
||||||
|
<span t-field="channel.livechat_channel_id.create_date"/>
|
||||||
|
</div>
|
||||||
|
<table cellspacing="0" cellpadding="0" style="width:100%; border-collapse: collapse;">
|
||||||
|
<t t-foreach="channel.message_ids.sorted(key=lambda m: m.date)" t-as="message" >
|
||||||
|
<t t-set="author_name" t-value="message.author_id.name if message.author_id else 'You'" />
|
||||||
|
<tr>
|
||||||
|
<td valign="top" align="center" rowspan="2" t-att-style="'width: 70px;' + top + bottom + left">
|
||||||
|
<t t-if="message.author_avatar">
|
||||||
|
<img t-attf-alt="{{author_name}}" style="width: 64px; height: 64px; object-fit: cover;" t-attf-src="data:image/png;base64,{{message.author_avatar}}"/>
|
||||||
|
</t>
|
||||||
|
<t t-else="">
|
||||||
|
<img t-attf-alt="{{author_name}}" style="width: 64px; height: 64px; object-fit: cover;" src="/mail/static/src/img/smiley/avatar.jpg"/>
|
||||||
|
</t>
|
||||||
|
</td>
|
||||||
|
<td t-att-style="'padding-left: 5px; margin: 0px;' + top">
|
||||||
|
<strong t-esc="author_name"/>
|
||||||
|
</td>
|
||||||
|
<td t-att-style="'font-size: 13px; padding: 5px;' + top + right" align="right"><span t-field="message.date"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td valign="top" colspan="2" t-att-style="'padding-left: 5px;' + bottom + right">
|
||||||
|
<span t-field="message.body" style="font-size: 13px;"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</t>
|
||||||
|
</table>
|
||||||
|
<div style="font-size: 13px; padding: 30px 0;">
|
||||||
|
<span>Best regards,</span><br /><br />
|
||||||
|
<span t-field="company.name"/>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<!-- FOOTER -->
|
||||||
|
<tr>
|
||||||
|
<td align="center" style="min-width: 590px; padding: 0 8px 0 8px; font-size:11px;">
|
||||||
|
<hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 4px 0px;"/>
|
||||||
|
<b t-esc="company.name"/><br/>
|
||||||
|
<div style="color: #999999;">
|
||||||
|
<t t-esc="company.phone"/>
|
||||||
|
<t t-if="company.email"> |
|
||||||
|
<a t-att-href="'mailto:%s' % company.email" style="text-decoration:none; color: #999999;"><t t-esc="company.email"/></a>
|
||||||
|
</t>
|
||||||
|
<t t-if="company.website"> |
|
||||||
|
<a t-att-href="'%s' % company.website" style="text-decoration:none; color: #999999;">
|
||||||
|
<t t-esc="company.website"/>
|
||||||
|
</a>
|
||||||
|
</t>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td></tr>
|
||||||
|
<!-- POWERED BY -->
|
||||||
|
<tr><td align="center" style="min-width: 590px;">
|
||||||
|
Powered by <a target="_blank" href="https://www.odoo.com?utm_source=db&utm_medium=email" style="color: #875A7B;">Odoo</a>
|
||||||
|
</td></tr>
|
||||||
|
</table>
|
||||||
|
</template>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
11
demo/discuss_shortcode/discuss_shortcode_demo.xml
Normal file
11
demo/discuss_shortcode/discuss_shortcode_demo.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data noupdate="1">
|
||||||
|
|
||||||
|
<record id="mail_canned_response_bye" model="mail.shortcode">
|
||||||
|
<field name="source">bye</field>
|
||||||
|
<field name="substitution">Thanks for your feedback. Goodbye!</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</odoo>
|
22
demo/im_livechat_channel/im_livechat_channel.xml
Normal file
22
demo/im_livechat_channel/im_livechat_channel.xml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<odoo>
|
||||||
|
<data noupdate="1">
|
||||||
|
<record id="base.user_demo" model="res.users">
|
||||||
|
<field name="groups_id" eval="[(3, ref('im_livechat.im_livechat_group_manager'))]"/>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<record id="im_livechat_channel_rule_demo" model="im_livechat.channel.rule">
|
||||||
|
<field name="regex_url">/im_livechat/</field>
|
||||||
|
<field name="action">auto_popup</field>
|
||||||
|
<field name="auto_popup_timer">3</field>
|
||||||
|
<field name="channel_id" ref="im_livechat_channel_data"/>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.im_livechat_group_user" model="res.groups">
|
||||||
|
<field eval="[(4, ref('base.user_demo'))]" name="users"/>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat_channel_data" model="im_livechat.channel">
|
||||||
|
<field eval="[(4, ref('base.user_admin')), (4, ref('base.user_demo'))]" name="user_ids"/>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
91
demo/im_livechat_channel/im_livechat_session_1.xml
Normal file
91
demo/im_livechat_channel/im_livechat_session_1.xml
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<record id="livechat_channel_session_1" model="discuss.channel">
|
||||||
|
<field name="channel_type">livechat</field>
|
||||||
|
<field name="livechat_channel_id" ref="im_livechat_channel_data"/>
|
||||||
|
<field name="livechat_operator_id" ref="base.partner_admin"/>
|
||||||
|
<field name="name">Visitor #234, Mitchell Admin</field>
|
||||||
|
<field name="anonymous_name">Visitor #234</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_1_member_admin" model="discuss.channel.member">
|
||||||
|
<field name="partner_id" ref="base.partner_admin"/>
|
||||||
|
<field name="channel_id" ref="im_livechat.livechat_channel_session_1"/>
|
||||||
|
<field name="is_pinned">False</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_1_guest" model="mail.guest">
|
||||||
|
<field name="name">Visitor #234</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_1_member_guest" model="discuss.channel.member">
|
||||||
|
<field name="guest_id" ref="im_livechat.livechat_channel_session_1_guest"/>
|
||||||
|
<field name="channel_id" ref="im_livechat.livechat_channel_session_1"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="livechat_channel_session_1_message_1" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_1"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_id" ref="base.partner_admin"/>
|
||||||
|
<field name="body">Hello, how may I help you?</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-1, days=-0, minutes=1)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_1_message_2" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_1"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_1_guest"/>
|
||||||
|
<field name="email_from">Visitor</field>
|
||||||
|
<field name="body">I'm looking for an application to record my timesheet, any tips?</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-1, days=-0, minutes=2)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_1_message_3" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_1"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_id" ref="base.partner_admin"/>
|
||||||
|
<field name="body">Yes, you can use our Timesheets application to record your time efficiently!</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-1, days=-0, minutes=3)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_1_message_4" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_1"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_1_guest"/>
|
||||||
|
<field name="email_from">Visitor</field>
|
||||||
|
<field name="body">Great! Thanks for the info</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-1, days=-0, minutes=4)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_1_message_5" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_1"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_id" ref="base.partner_admin"/>
|
||||||
|
<field name="body">You're welcome, have a nice day!</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-1, days=-0, minutes=5)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_1_rating_message" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_1"/>
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_1_guest"/>
|
||||||
|
<field name="subtype_id" ref="mail.mt_note"/>
|
||||||
|
<field name="message_type">notification</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-1, days=-0, minutes=5, seconds=25)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_1_rating" model="rating.rating">
|
||||||
|
<field name="access_token">LIVECHAT_1</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_1"/>
|
||||||
|
<field name="res_model_id" ref="mail.model_discuss_channel"/>
|
||||||
|
<field name="message_id" ref="livechat_channel_session_1_rating_message"/>
|
||||||
|
<field name="rated_partner_id" ref="base.partner_admin"/>
|
||||||
|
<field eval="False" name="partner_id"/>
|
||||||
|
<field eval="True" name="consumed"/>
|
||||||
|
</record>
|
||||||
|
<function model="discuss.channel" name="rating_apply"
|
||||||
|
eval="([ref('im_livechat.livechat_channel_session_1')], 5, 'LIVECHAT_1', None, 'Good Job')"/>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
80
demo/im_livechat_channel/im_livechat_session_10.xml
Normal file
80
demo/im_livechat_channel/im_livechat_session_10.xml
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<record id="livechat_channel_session_10" model="discuss.channel">
|
||||||
|
<field name="name">Visitor, Mitchell Admin</field>
|
||||||
|
<field name="livechat_operator_id" ref="base.partner_admin"/>
|
||||||
|
<field name="livechat_channel_id" ref="im_livechat.im_livechat_channel_data"/>
|
||||||
|
<field name="create_date" eval="datetime.now() - timedelta(days=1)"/>
|
||||||
|
<field name="channel_type">livechat</field>
|
||||||
|
<field name="anonymous_name">Visitor</field>
|
||||||
|
<field name="country_id" ref="base.be"/>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_10_member_admin" model="discuss.channel.member">
|
||||||
|
<field name="partner_id" ref="base.partner_admin"/>
|
||||||
|
<field name="channel_id" ref="im_livechat.livechat_channel_session_10"/>
|
||||||
|
<field name="is_pinned">False</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_10_guest" model="mail.guest">
|
||||||
|
<field name="name">Visitor</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_10_member_guest" model="discuss.channel.member">
|
||||||
|
<field name="guest_id" ref="im_livechat.livechat_channel_session_10_guest"/>
|
||||||
|
<field name="channel_id" ref="im_livechat.livechat_channel_session_10"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="livechat_channel_session_10_message_1" model="mail.message">
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_10_guest"/>
|
||||||
|
<field name="email_from">Visitor</field>
|
||||||
|
<field name="record_name">Visitor</field>
|
||||||
|
<field name="date" eval="datetime.now() - timedelta(days=1)"/>
|
||||||
|
<field name="create_date" eval="datetime.now() - timedelta(days=1)"/>
|
||||||
|
<field name="write_date" eval="datetime.now() - timedelta(days=1)"/>
|
||||||
|
<field name="body">Hi</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_10"/>
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_10_message_2" model="mail.message">
|
||||||
|
<field name="author_id" ref="base.partner_admin"/>
|
||||||
|
<field name="date" eval="datetime.now() - timedelta(days=1, seconds=-15)"/>
|
||||||
|
<field name="create_date" eval="datetime.now() - timedelta(days=1, seconds=-15)"/>
|
||||||
|
<field name="write_date" eval="datetime.now() - timedelta(days=1, seconds=-15)"/>
|
||||||
|
<field name="body">Hello, how may I help you?</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_10"/>
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_10_message_3" model="mail.message">
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_10_guest"/>
|
||||||
|
<field name="email_from">Visitor</field>
|
||||||
|
<field name="record_name">Visitor</field>
|
||||||
|
<field name="date" eval="datetime.now() - timedelta(days=1, seconds=-25)"/>
|
||||||
|
<field name="create_date" eval="datetime.now() - timedelta(days=1, seconds=-25)"/>
|
||||||
|
<field name="write_date" eval="datetime.now() - timedelta(days=1, seconds=-25)"/>
|
||||||
|
<field name="body">I would like to know more about the discuss application</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_10"/>
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_10_rating_message" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_10"/>
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_10_guest"/>
|
||||||
|
<field name="subtype_id" ref="mail.mt_note"/>
|
||||||
|
<field name="message_type">notification</field>
|
||||||
|
<field eval="datetime.now() - timedelta(days=1, seconds=-60)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_10_rating" model="rating.rating">
|
||||||
|
<field name="access_token">LIVECHAT_10</field>
|
||||||
|
<field name="res_model_id" ref="mail.model_discuss_channel"/>
|
||||||
|
<field name="message_id" ref="im_livechat.livechat_channel_session_10_rating_message"/>
|
||||||
|
<field name="rated_partner_id" ref="base.partner_admin"/>
|
||||||
|
<field name="partner_id" ref="base.partner_admin"/>
|
||||||
|
<field name="create_date" eval="datetime.now() - timedelta(days=1, seconds=-53)"/>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_10"/>
|
||||||
|
</record>
|
||||||
|
<function model="discuss.channel" name="rating_apply"
|
||||||
|
eval="([ref('im_livechat.livechat_channel_session_10')], 1, 'LIVECHAT_10', None, 'Not so good')"/>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
60
demo/im_livechat_channel/im_livechat_session_11.xml
Normal file
60
demo/im_livechat_channel/im_livechat_session_11.xml
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<record id="livechat_channel_session_11" model="discuss.channel">
|
||||||
|
<field name="name">Visitor, Mitchell Admin</field>
|
||||||
|
<field name="livechat_operator_id" ref="base.partner_admin"/>
|
||||||
|
<field name="livechat_channel_id" ref="im_livechat.im_livechat_channel_data"/>
|
||||||
|
<field name="create_date" eval="datetime.now()"/>
|
||||||
|
<field name="channel_type">livechat</field>
|
||||||
|
<field name="anonymous_name">Visitor</field>
|
||||||
|
<field name="country_id" ref="base.us"/>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_11_member_admin" model="discuss.channel.member">
|
||||||
|
<field name="partner_id" ref="base.partner_admin"/>
|
||||||
|
<field name="channel_id" ref="im_livechat.livechat_channel_session_11"/>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_11_guest" model="mail.guest">
|
||||||
|
<field name="name">Visitor</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_11_member_guest" model="discuss.channel.member">
|
||||||
|
<field name="guest_id" ref="im_livechat.livechat_channel_session_11_guest"/>
|
||||||
|
<field name="channel_id" ref="im_livechat.livechat_channel_session_11"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="livechat_channel_session_11_message_1" model="mail.message">
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_11_guest"/>
|
||||||
|
<field name="record_name">Visitor</field>
|
||||||
|
<field name="date" eval="datetime.now()"/>
|
||||||
|
<field name="create_date" eval="datetime.now()"/>
|
||||||
|
<field name="write_date" eval="datetime.now()"/>
|
||||||
|
<field name="body">Hi</field>
|
||||||
|
<field name="email_from">Visitor</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_11"/>
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_11_message_2" model="mail.message">
|
||||||
|
<field name="author_id" ref="base.partner_admin"/>
|
||||||
|
<field name="date" eval="datetime.now() - timedelta(seconds=-15)"/>
|
||||||
|
<field name="create_date" eval="datetime.now() - timedelta(seconds=-15)"/>
|
||||||
|
<field name="write_date" eval="datetime.now() - timedelta(seconds=-15)"/>
|
||||||
|
<field name="body">Hello, how may I help you?</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_11"/>
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_11_message_3" model="mail.message">
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_11_guest"/>
|
||||||
|
<field name="record_name">Visitor</field>
|
||||||
|
<field name="date" eval="datetime.now() - timedelta(seconds=-25)"/>
|
||||||
|
<field name="create_date" eval="datetime.now() - timedelta(seconds=-25)"/>
|
||||||
|
<field name="write_date" eval="datetime.now() - timedelta(seconds=-25)"/>
|
||||||
|
<field name="email_from">Visitor</field>
|
||||||
|
<field name="body">I would like to know more about the Discuss application</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_11"/>
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
91
demo/im_livechat_channel/im_livechat_session_2.xml
Normal file
91
demo/im_livechat_channel/im_livechat_session_2.xml
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<record id="livechat_channel_session_2" model="discuss.channel">
|
||||||
|
<field name="channel_type">livechat</field>
|
||||||
|
<field name="livechat_channel_id" ref="im_livechat_channel_data"/>
|
||||||
|
<field name="livechat_operator_id" ref="base.partner_demo"/>
|
||||||
|
<field name="name">Visitor #323, Marc Demo</field>
|
||||||
|
<field name="anonymous_name">Visitor #323</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_2_member_demo" model="discuss.channel.member">
|
||||||
|
<field name="partner_id" ref="base.partner_demo"/>
|
||||||
|
<field name="channel_id" ref="im_livechat.livechat_channel_session_2"/>
|
||||||
|
<field name="is_pinned">False</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_2_guest" model="mail.guest">
|
||||||
|
<field name="name">Visitor #323</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_2_member_guest" model="discuss.channel.member">
|
||||||
|
<field name="guest_id" ref="im_livechat.livechat_channel_session_2_guest"/>
|
||||||
|
<field name="channel_id" ref="im_livechat.livechat_channel_session_2"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="livechat_channel_session_2_message_1" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_2"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_id" ref="base.partner_demo"/>
|
||||||
|
<field name="body">Hello, how may I help you?</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-1, days=-1, minutes=6)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_2_message_2" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_2"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_2_guest"/>
|
||||||
|
<field name="email_from">Visitor</field>
|
||||||
|
<field name="body">I was wondering if Odoo has an application to easily manage social media for my business..</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-1, days=-1, minutes=7)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_2_message_3" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_2"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_id" ref="base.partner_demo"/>
|
||||||
|
<field name="body">Yes, we just released a new application called Social Marketing that should fit your needs! Check it out :)</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-1, days=-1, minutes=8)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_2_message_4" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_2"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_2_guest"/>
|
||||||
|
<field name="email_from">Visitor</field>
|
||||||
|
<field name="body">Awesome, thanks!</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-1, days=-1, minutes=9)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_2_message_5" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_2"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_id" ref="base.partner_demo"/>
|
||||||
|
<field name="body">You're welcome, enjoy Odoo!</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-1, days=-1, minutes=10)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_2_rating_message" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_2"/>
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_2_guest"/>
|
||||||
|
<field name="subtype_id" ref="mail.mt_note"/>
|
||||||
|
<field name="message_type">notification</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-1, days=-1, minutes=11)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_2_rating" model="rating.rating">
|
||||||
|
<field name="access_token">LIVECHAT_2</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_2"/>
|
||||||
|
<field name="res_model_id" ref="mail.model_discuss_channel"/>
|
||||||
|
<field name="rated_partner_id" ref="base.partner_demo"/>
|
||||||
|
<field name="message_id" ref="im_livechat.livechat_channel_session_2_rating_message"/>
|
||||||
|
<field eval="False" name="partner_id"/>
|
||||||
|
<field eval="True" name="consumed"/>
|
||||||
|
</record>
|
||||||
|
<function model="discuss.channel" name="rating_apply"
|
||||||
|
eval="([ref('im_livechat.livechat_channel_session_2')], 5, 'LIVECHAT_2', None, 'Super Job')"/>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
77
demo/im_livechat_channel/im_livechat_session_3.xml
Normal file
77
demo/im_livechat_channel/im_livechat_session_3.xml
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<record id="livechat_channel_session_3" model="discuss.channel">
|
||||||
|
<field name="channel_type">livechat</field>
|
||||||
|
<field name="livechat_channel_id" ref="im_livechat_channel_data"/>
|
||||||
|
<field name="livechat_operator_id" ref="base.partner_admin"/>
|
||||||
|
<field name="name">Joel Willis, Mitchell Admin</field>
|
||||||
|
<field name="anonymous_name">Joel Willis</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_3_member_admin" model="discuss.channel.member">
|
||||||
|
<field name="partner_id" ref="base.partner_admin"/>
|
||||||
|
<field name="channel_id" ref="im_livechat.livechat_channel_session_3"/>
|
||||||
|
<field name="is_pinned">False</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_3_member_portal" model="discuss.channel.member">
|
||||||
|
<field name="partner_id" ref="base.partner_demo_portal"/>
|
||||||
|
<field name="channel_id" ref="im_livechat.livechat_channel_session_3"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="livechat_channel_session_3_message_1" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_3"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_id" ref="base.partner_admin"/>
|
||||||
|
<field name="body">Hello, how may I help you?</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-1, days=-2, minutes=11)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_3_message_2" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_3"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_id" ref="base.partner_demo_portal"/>
|
||||||
|
<field name="body">Hello, are you single?</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-1, days=-2, minutes=12)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_3_message_3" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_3"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_id" ref="base.partner_admin"/>
|
||||||
|
<field name="body">Nope, sorry to disappoint :(</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-1, days=-2, minutes=13)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_3_message_4" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_3"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_id" ref="base.partner_demo_portal"/>
|
||||||
|
<field name="body">Oh :(</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-1, days=-2, minutes=14)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_3_rating_message" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_3"/>
|
||||||
|
<field name="author_id" ref="base.partner_demo_portal"/>
|
||||||
|
<field name="subtype_id" ref="mail.mt_note"/>
|
||||||
|
<field name="message_type">notification</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-1, days=-2, minutes=15)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_3_rating" model="rating.rating">
|
||||||
|
<field name="access_token">LIVECHAT_3</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_3"/>
|
||||||
|
<field name="message_id" ref="im_livechat.livechat_channel_session_3_rating_message"/>
|
||||||
|
<field name="res_model_id" ref="mail.model_discuss_channel"/>
|
||||||
|
<field name="rated_partner_id" ref="base.partner_admin"/>
|
||||||
|
<field name="partner_id" ref="base.partner_demo_portal"/>
|
||||||
|
<field eval="True" name="consumed"/>
|
||||||
|
</record>
|
||||||
|
<function model="discuss.channel" name="rating_apply"
|
||||||
|
eval="([ref('im_livechat.livechat_channel_session_3')], 5, 'LIVECHAT_3', None, 'Mega Job')"/>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
68
demo/im_livechat_channel/im_livechat_session_4.xml
Normal file
68
demo/im_livechat_channel/im_livechat_session_4.xml
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<record id="livechat_channel_session_4" model="discuss.channel">
|
||||||
|
<field name="channel_type">livechat</field>
|
||||||
|
<field name="livechat_channel_id" ref="im_livechat_channel_data"/>
|
||||||
|
<field name="livechat_operator_id" ref="base.partner_demo"/>
|
||||||
|
<field name="name">Joel Willis, Marc Demo</field>
|
||||||
|
<field name="anonymous_name">Joel Willis</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_4_member_demo" model="discuss.channel.member">
|
||||||
|
<field name="partner_id" ref="base.partner_demo"/>
|
||||||
|
<field name="channel_id" ref="im_livechat.livechat_channel_session_4"/>
|
||||||
|
<field name="is_pinned">False</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_4_member_portal" model="discuss.channel.member">
|
||||||
|
<field name="partner_id" ref="base.partner_demo_portal"/>
|
||||||
|
<field name="channel_id" ref="im_livechat.livechat_channel_session_4"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="livechat_channel_session_4_message_1" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_4"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_id" ref="base.partner_demo_portal"/>
|
||||||
|
<field name="body">Hello, I'm looking for a software that can be easily updated with my needs.</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-2, days=-3, minutes=15)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_4_message_2" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_4"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_id" ref="base.partner_demo"/>
|
||||||
|
<field name="body">Hello Joel Willis, you're at the right place! You can customize Odoo using our Studio application in just a few clicks.</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-2, days=-3, minutes=16)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_4_message_3" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_4"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_id" ref="base.partner_demo_portal"/>
|
||||||
|
<field name="body">Thanks for the info, I'll look into it!</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-2, days=-3, minutes=17)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_4_rating_message" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_4"/>
|
||||||
|
<field name="author_id" ref="base.partner_demo_portal"/>
|
||||||
|
<field name="subtype_id" ref="mail.mt_note"/>
|
||||||
|
<field name="message_type">notification</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-2, days=-3, minutes=20)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_4_rating" model="rating.rating">
|
||||||
|
<field name="access_token">LIVECHAT_4</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_4"/>
|
||||||
|
<field name="res_model_id" ref="mail.model_discuss_channel"/>
|
||||||
|
<field name="message_id" ref="im_livechat.livechat_channel_session_4_rating_message"/>
|
||||||
|
<field name="rated_partner_id" ref="base.partner_demo"/>
|
||||||
|
<field name="partner_id" ref="base.partner_demo_portal"/>
|
||||||
|
<field eval="True" name="consumed"/>
|
||||||
|
</record>
|
||||||
|
<function model="discuss.channel" name="rating_apply"
|
||||||
|
eval="([ref('im_livechat.livechat_channel_session_4')], 5, 'LIVECHAT_4', None, 'Good Job')"/>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
82
demo/im_livechat_channel/im_livechat_session_5.xml
Normal file
82
demo/im_livechat_channel/im_livechat_session_5.xml
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<record id="livechat_channel_session_5" model="discuss.channel">
|
||||||
|
<field name="channel_type">livechat</field>
|
||||||
|
<field name="livechat_channel_id" ref="im_livechat_channel_data"/>
|
||||||
|
<field name="livechat_operator_id" ref="base.partner_admin"/>
|
||||||
|
<field name="name">Visitor #532, Mitchell Admin</field>
|
||||||
|
<field name="anonymous_name">Visitor #532</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_5_member_admin" model="discuss.channel.member">
|
||||||
|
<field name="partner_id" ref="base.partner_admin"/>
|
||||||
|
<field name="channel_id" ref="im_livechat.livechat_channel_session_5"/>
|
||||||
|
<field name="is_pinned">False</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_5_guest" model="mail.guest">
|
||||||
|
<field name="name">Visitor #532</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_5_member_guest" model="discuss.channel.member">
|
||||||
|
<field name="guest_id" ref="im_livechat.livechat_channel_session_5_guest"/>
|
||||||
|
<field name="channel_id" ref="im_livechat.livechat_channel_session_5"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="livechat_channel_session_5_message_1" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_5"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_id" ref="base.partner_admin"/>
|
||||||
|
<field name="body">Hello, how may I help you?</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-2, days=-4, minutes=18)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_5_message_2" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_5"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_5_guest"/>
|
||||||
|
<field name="email_from">Visitor</field>
|
||||||
|
<field name="body">Hello, it seems that I can't log in to my database. Can you help?</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-2, days=-4, minutes=19)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_5_message_3" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_5"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_id" ref="base.partner_admin"/>
|
||||||
|
<field name="body">Hi, if you need help with your database, feel free to contact our support via http://www.odoo.com/help</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-2, days=-4, minutes=20)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_5_message_4" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_5"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_5_guest"/>
|
||||||
|
<field name="email_from">Visitor</field>
|
||||||
|
<field name="body">Ok.. Will do, thanks</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-2, days=-4, minutes=21)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_5_rating_message" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_5"/>
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_5_guest"/>
|
||||||
|
<field name="subtype_id" ref="mail.mt_note"/>
|
||||||
|
<field name="message_type">notification</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-2, days=-4, minutes=33)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_5_rating" model="rating.rating">
|
||||||
|
<field name="access_token">LIVECHAT_5</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_5"/>
|
||||||
|
<field name="res_model_id" ref="mail.model_discuss_channel"/>
|
||||||
|
<field name="message_id" ref="im_livechat.livechat_channel_session_5_rating_message"/>
|
||||||
|
<field name="rated_partner_id" ref="base.partner_admin"/>
|
||||||
|
<field eval="False" name="partner_id"/>
|
||||||
|
<field eval="True" name="consumed"/>
|
||||||
|
</record>
|
||||||
|
<function model="discuss.channel" name="rating_apply"
|
||||||
|
eval="([ref('im_livechat.livechat_channel_session_5')], 5, 'LIVECHAT_5', None, 'Super Job')"/>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
82
demo/im_livechat_channel/im_livechat_session_6.xml
Normal file
82
demo/im_livechat_channel/im_livechat_session_6.xml
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<record id="livechat_channel_session_6" model="discuss.channel">
|
||||||
|
<field name="channel_type">livechat</field>
|
||||||
|
<field name="livechat_channel_id" ref="im_livechat_channel_data"/>
|
||||||
|
<field name="livechat_operator_id" ref="base.partner_admin"/>
|
||||||
|
<field name="name">Visitor #649, Mitchell Admin</field>
|
||||||
|
<field name="anonymous_name">Visitor #649</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_6_member_admin" model="discuss.channel.member">
|
||||||
|
<field name="partner_id" ref="base.partner_admin"/>
|
||||||
|
<field name="channel_id" ref="im_livechat.livechat_channel_session_6"/>
|
||||||
|
<field name="is_pinned">False</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_6_guest" model="mail.guest">
|
||||||
|
<field name="name">Visitor #649</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_6_member_guest" model="discuss.channel.member">
|
||||||
|
<field name="guest_id" ref="im_livechat.livechat_channel_session_6_guest"/>
|
||||||
|
<field name="channel_id" ref="im_livechat.livechat_channel_session_6"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="livechat_channel_session_6_message_1" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_6"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_id" ref="base.partner_admin"/>
|
||||||
|
<field name="body">Hello, how may I help you?</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-3, days=-5, minutes=22)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_6_message_2" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_6"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_6_guest"/>
|
||||||
|
<field name="email_from">Visitor</field>
|
||||||
|
<field name="body">Hello, I'm a bit lost in the Invetory module, is there some documentation I could find?</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-3, days=-5, minutes=23)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_6_message_3" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_6"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_id" ref="base.partner_admin"/>
|
||||||
|
<field name="body">Yes, of course, you can find it here: https://www.odoo.com/documentation/17.0/</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-3, days=-5, minutes=24)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_6_message_4" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_6"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_6_guest"/>
|
||||||
|
<field name="email_from">Visitor</field>
|
||||||
|
<field name="body">Thanks!</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-3, days=-5, minutes=25)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_6_rating_message" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_6"/>
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_6_guest"/>
|
||||||
|
<field name="subtype_id" ref="mail.mt_note"/>
|
||||||
|
<field name="message_type">notification</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-3, days=-5, minutes=35)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_6_rating" model="rating.rating">
|
||||||
|
<field name="access_token">LIVECHAT_6</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_6"/>
|
||||||
|
<field name="res_model_id" ref="mail.model_discuss_channel"/>
|
||||||
|
<field name="message_id" ref="livechat_channel_session_6_rating_message"/>
|
||||||
|
<field name="rated_partner_id" ref="base.partner_admin"/>
|
||||||
|
<field eval="False" name="partner_id"/>
|
||||||
|
<field eval="True" name="consumed"/>
|
||||||
|
</record>
|
||||||
|
<function model="discuss.channel" name="rating_apply"
|
||||||
|
eval="([ref('im_livechat.livechat_channel_session_6')], 5, 'LIVECHAT_6', None, 'Good Job')"/>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
77
demo/im_livechat_channel/im_livechat_session_7.xml
Normal file
77
demo/im_livechat_channel/im_livechat_session_7.xml
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<record id="livechat_channel_session_7" model="discuss.channel">
|
||||||
|
<field name="channel_type">livechat</field>
|
||||||
|
<field name="livechat_channel_id" ref="im_livechat_channel_data"/>
|
||||||
|
<field name="livechat_operator_id" ref="base.partner_admin"/>
|
||||||
|
<field name="name">Joel Willis, Mitchell Admin</field>
|
||||||
|
<field name="anonymous_name">Joel Willis</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_7_member_admin" model="discuss.channel.member">
|
||||||
|
<field name="partner_id" ref="base.partner_admin"/>
|
||||||
|
<field name="channel_id" ref="im_livechat.livechat_channel_session_7"/>
|
||||||
|
<field name="is_pinned">False</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_7_member_portal" model="discuss.channel.member">
|
||||||
|
<field name="partner_id" ref="base.partner_demo_portal"/>
|
||||||
|
<field name="channel_id" ref="im_livechat.livechat_channel_session_7"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="livechat_channel_session_7_message_1" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_7"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_id" ref="base.partner_admin"/>
|
||||||
|
<field name="body">Hello, how may I help you?</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-3, days=-6, minutes=26)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_7_message_2" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_7"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_id" ref="base.partner_demo_portal"/>
|
||||||
|
<field name="body">Hi, I need a software to easily manage my stock, and generate sales orders.</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-3, days=-6, minutes=27)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_7_message_3" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_7"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_id" ref="base.partner_admin"/>
|
||||||
|
<field name="body">Joel Willis, you'll need our Inventory and Sales application to do so. You can try them for 15 days, FOR FREE :)</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-3, days=-6, minutes=28)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_7_message_4" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_7"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_id" ref="base.partner_demo_portal"/>
|
||||||
|
<field name="body">Good to hear, thanks!</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-3, days=-6, minutes=29)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_7_rating_message" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_7"/>
|
||||||
|
<field name="author_id" ref="base.partner_demo_portal"/>
|
||||||
|
<field name="subtype_id" ref="mail.mt_note"/>
|
||||||
|
<field name="message_type">notification</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-3, days=-6, minutes=50)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_7_rating" model="rating.rating">
|
||||||
|
<field name="access_token">LIVECHAT_7</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_7"/>
|
||||||
|
<field name="res_model_id" ref="mail.model_discuss_channel"/>
|
||||||
|
<field name="message_id" ref="im_livechat.livechat_channel_session_7_rating_message"/>
|
||||||
|
<field name="rated_partner_id" ref="base.partner_admin"/>
|
||||||
|
<field name="partner_id" ref="base.partner_demo_portal"/>
|
||||||
|
<field eval="True" name="consumed"/>
|
||||||
|
</record>
|
||||||
|
<function model="discuss.channel" name="rating_apply"
|
||||||
|
eval="([ref('im_livechat.livechat_channel_session_7')], 5, 'LIVECHAT_7', None, 'Super Job')"/>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
80
demo/im_livechat_channel/im_livechat_session_8.xml
Normal file
80
demo/im_livechat_channel/im_livechat_session_8.xml
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<record id="livechat_channel_session_8" model="discuss.channel">
|
||||||
|
<field name="channel_type">livechat</field>
|
||||||
|
<field name="livechat_channel_id" ref="im_livechat_channel_data"/>
|
||||||
|
<field name="livechat_operator_id" ref="base.partner_demo"/>
|
||||||
|
<field name="name">Visitor #722, Marc Demo</field>
|
||||||
|
<field name="anonymous_name">Visitor #722</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_8_member_demo" model="discuss.channel.member">
|
||||||
|
<field name="partner_id" ref="base.partner_demo"/>
|
||||||
|
<field name="channel_id" ref="im_livechat.livechat_channel_session_8"/>
|
||||||
|
<field name="is_pinned">False</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_8_guest" model="mail.guest">
|
||||||
|
<field name="name">Visitor #722</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_8_member_guest" model="discuss.channel.member">
|
||||||
|
<field name="guest_id" ref="im_livechat.livechat_channel_session_8_guest"/>
|
||||||
|
<field name="channel_id" ref="im_livechat.livechat_channel_session_8"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="livechat_channel_session_8_message_1" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_8"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_id" ref="base.partner_demo"/>
|
||||||
|
<field name="body">Hello, how may I help you?</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-3, days=-7, minutes=30)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_8_message_2" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_8"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_8_guest"/>
|
||||||
|
<field name="body">Heeeey Marc, how are you?</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-3, days=-7, minutes=31)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_8_message_3" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_8"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_id" ref="base.partner_demo"/>
|
||||||
|
<field name="body">I'm fine, and you?</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-3, days=-7, minutes=32)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_8_message_4" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_8"/>
|
||||||
|
<field name="message_type">email</field>
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_8_guest"/>
|
||||||
|
<field name="body">I'm great, thanks for asking!</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-3, days=-7, minutes=33)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_8_rating_message" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_8"/>
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_8_guest"/>
|
||||||
|
<field name="subtype_id" ref="mail.mt_note"/>
|
||||||
|
<field name="message_type">notification</field>
|
||||||
|
<field eval="DateTime.today() + relativedelta(months=-3, days=-7, minutes=52)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_8_rating" model="rating.rating">
|
||||||
|
<field name="access_token">LIVECHAT_8</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_8"/>
|
||||||
|
<field name="res_model_id" ref="mail.model_discuss_channel"/>
|
||||||
|
<field name="message_id" ref="livechat_channel_session_8_rating_message"/>
|
||||||
|
<field name="rated_partner_id" ref="base.partner_demo"/>
|
||||||
|
<field eval="False" name="partner_id"/>
|
||||||
|
<field eval="True" name="consumed"/>
|
||||||
|
</record>
|
||||||
|
<function model="discuss.channel" name="rating_apply"
|
||||||
|
eval="([ref('im_livechat.livechat_channel_session_8')], 5, 'LIVECHAT_8', None, 'Super Job')"/>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
109
demo/im_livechat_channel/im_livechat_session_9.xml
Normal file
109
demo/im_livechat_channel/im_livechat_session_9.xml
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<record id="livechat_channel_session_9" model="discuss.channel">
|
||||||
|
<field name="name">Visitor, Mitchell Admin</field>
|
||||||
|
<field name="livechat_operator_id" ref="base.partner_admin"/>
|
||||||
|
<field name="livechat_channel_id" ref="im_livechat.im_livechat_channel_data"/>
|
||||||
|
<field name="create_date" eval="datetime.now() - timedelta(days=1)"/>
|
||||||
|
<field name="channel_type">livechat</field>
|
||||||
|
<field name="anonymous_name">Visitor</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_9_member_admin" model="discuss.channel.member">
|
||||||
|
<field name="partner_id" ref="base.partner_admin"/>
|
||||||
|
<field name="channel_id" ref="im_livechat.livechat_channel_session_9"/>
|
||||||
|
<field name="is_pinned">False</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_9_guest" model="mail.guest">
|
||||||
|
<field name="name">Visitor</field>
|
||||||
|
</record>
|
||||||
|
<record id="im_livechat.livechat_channel_session_9_member_guest" model="discuss.channel.member">
|
||||||
|
<field name="guest_id" ref="im_livechat.livechat_channel_session_9_guest"/>
|
||||||
|
<field name="channel_id" ref="im_livechat.livechat_channel_session_9"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="livechat_channel_session_9_message_1" model="mail.message">
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_9_guest"/>
|
||||||
|
<field name="record_name">Visitor</field>
|
||||||
|
<field name="date" eval="datetime.now() - timedelta(days=1)"/>
|
||||||
|
<field name="create_date" eval="datetime.now() - timedelta(days=1)"/>
|
||||||
|
<field name="write_date" eval="datetime.now() - timedelta(days=1)"/>
|
||||||
|
<field name="body">Hi</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_9"/>
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_9_message_2" model="mail.message">
|
||||||
|
<field name="author_id" ref="base.partner_admin"/>
|
||||||
|
<field name="date" eval="datetime.now() - timedelta(days=1, seconds=-15)"/>
|
||||||
|
<field name="create_date" eval="datetime.now() - timedelta(days=1, seconds=-15)"/>
|
||||||
|
<field name="write_date" eval="datetime.now() - timedelta(days=1, seconds=-15)"/>
|
||||||
|
<field name="body">Hello, how may I help you?</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_9"/>
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_9_message_3" model="mail.message">
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_9_guest"/>
|
||||||
|
<field name="record_name">Visitor</field>
|
||||||
|
<field name="date" eval="datetime.now() - timedelta(days=1, seconds=-25)"/>
|
||||||
|
<field name="create_date" eval="datetime.now() - timedelta(days=1, seconds=-25)"/>
|
||||||
|
<field name="write_date" eval="datetime.now() - timedelta(days=1, seconds=-25)"/>
|
||||||
|
<field name="body">I would like to know more about the CRM application</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_9"/>
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_9_message_4" model="mail.message">
|
||||||
|
<field name="author_id" ref="base.partner_admin"/>
|
||||||
|
<field name="date" eval="datetime.now() - timedelta(days=1, seconds=-33)"/>
|
||||||
|
<field name="create_date" eval="datetime.now() - timedelta(days=1, seconds=-33)"/>
|
||||||
|
<field name="write_date" eval="datetime.now() - timedelta(days=1, seconds=-33)"/>
|
||||||
|
<field name="body">The CRM application helps you to track leads, close opportunities and get accurate forecasts. You can test it for free on our website.</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_9"/>
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_9_message_5" model="mail.message">
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_9_guest"/>
|
||||||
|
<field name="record_name">Visitor</field>
|
||||||
|
<field name="date" eval="datetime.now() - timedelta(days=1, seconds=-42)"/>
|
||||||
|
<field name="create_date" eval="datetime.now() - timedelta(days=1, seconds=-42)"/>
|
||||||
|
<field name="write_date" eval="datetime.now() - timedelta(days=1, seconds=-42)"/>
|
||||||
|
<field name="body">Great, thanks!</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_9"/>
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_9_message_6" model="mail.message">
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_9_guest"/>
|
||||||
|
<field name="record_name">Visitor</field>
|
||||||
|
<field name="date" eval="datetime.now() - timedelta(days=1, seconds=-53)"/>
|
||||||
|
<field name="create_date" eval="datetime.now() - timedelta(days=1, seconds=-53)"/>
|
||||||
|
<field name="write_date" eval="datetime.now() - timedelta(days=1, seconds=-53)"/>
|
||||||
|
<field name="body">Rating: :-)</field>
|
||||||
|
<field name="message_type">comment</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_9"/>
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_9_rating_message" model="mail.message">
|
||||||
|
<field name="model">discuss.channel</field>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_9"/>
|
||||||
|
<field name="author_guest_id" ref="im_livechat.livechat_channel_session_9_guest"/>
|
||||||
|
<field name="subtype_id" ref="mail.mt_note"/>
|
||||||
|
<field name="message_type">notification</field>
|
||||||
|
<field eval="datetime.now() - timedelta(days=1, seconds=-60)" name="date"/>
|
||||||
|
</record>
|
||||||
|
<record id="livechat_channel_session_9_rating" model="rating.rating">
|
||||||
|
<field name="access_token">LIVECHAT_9</field>
|
||||||
|
<field name="res_model_id" ref="mail.model_discuss_channel"/>
|
||||||
|
<field name="message_id" ref="im_livechat.livechat_channel_session_9_rating_message"/>
|
||||||
|
<field name="rated_partner_id" ref="base.partner_admin"/>
|
||||||
|
<field name="partner_id" ref="base.partner_admin"/>
|
||||||
|
<field name="create_date" eval="datetime.now() - timedelta(days=1, seconds=-53)"/>
|
||||||
|
<field name="res_id" ref="im_livechat.livechat_channel_session_9"/>
|
||||||
|
</record>
|
||||||
|
<function model="discuss.channel" name="rating_apply"
|
||||||
|
eval="([ref('im_livechat.livechat_channel_session_9')], 5, 'LIVECHAT_9', None, 'Super Job')"/>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
2001
i18n/af.po
Normal file
2001
i18n/af.po
Normal file
File diff suppressed because it is too large
Load Diff
1997
i18n/am.po
Normal file
1997
i18n/am.po
Normal file
File diff suppressed because it is too large
Load Diff
2084
i18n/ar.po
Normal file
2084
i18n/ar.po
Normal file
File diff suppressed because it is too large
Load Diff
2002
i18n/az.po
Normal file
2002
i18n/az.po
Normal file
File diff suppressed because it is too large
Load Diff
2057
i18n/bg.po
Normal file
2057
i18n/bg.po
Normal file
File diff suppressed because it is too large
Load Diff
2003
i18n/bs.po
Normal file
2003
i18n/bs.po
Normal file
File diff suppressed because it is too large
Load Diff
2120
i18n/ca.po
Normal file
2120
i18n/ca.po
Normal file
File diff suppressed because it is too large
Load Diff
2054
i18n/cs.po
Normal file
2054
i18n/cs.po
Normal file
File diff suppressed because it is too large
Load Diff
2055
i18n/da.po
Normal file
2055
i18n/da.po
Normal file
File diff suppressed because it is too large
Load Diff
2123
i18n/de.po
Normal file
2123
i18n/de.po
Normal file
File diff suppressed because it is too large
Load Diff
2002
i18n/el.po
Normal file
2002
i18n/el.po
Normal file
File diff suppressed because it is too large
Load Diff
2000
i18n/en_GB.po
Normal file
2000
i18n/en_GB.po
Normal file
File diff suppressed because it is too large
Load Diff
2112
i18n/es.po
Normal file
2112
i18n/es.po
Normal file
File diff suppressed because it is too large
Load Diff
2119
i18n/es_419.po
Normal file
2119
i18n/es_419.po
Normal file
File diff suppressed because it is too large
Load Diff
2000
i18n/es_BO.po
Normal file
2000
i18n/es_BO.po
Normal file
File diff suppressed because it is too large
Load Diff
2000
i18n/es_CL.po
Normal file
2000
i18n/es_CL.po
Normal file
File diff suppressed because it is too large
Load Diff
2000
i18n/es_CO.po
Normal file
2000
i18n/es_CO.po
Normal file
File diff suppressed because it is too large
Load Diff
2000
i18n/es_CR.po
Normal file
2000
i18n/es_CR.po
Normal file
File diff suppressed because it is too large
Load Diff
2000
i18n/es_DO.po
Normal file
2000
i18n/es_DO.po
Normal file
File diff suppressed because it is too large
Load Diff
2000
i18n/es_EC.po
Normal file
2000
i18n/es_EC.po
Normal file
File diff suppressed because it is too large
Load Diff
2000
i18n/es_PE.po
Normal file
2000
i18n/es_PE.po
Normal file
File diff suppressed because it is too large
Load Diff
2000
i18n/es_PY.po
Normal file
2000
i18n/es_PY.po
Normal file
File diff suppressed because it is too large
Load Diff
2000
i18n/es_VE.po
Normal file
2000
i18n/es_VE.po
Normal file
File diff suppressed because it is too large
Load Diff
2065
i18n/et.po
Normal file
2065
i18n/et.po
Normal file
File diff suppressed because it is too large
Load Diff
2000
i18n/eu.po
Normal file
2000
i18n/eu.po
Normal file
File diff suppressed because it is too large
Load Diff
2041
i18n/fa.po
Normal file
2041
i18n/fa.po
Normal file
File diff suppressed because it is too large
Load Diff
2115
i18n/fi.po
Normal file
2115
i18n/fi.po
Normal file
File diff suppressed because it is too large
Load Diff
2000
i18n/fo.po
Normal file
2000
i18n/fo.po
Normal file
File diff suppressed because it is too large
Load Diff
2114
i18n/fr.po
Normal file
2114
i18n/fr.po
Normal file
File diff suppressed because it is too large
Load Diff
2000
i18n/fr_CA.po
Normal file
2000
i18n/fr_CA.po
Normal file
File diff suppressed because it is too large
Load Diff
2000
i18n/gl.po
Normal file
2000
i18n/gl.po
Normal file
File diff suppressed because it is too large
Load Diff
2004
i18n/gu.po
Normal file
2004
i18n/gu.po
Normal file
File diff suppressed because it is too large
Load Diff
2048
i18n/he.po
Normal file
2048
i18n/he.po
Normal file
File diff suppressed because it is too large
Load Diff
2020
i18n/hr.po
Normal file
2020
i18n/hr.po
Normal file
File diff suppressed because it is too large
Load Diff
2054
i18n/hu.po
Normal file
2054
i18n/hu.po
Normal file
File diff suppressed because it is too large
Load Diff
2105
i18n/id.po
Normal file
2105
i18n/id.po
Normal file
File diff suppressed because it is too large
Load Diff
2025
i18n/im_livechat.pot
Normal file
2025
i18n/im_livechat.pot
Normal file
File diff suppressed because it is too large
Load Diff
1997
i18n/is.po
Normal file
1997
i18n/is.po
Normal file
File diff suppressed because it is too large
Load Diff
2105
i18n/it.po
Normal file
2105
i18n/it.po
Normal file
File diff suppressed because it is too large
Load Diff
2058
i18n/ja.po
Normal file
2058
i18n/ja.po
Normal file
File diff suppressed because it is too large
Load Diff
2000
i18n/ka.po
Normal file
2000
i18n/ka.po
Normal file
File diff suppressed because it is too large
Load Diff
2000
i18n/kab.po
Normal file
2000
i18n/kab.po
Normal file
File diff suppressed because it is too large
Load Diff
2003
i18n/km.po
Normal file
2003
i18n/km.po
Normal file
File diff suppressed because it is too large
Load Diff
2059
i18n/ko.po
Normal file
2059
i18n/ko.po
Normal file
File diff suppressed because it is too large
Load Diff
2001
i18n/lb.po
Normal file
2001
i18n/lb.po
Normal file
File diff suppressed because it is too large
Load Diff
1997
i18n/lo.po
Normal file
1997
i18n/lo.po
Normal file
File diff suppressed because it is too large
Load Diff
2059
i18n/lt.po
Normal file
2059
i18n/lt.po
Normal file
File diff suppressed because it is too large
Load Diff
2040
i18n/lv.po
Normal file
2040
i18n/lv.po
Normal file
File diff suppressed because it is too large
Load Diff
2000
i18n/mk.po
Normal file
2000
i18n/mk.po
Normal file
File diff suppressed because it is too large
Load Diff
2018
i18n/mn.po
Normal file
2018
i18n/mn.po
Normal file
File diff suppressed because it is too large
Load Diff
2005
i18n/nb.po
Normal file
2005
i18n/nb.po
Normal file
File diff suppressed because it is too large
Load Diff
1997
i18n/ne.po
Normal file
1997
i18n/ne.po
Normal file
File diff suppressed because it is too large
Load Diff
2109
i18n/nl.po
Normal file
2109
i18n/nl.po
Normal file
File diff suppressed because it is too large
Load Diff
2095
i18n/pl.po
Normal file
2095
i18n/pl.po
Normal file
File diff suppressed because it is too large
Load Diff
2037
i18n/pt.po
Normal file
2037
i18n/pt.po
Normal file
File diff suppressed because it is too large
Load Diff
2107
i18n/pt_BR.po
Normal file
2107
i18n/pt_BR.po
Normal file
File diff suppressed because it is too large
Load Diff
2015
i18n/ro.po
Normal file
2015
i18n/ro.po
Normal file
File diff suppressed because it is too large
Load Diff
2124
i18n/ru.po
Normal file
2124
i18n/ru.po
Normal file
File diff suppressed because it is too large
Load Diff
2043
i18n/sk.po
Normal file
2043
i18n/sk.po
Normal file
File diff suppressed because it is too large
Load Diff
2042
i18n/sl.po
Normal file
2042
i18n/sl.po
Normal file
File diff suppressed because it is too large
Load Diff
2000
i18n/sq.po
Normal file
2000
i18n/sq.po
Normal file
File diff suppressed because it is too large
Load Diff
2101
i18n/sr.po
Normal file
2101
i18n/sr.po
Normal file
File diff suppressed because it is too large
Load Diff
2003
i18n/sr@latin.po
Normal file
2003
i18n/sr@latin.po
Normal file
File diff suppressed because it is too large
Load Diff
2070
i18n/sv.po
Normal file
2070
i18n/sv.po
Normal file
File diff suppressed because it is too large
Load Diff
2001
i18n/ta.po
Normal file
2001
i18n/ta.po
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user