Skip to content

Commit

Permalink
Update documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
mzilinec committed Jun 7, 2019
1 parent 8dd7a58 commit 8ea86ef
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 138 deletions.
6 changes: 3 additions & 3 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
# -- Project information -----------------------------------------------------

project = 'Botshot'
copyright = '2018, David Prihoda, Matus Zilinec'
author = 'David Prihoda, Matus Zilinec'
copyright = '2019, Matus Zilinec, David Prihoda'
author = 'Matus Zilinec, David Prihoda'

# The short X.Y version
version = ''
Expand Down Expand Up @@ -133,7 +133,7 @@
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'Botshot.tex', 'Botshot Documentation',
'David Prihoda, Matus Zilinec, Jakub Drdak', 'manual'),
'Matus Zilinec, David Prihoda, Jakub Drdak', 'manual'),
]


Expand Down
188 changes: 114 additions & 74 deletions docs/quickstart/actions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,76 +10,124 @@ Hardcoded actions
========================

| You can simply define a message to be sent directly from the YAML flow.
| We encourage you to try making a flow just with these and testing it in the web chat interface before moving on to Python code.
| In the example below, each time the user visits the "root" state, the bot sends the message "How are you?" and moves to the state "root" of the flow "next".
.. code-block:: yaml
action:
text: "How are you?" # sends a text message
replies: # sends quick replies below the message
- "I'm fine!"
- "Don't even ask"
next: "next.root:" # moves to a different state
greeting:
states:
- name: "root"
action:
text: "How are you?" # sends a text message
replies: # sends quick replies below the message
- "I'm fine!"
- "Don't even ask"
next: "next.root:" # moves to a different state
========================
Coding actions in Python
========================

You can call a custom function anywhere where you would use a hardcoded action. This function can be imported relatively or absolutely.
You can also define the action as a regular Python function.
In this function, you can implement business logic and send messages from the bot.

.. code-block:: yaml
# absolute import
action: chatbot.bots.default.conditions.bar
action: actions.foo # relative import
greeting:
states:
- name: "root"
# relative import ...
action: actions.foo
# ... or absolute import
action: chatbot.bots.default.conditions.bar
The function takes one parameter - an instance of ``DialogManager`` and optionally returns name of the next state (equivalent to ``next`` in YAML).
This function should look at the conversation context (NLU entities), fetch any data it needs from external APIs and send messages to the user.
| The function should take one parameter - ``dialog``. This object can be used to send messages and query conversation context and user profile.
| To move to another state, the function can optionally return the new state's name (equivalent to ``next`` in YAML).
.. code-block:: python
import random
from custom.logic import get_all_jokes
from botshot.core.dialog_manager import DialogManager
from botshot.core.dialog import Dialog
from botshot.core.responses import *
def show_joke(dialog: DialogManager):
def show_joke(dialog: Dialog):
jokes = get_all_jokes()
joke = random.choice(jokes)
dialog.send(joke) # sends a string message
return "next.root:"
.. note:: While waiting for the function to return, a typing indicator is displayed. (three dots in messenger)
| You can send messages by calling ``dialog.send()``. This method takes one argument - the message!
| The argument can be a string, a standard template from ``botshot.core.responses``, or a list of messages.
| See `Message Templates`_.
|
| The context of the conversation is stored in ``dialog.context``. See `Context`_ for more information.
.. note:: The function will be run asynchronously. While waiting for the function to return, a typing indicator will be displayed. (three dots in messenger)


--------------------------------------
Sending more messages at once
--------------------------------------

.. code-block:: python
messages = []
for i in range(3):
messages.append("Message #{}".format(i))
dialog.send(messages)
.. TODO picture
.. warning:: Avoid calling dialog.send() in a loop. In bad network conditions, the messages might be sent in wrong order.

--------------------------------------
Sending delayed messages
--------------------------------------

You can schedule messages to be sent at a time in the future, or when the user is inactive for a period of time.
Read more in `Scheduling messages`_.

.. code-block:: python
payload = {"_state": "default.schedule", "schedule_id": "123"}
# Regular scheduled message - use a datetime or number of seconds
dialog.schedule(payload, at=None, seconds=None)
# Executed only if the user remains inactive
dialog.inactive(payload, seconds=None)
.. TODO explain payloads
-------------------
Message templates
-------------------

