summaryrefslogtreecommitdiff
path: root/addons/mail_bot
diff options
context:
space:
mode:
authordmonzonis <mod@odoo.com>2020-05-07 07:09:43 +0000
committerThibault DelavallΓ©e <tde@odoo.com>2020-05-27 12:47:16 +0000
commit936d206559035627b07a25e7a0f807ad43d39f54 (patch)
tree23b7d64a07f15a26b630383e70bc472fef1bbb70 /addons/mail_bot
parent5b20117495b908bde3877c02db3ada7249eb7993 (diff)
[IMP] mail_bot: improve OdooBot workflow
This commit attempts to improve the workflow of the OdooBot onboarding tutorial, as well as the answer given by the bot while idle. These changes come from watching how users interact with OdooBot. To improve the user's experience, the following changes have been made: 1. Move the attachment to the end of the tour, as it is where most people just close the bot. 2. Remove the quotation marks around commands that OdooBot tells the user to type, like "/" or ":)", as some users try to actually type the quotation marks too. Instead, use a light grey background around the command that the user should type. 3. Some users ask OdooBot questions, but the responses they get are useless. To solve this, use a message linking to the documentation or the videos when: - The user gives wrong answers twice for the same stage of the tour - The user talks again when the tour is completed - There's a question mark in the answer To achieve this a "failed" state field is added on user model, allowing to distinguish state in the bot workflow from state of answers (failed / not failed). Task ID: 2233014 PR #49661
Diffstat (limited to 'addons/mail_bot')
-rw-r--r--addons/mail_bot/__manifest__.py2
-rw-r--r--addons/mail_bot/models/mail_bot.py51
-rw-r--r--addons/mail_bot/models/mail_channel.py2
-rw-r--r--addons/mail_bot/models/res_users.py2
-rw-r--r--addons/mail_bot/static/src/scss/odoobot_style.scss8
-rw-r--r--addons/mail_bot/views/assets.xml1
6 files changed, 47 insertions, 19 deletions
diff --git a/addons/mail_bot/__manifest__.py b/addons/mail_bot/__manifest__.py
index c1010924ea6..348754d3f62 100644
--- a/addons/mail_bot/__manifest__.py
+++ b/addons/mail_bot/__manifest__.py
@@ -3,7 +3,7 @@
{
'name': 'OdooBot',
- 'version': '1.0',
+ 'version': '1.1',
'category': 'Productivity/Discuss',
'summary': 'Add OdooBot in discussions',
'description': "",
diff --git a/addons/mail_bot/models/mail_bot.py b/addons/mail_bot/models/mail_bot.py
index 7a4aebee197..6c17d60bbd4 100644
--- a/addons/mail_bot/models/mail_bot.py
+++ b/addons/mail_bot/models/mail_bot.py
@@ -25,7 +25,7 @@ class MailBot(models.AbstractModel):
if len(record) != 1 or values.get("author_id") == odoobot_id:
return
if self._is_bot_pinged(values) or self._is_bot_in_private_channel(record):
- body = values.get("body", "").replace(u'\xa0', u' ').strip().lower().strip(".?!")
+ body = values.get("body", "").replace(u'\xa0', u' ').strip().lower().strip(".!")
answer = self._get_answer(record, body, values, command)
if answer:
message_type = values.get('message_type', 'comment')
@@ -38,42 +38,53 @@ class MailBot(models.AbstractModel):
if self._is_bot_in_private_channel(record):
# main flow
if odoobot_state == 'onboarding_emoji' and self._body_contains_emoji(body):
- self.env.user.odoobot_state = "onboarding_attachement"
- return _("Great! πŸ‘<br/>Now, try to <b>send an attachment</b>, like a picture of your cute dog...")
- elif odoobot_state == 'onboarding_attachement' and values.get("attachment_ids"):
self.env.user.odoobot_state = "onboarding_command"
- return _("Not a cute dog, but you get it 😊<br/>To access special features, <b>start your sentence with '/'</b>. Try to get help.")
+ self.env.user.odoobot_failed = False
+ return _("Great! πŸ‘<br/>To access special commands, <b>start your sentence with</b> <span class=\"o_odoobot_command\">/</span>. Try getting help.")
elif odoobot_state == 'onboarding_command' and command == 'help':
self.env.user.odoobot_state = "onboarding_ping"
- return _("Wow you are a natural!<br/>Ping someone to grab its attention with @nameoftheuser. <b>Try to ping me using @OdooBot</b> in a sentence.")
+ self.env.user.odoobot_failed = False
+ return _("Wow you are a natural!<br/>Ping someone to grab its attention with @username. <b>Try to ping me using</b> <span class=\"o_odoobot_command\">@OdooBot</span> in a sentence.")
elif odoobot_state == 'onboarding_ping' and self._is_bot_pinged(values):
+ self.env.user.odoobot_state = "onboarding_attachement"
+ self.env.user.odoobot_failed = False
+ return _("Yep, I am here! πŸŽ‰ <br/>Now, try <b>sending an attachment</b>, like a picture of your cute dog...")
+ elif odoobot_state == 'onboarding_attachement' and values.get("attachment_ids"):
self.env.user.odoobot_state = "idle"
- return _("Yep, I am here! πŸŽ‰ <br/>You finished the tour, you can <b>close this chat window</b>. Enjoy discovering Odoo.")
- elif odoobot_state == "idle" and (_('start the tour') in body.lower()):
+ self.env.user.odoobot_failed = False
+ return _("I am a simple bot, but if that's a dog, he is the cutest 😊 <br/>Congratulations, you finished this tour. You can now <b>close this chat window</b>. Enjoy discovering Odoo.")
+ elif odoobot_state in ("idle", "not_initialized") and (_('start the tour') in body.lower()):
self.env.user.odoobot_state = "onboarding_emoji"
return _("To start, try to send me an emoji :)")
# easter eggs
elif odoobot_state == "idle" and body in ['❀️', _('i love you'), _('love')]:
return _("Aaaaaw that's really cute but, you know, bots don't work that way. You're too human for me! Let's keep it professional ❀️")
- elif odoobot_state == "idle" and (('help' in body) or _('help') in body):
- return _("I'm just a bot... :( You can check <a href=\"https://www.odoo.com/page/docs\">our documentation</a>) for more information!")
elif _('fuck') in body or "fuck" in body:
return _("That's not nice! I'm a bot but I have feelings... πŸ’”")
+ # help message
+ elif self._is_help_requested(body) or odoobot_state == 'idle':
+ return _("Unfortunately, I'm just a bot 😞 I don't understand! If you need help discovering our product, please check "
+ "<a href=\"https://www.odoo.com/page/docs\" target=\"_blank\">our documentation</a> or "
+ "<a href=\"https://www.odoo.com/slides\" target=\"_blank\">our videos</a>.")
else:
- #repeat question
+ # repeat question
if odoobot_state == 'onboarding_emoji':
- return _("Not exactly. To continue the tour, send an emoji, <b>type \":)\"</b> and press enter.")
+ self.env.user.odoobot_failed = True
+ return _("Not exactly. To continue the tour, send an emoji: <b>type</b> <span class=\"o_odoobot_command\">:)</span> and press enter.")
elif odoobot_state == 'onboarding_attachement':
- return _("To <b>send an attachment</b>, click the πŸ“Ž icon on the right, and select a file.")
+ self.env.user.odoobot_failed = True
+ return _("To <b>send an attachment</b>, click on the <i class=\"fa fa-paperclip\" aria-hidden=\"true\"></i> icon and select a file.")
elif odoobot_state == 'onboarding_command':
- return _("Not sure wat you are doing. Please press / and wait for the propositions. Select \"help\" and press enter")
+ self.env.user.odoobot_failed = True
+ return _("Not sure what you are doing. Please, type <span class=\"o_odoobot_command\">/</span> and wait for the propositions. Select <span class=\"o_odoobot_command\">help</span> and press enter")
elif odoobot_state == 'onboarding_ping':
- return _("Sorry, I am not listening. To get someone's attention, <b>ping him</b>. Write \"@odoobot\" and select me.")
+ self.env.user.odoobot_failed = True
+ return _("Sorry, I am not listening. To get someone's attention, <b>ping him</b>. Write <span class=\"o_odoobot_command\">@OdooBot</span> and select me.")
return random.choice([
- _("I'm not smart enough to answer your question.<br/>To follow my guide, ask") + ": <b>"+_('start the tour') + "</b>",
+ _("I'm not smart enough to answer your question.<br/>To follow my guide, ask: <span class=\"o_odoobot_command\">start the tour</span>."),
_("Hmmm..."),
_("I'm afraid I don't understand. Sorry!"),
- _("Sorry I'm sleepy. Or not! Maybe I'm just trying to hide my unawareness of human language...<br/>I can show you features if you write")+ ": '<b>"+_('start the tour')+"</b>'.",
+ _("Sorry I'm sleepy. Or not! Maybe I'm just trying to hide my unawareness of human language...<br/>I can show you features if you write: <span class=\"o_odoobot_command\">start the tour</span>.")
])
return False
@@ -219,3 +230,9 @@ class MailBot(models.AbstractModel):
if record._name == 'mail.channel' and record.channel_type == 'chat':
return odoobot_id in record.with_context(active_test=False).channel_partner_ids.ids
return False
+
+ def _is_help_requested(self, body):
+ """Returns whether a message linking to the documentation and videos
+ should be sent back to the user.
+ """
+ return any(token in body for token in ['help', _('help'), '?']) or self.env.user.odoobot_failed
diff --git a/addons/mail_bot/models/mail_channel.py b/addons/mail_bot/models/mail_channel.py
index 8b792780971..909696e5618 100644
--- a/addons/mail_bot/models/mail_channel.py
+++ b/addons/mail_bot/models/mail_channel.py
@@ -23,7 +23,7 @@ class Channel(models.Model):
'email_send': False,
'name': 'OdooBot'
})
- message = _("Hello,<br/>Odoo's chat helps employees collaborate efficiently. I'm here to help you discover its features.<br/><b>Try to send me an emoji :)</b>")
+ message = _("Hello,<br/>Odoo's chat helps employees collaborate efficiently. I'm here to help you discover its features.<br/><b>Try to send me an emoji</b> <span class=\"o_odoobot_command\">:)</span>")
channel.sudo().message_post(body=message, author_id=odoobot_id, message_type="comment", subtype_xmlid="mail.mt_comment")
self.env.user.odoobot_state = 'onboarding_emoji'
return channel
diff --git a/addons/mail_bot/models/res_users.py b/addons/mail_bot/models/res_users.py
index f1975df23e4..8468bc16d0f 100644
--- a/addons/mail_bot/models/res_users.py
+++ b/addons/mail_bot/models/res_users.py
@@ -5,6 +5,7 @@ from odoo import models, fields
class Users(models.Model):
_inherit = 'res.users'
+
odoobot_state = fields.Selection(
[
('not_initialized', 'Not initialized'),
@@ -15,6 +16,7 @@ class Users(models.Model):
('idle', 'Idle'),
('disabled', 'Disabled'),
], string="OdooBot Status", readonly=True, required=True, default="not_initialized") # keep track of the state: correspond to the code of the last message sent
+ odoobot_failed = fields.Boolean(readonly=True)
def __init__(self, pool, cr):
""" Override of __init__ to add access rights.
diff --git a/addons/mail_bot/static/src/scss/odoobot_style.scss b/addons/mail_bot/static/src/scss/odoobot_style.scss
new file mode 100644
index 00000000000..aa5e187bb00
--- /dev/null
+++ b/addons/mail_bot/static/src/scss/odoobot_style.scss
@@ -0,0 +1,8 @@
+.o_odoobot_command {
+ background-color: lightgray;
+ border-radius: 4px;
+ padding: 2px;
+ padding-left: 10px;
+ padding-right: 10px;
+ font-weight: bold;
+}
diff --git a/addons/mail_bot/views/assets.xml b/addons/mail_bot/views/assets.xml
index 243fa5228a2..e3d5ee81feb 100644
--- a/addons/mail_bot/views/assets.xml
+++ b/addons/mail_bot/views/assets.xml
@@ -3,6 +3,7 @@
<data>
<template id="assets_backend" name="mailbot assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
+ <link rel="stylesheet" type="text/scss" href="/mail_bot/static/src/scss/odoobot_style.scss"/>
<script type="text/javascript" src="/mail_bot/static/src/js/mailbot_service.js"></script>
<script type="text/javascript" src="/mail_bot/static/src/js/notification_alert.js"></script>
<script type="text/javascript" src="/mail_bot/static/src/js/systray_messaging_menu.js"></script>