Reaching Out to the User
Reaching out first
In most use cases, when the user opens the chat window with your assistant, you will want the assistant to send the first message. Doing this can give the user an idea of what the bot can or can't do and set them up to have a more successful conversation. Some messaging or voice channels have existing configuration options to send a payload to the assistant when the user first starts the conversation, but you can also add this option to your own custom channel.
Once you've configured your channel to send a payload, you will need to specify how the assistant should react and greet the user. You can either re-use an existing intent's behavior for this, or specify a new intent and rule for this. Below is a guide on how to specify a welcome rule.
1. Update the configuration
Since you are using a rule for this behavior, you need to add the RulePolicy to your configuration file:
policies:
# other policies
- name: RulePolicy
2. Add a rule
To have the assistant respond to the intent greet with a welcome message only at the beginning of a conversation, add the following rule:
rules:
- rule: welcome user
conversation_start: true # this rule only applies at the beginning of a conversation
steps:
- intent: greet
- action: utter_welcome
3. Add a response
Finally, add a response for the utter_welcome utter action to your domain:
domain:
responses:
utter_welcome:
- text: Hi there! What can I help you with today?
External Events
Sometimes you want an external device to change the course of an ongoing conversation. For example, if you have a moisture sensor attached to a Raspberry Pi, you could use it to notify you when a plant needs watering via your assistant.
1. Trigger an Intent
To have an event from an external device change the course of an ongoing conversation, you can have the device post to the trigger_intent endpoint of your conversation. The trigger_intent endpoint injects a user intent (possibly with entities) into your conversation.
For example, the following post request would inject the intent EXTERNAL_dry_plant and the plant entity into the conversation with id user123:
curl -H "Content-Type: application/json" -X POST \
-d '{"name": "EXTERNAL_dry_plant", "entities": {"plant": "Orchid"}}' \
"http://localhost:5005/conversations/user123/trigger_intent?output_channel=latest"
2. Get the Conversation ID
In a real-life scenario, your external device would get the conversation ID from an API or a database. In the dry plant example, you might have a database of plants, the users that water them, and the users' conversation IDs.
3. Add NLU Training Data
In the dry plant example, your Raspberry Pi needs to send a message with the intent EXTERNAL_dry_plant to the trigger_intent endpoint. This intent will be reserved for use by the Raspberry Pi, so there won't be any NLU training examples for it.
domain:
intents:
- EXTERNAL_dry_plant
4. Update the Domain
To tell the assistant which plant needs watering, you can define an entity that you'll post along with the intent. To be able to use the entity value directly in a response, define a slot by the same name:
domain:
entities:
- plant
slots:
plant:
type: text
influence_conversation: false
5. Add a Rule
You'll need a rule that tells your assistant how to respond when it receives a message from the Raspberry Pi.
rules:
- rule: warn about dry plant
steps:
- intent: EXTERNAL_dry_plant
- action: utter_warn_dry
6. Add a Response
You'll need to define the response text for utter_warn_dry:
domain:
responses:
utter_warn_dry:
- text: "Your {plant} needs some water!"
Try it out
To try out the dry plant notification example, you'll need to start either Rasa X or a CallbackChannel.
A reminder
Reminders
You can have your assistant reach out to the user after a set amount of time by using Reminders.
Scheduling Reminders
1. Define a Reminder
To schedule a reminder, you need to define a custom action that returns the ReminderScheduled event. For example, the following custom action schedules a reminder for five seconds from now:
import datetime
from rasa_sdk.events import ReminderScheduled
from rasa_sdk import Action
class ActionSetReminder(Action):
"""Schedules a reminder, supplied with the last message's entities."""
def name(self) -> Text:
return "action_set_reminder"
async def run(self, dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any],) -> List[Dict[Text, Any]]:
dispatcher.utter_message("I will remind you in 5 seconds.")
date = datetime.datetime.now() + datetime.timedelta(seconds=5)
entities = tracker.latest_message.get("entities")
reminder = ReminderScheduled(
"EXTERNAL_reminder",
trigger_date_time=date,
entities=entities,
name="my_reminder",
kill_on_user_message=False,
)
return [reminder]
2. Add a Rule
To schedule a reminder, add a rule:
rules:
- rule: Schedule a reminder
steps:
- intent: ask_remind_call
entities:
- PERSON
- action: action_schedule_reminder
3. Add Training Data
You should add NLU training examples for scheduling the reminder:
nlu:
- intent: ask_remind_call
examples: |
- remind me to call John
- later I have to call Alan
- Please, remind me to call Vova
- please remind me to call Tanja
- I must not forget to call Juste
4. Update your Pipeline
By adding SpacyNLP and SpacyEntityExtractor to your pipeline in config.yml, you won't need to annotate any of the names in your training data:
pipeline:
# other components
- name: SpacyNLP
model: "en_core_web_md"
- name: SpacyEntityExtractor
dimensions: ["PERSON"]
Reacting to Reminders
1. Define a Reaction
The bot reaches out to the user after receiving a POST request to the trigger_intent endpoint. Reminders, however, send the request to the right conversation ID automatically after a certain amount of time using the name that you define in the ReminderScheduled event.
To define a reaction to the reminder, you only need to write a rule that tells the bot what action to take when it receives the reminder intent.
class ActionReactToReminder(Action):
"""Reminds the user to call someone."""
def name(self) -> Text:
return "action_react_to_reminder"
async def run(self, dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any],) -> List[Dict[Text, Any]]:
name = next(tracker.get_slot("PERSON"), "someone")
dispatcher.utter_message(f"Remember to call {name}!")
return []
2. Add a Rule
To tell your bot what action to run when a reminder is triggered, add a rule.
rules:
- rule: Trigger `action_react_to_reminder` for `EXTERNAL_reminder`
steps:
- intent: EXTERNAL_reminder
- action: action_react_to_reminder
3. Add Training Data
You'll need to define the intent that triggers reacting to the reminder:
domain:
intents:
- intent: EXTERNAL_reminder
Cancelling Reminders
1. Define an Action that Cancels a Reminder
To cancel a reminder that you've already scheduled, you need a custom action that returns the ReminderCancelled() event.
For the call reminder example, you can define a custom action action_forget_reminders that cancels all reminders:
class ForgetReminders(Action):
"""Cancels all reminders."""
def name(self) -> Text:
return "action_forget_reminders"
async def run(self, dispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
dispatcher.utter_message(f"Okay, I'll cancel all your reminders.")
return [ReminderCancelled()]
2. Add a Rule
You'll need to add a rule for cancelling a reminder.
rules:
- rule: Cancel a reminder
steps:
- intent: ask_forget_reminders
- action: action_forget_reminders
3. Add Training Data
You'll need to define an intent that triggers cancelling the reminder:
nlu:
- intent: ask_forget_reminders
examples: |
- Forget about the reminder
- do not remind me
- cancel the reminder
- cancel all reminders please
Try it Out
To try out reminders you'll need to start either Rasa X or a CallbackChannel. You'll also need to start the action server to schedule, react to, and cancel your reminders.