| You can send messages by calling ``dialog.send()``. This method requires one argument - the message!
|
|
| The message should either be a string, one of the templates from ``golem.core.responses``, or a list of these.
| Here is a list of all the templates you can use:
This section contains a list of all message templates that can be sent using ``dialog.send()``.
The templates are universal, but they will render slightly different on each messaging service.

+++++++++++++++++
Text message
+++++++++++++++++

| A basic message with text. Can optionally have buttons or quick replies.
| A basic message with text. Can contain buttons or quick replies.
| The officially supported button types are:
``TextMessage(text, buttons=[], replies=[])``

- ``LinkButton(title, url)`` Redirects to a webpage upon being clicked.
- ``PayloadButton(title, payload)`` Sends a special `postback message`_ on click.
- ``PhoneButton(title, phone_number)`` Facebook only. Calls a number when clicked.
- ``ShareButton()`` Facebook only. Opens the "Share" window.
Buttons are shown below the message. They can be used to provide additional related actions.

| The supported quick reply types are:
- ``LinkButton(title, url)`` - Opens a web page upon being clicked.
- ``PayloadButton(title, payload)`` - Sends a special `postback message`_ with programmer-defined payload on click.
- ``PhoneButton(title, phone_number)`` - Facebook only. Calls a number when clicked.
- ``ShareButton()`` - Facebook only. Opens the "Share" window.

- ``QuickReply(title)`` Used to suggest what the user can say. Sends "title" as a message.
- ``LocationQuickReply()`` Facebook only. Opens the "Send location" window.
Quick replies are used to suggest a user's response. They contain text that is sent back to the chatbot when clicked. They can also contain payload.

- ``QuickReply(title)`` - Used to suggest what the user can say. Sends "title" as a message.
- ``LocationQuickReply()`` - Facebook only. Opens the "Send location" window.

.. code-block:: python
Expand All @@ -103,32 +151,53 @@ Text message
msg.with_replies(reply_list)
TODO picture, result on more platforms?
.. TODO show result on all platforms
.. note:: Different platforms have different message limitations. For example, quick replies in Facebook Messenger can have a maximum of 20 characters.

+++++++++++++++++++++
Image message
Media message
+++++++++++++++++++++

TODO
MediaMessage can be used to send an image with optional buttons. The image should be located on a publicly available URL.

+++++++++++++++++++++
Audio message
+++++++++++++++++++++
Example:

