# Custom Forms
# Introduction
Let's have a quick look at your project folder structure:
awesome-project
|- .botfront
|- actions
|- botfront-db
|- models
Folder | Description |
---|---|
.botfront | Project configuration files, docker-compose files |
actions | Custom actions for the actions server |
botfront-db | MongoDB persisted files |
models | Persisted models |
You probably figured it out: actions
is our folder of interest.
TLDR;
If you already know about Rasa and custom actions:
- Add your actions in the
actions/my_actions.py
file. - Run
botfront watch
from the root of your project folder to automatically rebuild your action server on file changes.
# Tutorial
Let's build a conversation like this:
- User: i want to book a room
- Bot: ok what is your name for booking
But let's start with a simpler version:
- User: i want to book a room
- Bot: Ok
While taking baby steps...
# 1. Add a story
In a new story group, add the following story and click Train everything
* inform_guests
- utter_ok
You can verify that the story works by typing /inform_guests
in the chat window
TIP
Note that we prefixed the intent with /
. Since there is no training data for that intent, we can't use natural language yet. The /
allows us to invoke the intent directly.
The bot should reply with utter_ok
.
# 2. Add training data to inform_guests
Add the following examples to the inform_guests
intent of your NLU model and re-train it:
i want to book a room
i want room tonight
booking room
Add more intents
You need at least two different intents to train an NLU model. You can add more intents by importing from the Chit Chat tab.
# 3. Add a bot response
Finally, let's create a bot response for the utter_ok
template we just put in the story:
TIP
You just created a sequence of messages. The bot will utter 2 messages even if your story only had one action following * inform_guests
Let's just remind ourselves of our end goal:
- User: i want to book a room
- Bot: ok what is your name for booking
- so let's Creat form action to ask user to enter his name (in this EX but we can add form action to fill any other data(phone,date,company_name... ))
# 6. Create a form action
Open the actions
folder and add a new file called my_actions.py
and paste the following content:
import logging
from functools import reduce
from typing import Dict, Text, Any, List, Union
from rasa_sdk import ActionExecutionRejection
from rasa_sdk import Tracker
from rasa_sdk.events import SlotSet, AllSlotsReset
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.forms import FormAction, REQUESTED_SLOT
logging.basicConfig(level="DEBUG")
logger = logging.getLogger()
class Name_Form(FormAction):
"""Example of a custom form action"""
def name(self):
# type: () -> Text
"""Unique identifier of the form"""
return "name_form"
@staticmethod
def required_slots(tracker:Tracker) -> List[Text]:
"""A list of required slots that the form has to fill"""
return ["name"]
def slot_mappings(self):
# type: () -> Dict[Text: Union[Dict, List[Dict]]]
"""A dictionary to map required slots to
- an extracted entity
- intent: value pairs
- a whole message
or a list of them, where a first match will be picked"""
return {"name": [self.from_entity(entity="name"),
self.from_text()]}
def submit(self,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any]) -> List[Dict]:
"""Define what the form has to do
after all required slots are filled"""
"" here we can write code to do what we want (like if want to enter email here can check its format with specific structre (
def validate_email(self,
value: Text,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any]) -> Any:
regex = '^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$'
if(re.search(regex,value)):
return value
else:
dispatcher.utter_template('utter_wrong_email', tracker)
# validation failed, set slot to None
return None
)
return []
Save your file. The actions
service should be rebuilding and you should see this in the terminal window showing logs (botfront logs
):
INFO:rasa_sdk.executor:Registered function for 'action_guests'.
# 7. Update your story
Now let's change the story we created earlier: replace the bot response utter_ok
with name_form
* inform_guests
- name_form
- form {"name":"name_form"} ## to deactivate the form after setting slot
- form {"name": null}
- slot{"name": "any value"}
::: tips
The action name
name_form
comes from thename()
method of theGuestsAction
class.In name_form, form muts be small not(capital)
Slot name in story is the same name in your form action
Must mention your slot in story sloyts to fill it
Form action it return utterance what is value=(your slot name)
Added you utterance to your responses
When wanting to mention your slot in action out the form_action , must use (tracker.get_slot("your slot name"))
:::
# 8. Retrain and test your bot
Then you can see the result:
# 9. Shutting down
You can safely shut down your project with botfront down
to free all resources. Your data is kept in the botfront-db
folder and will be accessible from Botfront the next time you turn it on.
# Next steps
Congratulations, you've learned how to use Rasa with Botfront! Everything you see on official Rasa documentation should apply with a few exceptions such as voice and messaging platforms.
← Actions Installation →