Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement reminderbot demo and add user guide #5189

Merged
merged 31 commits into from
Feb 25, 2020
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
ad75348
Implement reminderbot demo
Feb 4, 2020
50353d4
Add more nlu-training examples
Feb 4, 2020
f0c3300
Write user-guide for external events
Feb 6, 2020
31a5015
Update headlines
Feb 6, 2020
8b08c4c
Add `Cancelling reminders` section
Feb 6, 2020
023c796
Merge branch 'master' into johannes-reminder-demo
Feb 6, 2020
cad5087
Merge branch 'master' into johannes-reminder-demo
Feb 10, 2020
387adb4
Add changelog entry
Feb 10, 2020
9b87d13
Merge branch 'johannes-reminder-demo' of github.com:RasaHQ/rasa into …
Feb 10, 2020
9a9852c
Add README for reminderbot
Feb 17, 2020
247eb21
Add link to reminderbot
Feb 17, 2020
bb3f01e
Move reminders-and-external-events.rst to core
Feb 21, 2020
55d3a1a
Turn around sections and update intro
Feb 21, 2020
5a03887
Explain how to link to Raspberry Pi
Feb 21, 2020
488fce9
Use `literalinclude`
Feb 21, 2020
4906762
Fix warning
Feb 21, 2020
07369fd
Clean code
Feb 21, 2020
e7080fb
Ignore new *.db and *.db-* files
Feb 21, 2020
f36803e
Merge branch 'master' into johannes-reminder-demo
Feb 21, 2020
96db304
Make `run` async
Feb 21, 2020
ca98fd8
Fix phrasing and typos
Feb 24, 2020
f47d59d
Capitalize titles
Feb 24, 2020
90f4426
Add Wikipedia link for "webhook"
Feb 24, 2020
07faaa5
Merge branch 'master' into johannes-reminder-demo
Feb 24, 2020
7005d6f
Describe change in gitignore
Feb 24, 2020
bf2a4d3
Use single blank line throughout
Feb 24, 2020
ded325f
Add link comment to callback responses
Feb 24, 2020
7d1837f
Merge branch 'master' into johannes-reminder-demo
Feb 24, 2020
51f3fb8
Merge branch 'master' into johannes-reminder-demo
wochinge Feb 24, 2020
2f5b40c
Merge branch 'master' into johannes-reminder-demo
Feb 25, 2020
1d97897
Merge branch 'master' into johannes-reminder-demo
Feb 25, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,11 @@ failed_stories.md
errors.json
pip-wheel-metadata/*
events.db
events.db-shm
events.db-wal
rasa.db
rasa.db-shm
rasa.db-wal
*.swp
*.coverage*
env
Expand Down
1 change: 1 addition & 0 deletions changelog/5189.doc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added user guide for reminders and external events, including ``reminderbot`` demo.
JEM-Mosig marked this conversation as resolved.
Show resolved Hide resolved
183 changes: 183 additions & 0 deletions docs/core/reminders-and-external-events.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
:desc: Learn how to use external events and schedule reminders.

.. _reminders-and-external-events:

Reminders and External Events
=============================

.. edit-link::

The ``ReminderScheduled`` event and the
`trigger_intent endpoint <../../api/http-api/#operation/triggerConversationIntent>`_ let your assistant remind you
about things after a given period of time, or to respond to external events (other applications, sensors, etc.).
You can find a full example assistant that implements these features
`here <https://github.com/RasaHQ/rasa/tree/master/examples/reminderbot/README.md>`_.

.. contents::
:local:


.. _reminders:

Reminders
---------

Instead of an external sensor, you might just want to be reminded about something after a certain amount of time.
For this, Rasa provides the special event ``ReminderScheduled``, and another event, ``ReminderCancelled``, to unschedule a reminder.


.. _scheduling-reminders-guide:

Scheduling reminders
^^^^^^^^^^^^^^^^^^^^

Let's say you want your assistant to remind you to call a friend in 5 seconds.
(You probably want some longer time span, but for the sake of testing, let it be 5 seconds.)
Thus, we define an intent ``ask_remind_call`` with some NLU data,

.. code-block:: md

## intent:ask_remind_call
- remind me to call [Albert](name)
- remind me to call [Susan](name)
- later I have to call [Daksh](name)
- later I have to call [Anna](name)
...

and connect this intent with a new custom action ``action_set_reminder``.
We could make this connection by providing training stories (recommended for more complex assistants), or using the :ref:`mapping-policy`.

The custom action ``action_set_reminder`` should schedule a reminder that, 5 seconds later, triggers an intent ``EXTERNAL_reminder`` with all the entities that the user provided in his/her last message (similar to an external event):

.. literalinclude:: ../../examples/reminderbot/actions.py
:pyobject: ActionSetReminder


Note that this requires the ``datetime`` and ``rasa_sdk.events`` packages.

Finally, we define another custom action ``action_react_to_reminder`` and link it to the ``EXTERNAL_reminder`` intent:

.. code-block:: md

- EXTERNAL_reminder:
triggers: action_react_to_reminder

where the ``action_react_to_reminder`` is

.. literalinclude:: ../../examples/reminderbot/actions.py
:pyobject: ActionReactToReminder

Instead of a custom action, we could also have used a simple response template.
But here we want to make use of the fact that the reminder can carry entities, and we can process the entities in this custom action.

.. warning::

Reminders are cancelled whenever you shutdown your Rasa server.


.. warning::

Reminders currently (Rasa 1.8) don't work in `rasa shell`.
You have to test them with a
`running Rasa X server <https://rasa.com/docs/rasa-x/installation-and-setup/docker-compose-script/>`_ instead.


.. note::

Proactively reaching out to the user is dependent on the abilities of a channel and
hence not supported by every channel. If your channel does not support it, consider
using the :ref:`callbackInput` channel to send messages to a webhook.
JEM-Mosig marked this conversation as resolved.
Show resolved Hide resolved


JEM-Mosig marked this conversation as resolved.
Show resolved Hide resolved

.. _cancelling-reminders-guide:

Cancelling reminders
JEM-Mosig marked this conversation as resolved.
Show resolved Hide resolved
^^^^^^^^^^^^^^^^^^^^

Sometimes the user may want to cancel a reminder that he has scheduled earlier.
A simple way of adding this functionality to your assistant is to create an intent ``ask_forget_reminders`` and let your assistant respond to it with a custom action such as

.. literalinclude:: ../../examples/reminderbot/actions.py
:pyobject: ForgetReminders

Here, ``ReminderCancelled()`` simply cancels all the reminders that are currently scheduled.
Alternatively, you may provide some parameters to narrow down the types of reminders that you want to cancel.
For example,

- ``ReminderCancelled(intent="greet")`` cancels all reminders with intent ``greet``
- ``ReminderCancelled(entities={...})`` cancels all reminders with the given entities
- ``ReminderCancelled("...")`` cancels the one unique reminder with the given name "``...``" that you supplied
during its creation


.. _external-event-guide:

External events
---------------

Let's say you want to send a message from some other device to change the course of an ongoing conversation.
For example, some moisture-sensor attached to a Raspberry Pi should inform your personal assistant that your favourite
plant needs watering, and your assistant should then relay this message to you.

To do this, your Raspberry Pi needs to send a message to the `trigger_intent endpoint <../../api/http-api/#operation/triggerConversationIntent>`_ of your conversation.
As the name says, this injects a user intent (possibly with entities) into your conversation.
So for Rasa it is almost as if you had entered a message that got classified with this intent and these entities.
Rasa then needs to respond to this input with an action such as ``action_warn_dry``.
The easiest and most reliable way to connect this action with the intent is via the :ref:`mapping-policy`.


.. _getting-conversation-id:

Getting the conversation ID
^^^^^^^^^^^^^^^^^^^^^^^^^^^

The first thing we need is the Session ID of the conversation that your sensor should send a notification to.
An easy way to get this is to define a custom action (see :ref:`custom-actions`) that displays the ID in the conversation.
For example:

.. literalinclude:: ../../examples/reminderbot/actions.py
:pyobject: ActionTellID


In addition, we also declare an intent ``ask_id``, define some NLU data for it, and add both ``action_tell_id`` and
``ask_id`` to the domain file, where we specify that one should trigger the other:

.. code-block:: md

intents:
- ask_id:
triggers: action_tell_id


Now, when you ask "What is the ID of this conversation?", the assistant replies with something like "The ID of this
conversation is: 38cc25d7e23e4dde800353751b7c2d3e".

If you want your assistant to link to the Raspberry Pi automatically, you will have to write a custom action that
informs the Pi about the conversation id when your conversation starts (see :ref:`custom_session_start`).


.. _responding_to_external_events:

Responding to external events
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Now that we have our Session ID, we need to prepare the assistant so it responds to messages from the sensor.
To this end, we define a new intent ``EXTERNAL_dry_plant`` without any NLU data.
This intent will later be triggered by the external sensor.
Here, we start the intent name with ``EXTERNAL_`` to indicate that this is not something the user would say, but you can name the intent however you like.

In the domain file, we now connect the intent ``EXTERNAL_dry_plant`` with another custom action ``action_warn_dry``, e.g.

.. literalinclude:: ../../examples/reminderbot/actions.py
:pyobject: ActionWarnDry


Now, when you are in a conversation with id ``38cc25d7e23e4dde800353751b7c2d3e``, then running

.. code-block:: shell

curl -H "Content-Type: application/json" -X POST -d '{"name": "EXTERNAL_dry_plant", "entities": {"plant": "Orchid"}}' http://localhost:5005/conversations/38cc25d7e23e4dde800353751b7c2d3e/trigger_intent


in the terminal will cause your assistant to say "Your Orchid needs some water!".
21 changes: 2 additions & 19 deletions docs/core/responses.rst
Original file line number Diff line number Diff line change
Expand Up @@ -166,22 +166,5 @@ Proactively Reaching Out to the User with External Events
You may want to proactively reach out to the user,
for example to display the output of a long running background operation
or notify the user of an external event.

To do so, you can ``POST`` an intent to the
`trigger_intent endpoint <../../api/http-api/#operation/triggerConversationIntent>`_.
The intent, let's call it ``EXTERNAL_sensor``, will be treated as if the user had sent a message with this intent.
You can even provide a dictionary of entities as parameters, e.g. ``{"temperature": "high"}``.
For your bot to respond, we recommend you use the :ref:`mapping-policy` to connect the sent intent ``EXTERNAL_sensor``
with the action you want your bot to execute, e.g. ``utter_warn_temperature``.
You can also use a custom action here, of course.

Use the ``output_channel`` query parameter to specify which output
channel should be used to communicate the assistant's responses back to the user.
Any messages that are dispatched in the custom action will be forwarded to the specified output channel.
Set this parameter to ``"latest"`` if you want to use the latest input channel that the user has used.

.. note::

Proactively reaching out to the user is dependent on the abilities of a channel and
hence not supported by every channel. If your channel does not support it, consider
using the :ref:`callbackInput` channel to send messages to a webhook.
To learn more, check out `reminderbot <https://github.com/RasaHQ/rasa/tree/master/examples/reminderbot/README.md>`_ in
the Rasa examples directory, or the `docs page on this topic <../../core/external-events-and-reminders>`_.
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ Understand messages, hold conversations, and connect to messaging channels and A
core/domains
core/responses
core/actions
core/reminders-and-external-events
core/policies
core/slots
core/forms
Expand Down
40 changes: 40 additions & 0 deletions examples/reminderbot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Reminderbot

The `reminderbot` example demonstrates how your bot can respond to external events or reminders.

## What’s inside this example?

This example contains some training data and the main files needed to build an
assistant on your local machine. The `reminderbot` consists of the following files:

- **data/nlu.md** contains training examples for the NLU model
- **data/stories.md** contains training stories for the Core model
- **config.yml** contains the model configuration
- **domain.yml** contains the domain of the assistant
- **credentials.yml** contains credentials for the different channels
- **endpoints.yml** contains the different endpoints reminderbot can use
- **actions.py** contains the custom actions that deal with external events and reminders

## How to use this example?

To train and chat with `reminderbot`, execute the following steps:

1. Train a Rasa model containing the Rasa NLU and Rasa Core models by running:
JEM-Mosig marked this conversation as resolved.
Show resolved Hide resolved
```
rasa train
```
The model will be stored in the `/models` directory as a zipped file.

2. Run a rasa action server with
JEM-Mosig marked this conversation as resolved.
Show resolved Hide resolved
```
rasa run actions
```

3. Run a Rasa X to talk to your bot.
If you don't have a Rasa X server running, you can test things with `rasa x` in a separate shell (the action server must keep running).

For more information about the individual commands, please check out our
[documentation](http://rasa.com/docs/rasa/user-guide/command-line-interface/).

## Encountered any issues?
Let us know about it by posting on [Rasa Community Forum](https://forum.rasa.com)!
Empty file.
Loading