TODO
.. code-block:: python
+++++++++++++++++++++
Video message
+++++++++++++++++++++
from botshot.core.responses import MediaMessage
TODO
message = MediaMessage(url="http://placehold.it/300x300", buttons=[LinkButton("Open", "http://example.com"))
renders as:
.. TODO show result on all platforms
.. +++++++++++++++++++++
.. Image message
.. +++++++++++++++++++++
.. TODO
.. +++++++++++++++++++++
.. Audio message
.. +++++++++++++++++++++
.. TODO
.. +++++++++++++++++++++
.. Video message
.. +++++++++++++++++++++
.. TODO
+++++++++++++++++++++
Card template
+++++++++++++++++++++
The card template displays a card with a title, subtitle, an image and buttons.
It can be used to present structured information about an item or product.
.. code-block:: python
msg = CardTemplate(
Expand All @@ -139,11 +208,14 @@ Card template
)
msg.add_button(button)
.. TODO show result on all platforms
+++++++++++++++++++++
Carousel template
+++++++++++++++++++++
The carousel template is a horizontal list of cards.
.. code-block:: python
msg = CarouselTemplate()
Expand All @@ -159,36 +231,4 @@ Carousel template
List template
+++++++++++++++++++++
TODO

++++++++++++++++++++++++++++++
Sending more messages at once
++++++++++++++++++++++++++++++

.. code-block:: python
messages = []
for i in range(3):
messages.append("Message #{}".format(i))
dialog.send(messages)
TODO picture

.. warning:: Avoid calling dialog.send() in a loop. In bad network conditions, the messages might be sent in wrong order.

-------------------
Scheduling messages
-------------------

You can schedule a message to be sent in the future.
You can optionally send it only if the user doesn't say anything first.

.. code-block:: python
payload = {"_state": "default.schedule", "schedule_id": "123"}
# Regular scheduled message - use a datetime or number of seconds
dialog.schedule(payload, at=None, seconds=None)
# Runs only if the user remains inactive
dialog.inactive(payload, seconds=None)
The list template is a vertical list of cards.
4 changes: 1 addition & 3 deletions docs/quickstart/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ Configuration

If you used the ``bots`` init tool, you don't need to configure anything at the moment.

TODO The dialogue manager is quite well thought out and has a powerful set of rules that you can utilize to handle any conversational situation.

----------------------
Project structure
----------------------
Expand All @@ -16,7 +14,7 @@ It might look similar to this:
::

my_bot/ # the root directory
my_bot/ # your chatbot (django) app
bot/ # your chatbot (django) app
chatbots/ # actual chatbot logic (read on)
botshot_settings.py # chatbot-specific settings
settings.py # web server settings
Expand Down
36 changes: 14 additions & 22 deletions docs/quickstart/conversation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,12 @@ Conversation

Let's finally build a chatbot!


| The central part of your chatbot is the conversation (meaning, what should the bot say and when).
| In most chatbots, you can think of the conversation as a graph.
|
| Each node in this graph represents a state, a specific point in the conversation.
| For example, you might have states for greeting, telling a joke, showing a quiz and so on.
|
| The chatbot can then move between states when a message is received.
Take a look at this picture: (TODO picture)

.. You might say that a graph like this is actually an acceptable good model of a real world conversation.
=======================
Flows and states
=======================

| Botshot provides a **dialog manager** that makes it easy to define and move between these conversation **states**.
| We further group states into so-called **flows**, which you can use to split your bot into smaller independent modules. A **flow** is a just a set of states about a specific topic.
| Botshot provides a **dialog manager** that makes it easy to define different **states** of the conversation and move between them.
| We group states into smaller independent modules, so-called **flows**. A **flow** usually defines a conversation about a specific topic.
|
|
| You can define the conversation in YAML_, in JSON [#f1]_, or directly in code.
Expand All @@ -31,18 +18,18 @@ Flows and states
Defining the conversation in YAML
---------------------------------

| We prefer to use YAML over definitions in code, as it is cleaner and allows to separate structure from the content.
| If you used the ``bots`` script, there is already a default flow at ``my_bot/chatbots/default/flow.yml``.
| Each ``flow.yml`` has to be included in ``bot_settings.py`` like this:
| We prefer to use YAML over definitions in code, as it is cleaner and allows to separate definition from the implementation.
| If you used the ``bots`` script, there is already a default flow in ``bot/bots/default/flow.yml``.
| You can enable or disable each ``flow.yml`` by adding or removing it under ``FLOWS`` in ``settings.py``:
.. code-block:: python
BOT_CONFIG = {
"FLOWS": { # we recommend creating a separate directory and file for each flow
"FLOWS": { # we recommend creating a separate directory for each flow
"chatbot/bots/default/flow.yml"
...
| The structure of ``flow.yml`` is as follows.
| You can see an example ``flow.yml`` below.
.. code-block:: yaml
Expand All @@ -62,14 +49,19 @@ Defining the conversation in YAML
accepts: # entities that trigger this flow
- city_name
| The file contains a flow named "greeting", that has two states, "root" and "joke".
| The "root" state is always required - it is where the chatbot will first move when the user sends a "greeting" message.
| The state's action can be hardcoded directly in the definition, like in the "root" state, or it can reference a Python function, like in the "joke" state.
| All the ways in which you can move between states are described in the optional section below.
| You can now skip directly to `Actions`_ or continue reading.
+++++++++++++++++++
State transitions
+++++++++++++++++++
| Each conversation starts in the default.root state.
| The system of transitions between states is quite well thought out.
| Each conversation starts in the "root" state of the "default" flow.
| The user can then system of transitions between states.
| This is important, get ready.
1. **Intent transition** First, the dialogue manager checks whether an **intent** was received from the NLU.
Expand Down

0 comments on commit 8ea86ef

Please sign in to comment.