A Step-by-Step guide to create a Chatbot Assistant Using RASA

Mahesh Babu Athmakuri
9 min readMay 28, 2020
How our assistant looks after development.

Have you ever wondered! how easy it is to create a conversational assistant(Chatbot).With the new age technologies like Machine Learning and Artificial Intelligence, it became very easy to create a Chatbot. In this blog, we are going to discuss one of the most famous and open source conversational AI framework for creating contextual Assistant. i.e. Rasa

What you will learn in this.

  • How to create a Rasa Project.
  • How to develop a simple Movie ticket booking bot with Rasa.
  • How to integrate bot into Webpage.

For creating chatbots using the Rasa framework you need not to be a ML/AI developer and with very minimal programming knowledge you can develop an interactive Conversational Assistant.

So without further delay let’s see the step by step how to create a simple movie booking chatbot.

Prerequisite: Anaconda distribution to be installed.

Step 1:

Create a conda environment with the name of rasa(you can name anything).

conda create -n rasa python=3.6

Activate the rasa environment.

conda activate rasa

Step 2:

Install Rasa Open Source using pip.

Pip3 install rasa

Step 3 :

Now create a new folder wherever you want to create the Rasa project and navigate to inside the folder and then execute the below command to create a new Rasa project

This command creates a new basic Rasa project with few required files that are necessary to run Rasa project.

rasa init

It prompts with the below message. Then press enter.

Please enter a path where the project will be created [default: current directory] .

It prompts with another message

“Do you want to train an initial model?” . Press Y/n.

If you press “Y” then the basic model will be trained and this basic model is ready to run.

If you press “n” then the model will not be trained and you can train the model later by using the command “rasa train”

Once the project is created, you can see the below files will be created in the project folder.

Let’s understand the files created by Rasa.

Under the data folder, two files are created.The first file is nlu.md and the other one is stories.md.

nlu.md : NLU means Natural Language Understanding and contains your training data.

The messages which have similar meaning are grouped together and named with intents. Intent means finding the user’s intentions. Once your model is trained, Rasa will identify the correct intent for your new/unseen messages.

Now, we will add the new intent named as inform to our nlu.md file.

## intent:inform
- [telugu](language)
- [english](language)
- [hindi](language)
- [tamil](language)
- [malayalam](language)
- [Bahubali](movie_name)
- [Ala Vaikuntapuramlo](movie_name)
- [Villan](movie_name)
- [joker](movie_name)
- [Murder](movie_name)
- [Noescape](movie_name)
- [murder](movie_name)
- [villan](movie_name)
- [2020-05-13](planned_date)
- [2020-05-14](planned_date)
- [2020-05-16](planned_date)
- [2020-06-01](planned_date)
- [2020-05-18](planned_date)
- [2020-05-20](planned_date)
- [2020-05-22](planned_date)
- [2020-05-25](planned_date)
- [2020-06-20](planned_date)
- [2020-06-12](planned_date)
- [2020-06-16](planned_date)
- [2020-05-28](planned_date)
- [Asian Cinemas](theater_name)
- [PVR Icon](theater_name)
- [GVK](theater_name)
- [Forum Mall](theater_name)
- [Manjeera Mall](theater_name)
- [Prasad's Mlutiplex](theater_name)
- [PVR Cinemas](theater_name)
- [Gokul Theater](theater_name)
- [INOX](theater_name)
- [Carnival Cinemas](theater_name)
- [Platinum Movie Time](theater_name)
- [Asian Shiv Ganga](theater_name)
- [Sensation theater](theater_name)
- [Sensation Ismonia](theater_name)
- [Vijetha Theater](theater_name)
- [Bhujanga Theater](theater_name)
- [Carnival Movie Time](theater_name)
- [Asia Multiplex](theater_name)
- [PVR](theater_name)
- [GVK](theater_name)
- [10:00 AM](planned_time)
- [11:00 AM](planned_time)
- [12:00 PM](planned_time)
- [12:30 PM](planned_time)
- [01:00 PM](planned_time)
- [02:00 AM](planned_time)
- [04:00 AM](planned_time)
- [05:00 PM](planned_time)
- [07:30 PM](planned_time)
- [09:00 PM](planned_time)
- [1](no_of_tickets)
- [3](no_of_tickets)
- [5](no_of_tickets)
- [7](no_of_tickets)
- [9](no_of_tickets)
- [10](no_of_tickets)
- Book a [10](no_of_tickets) [Bahubali](movie_name) [telugu](language) tickets for [GVK](theater_name) on [2020-05-20](planned_date) at [09:00 PM](planned_time) show.
- Please Book a [5](no_of_tickets) [Villan](movie_name) [hindi](language) tickets for [PVR](theater_name) on [2020-06-12](planned_date) at [07:00 PM](planned_time) show.
- Kindly book a [2](no_of_tickets) [Noescape](movie_name) [english](language) tickets for [Krishna Mahal theater](theater_name) on [2020-05-28](planned_date) at [11:00 AM](planned_time) show.
- Book a [4](no_of_tickets) [Ala vaikuntapuramlo](movie_name) [telugu](language) tickets.
- Book [Bahubali](movie_name) tickets.
- I wanted to go for [telugu](language) movies
- Iam looking for [telugu](language) movies
- Iam palnnig to book [English](language) movies
- Iam palnnig to book [Hindi](language) movies
- Iam wanted to book [Bahubali](movie_name) [telugu](language) movie.
- I wanted to go for [Dhangal](movie_name) [telugu](language) movie
- Iam looking for [Robo](movie_name) [telugu](language) movies
- Iam palnnig to book [Bahubali](movie_name) [English](language) movies
- Iam palnnig to book [Bahubali](movie_name) [Hindi](language) movies

So we have added the new intent(inform) and entities language, movie_name, planned_date, theater_name, planned_time, no_of_tickets

Entity is nothing but important data and usually this can be names, date, time etc. We extract the entities from the intent which are useful for taking next actions.

Stories.md : It contains the stories of how the user interaction will be. In this file, we will teach our assistant how to respond to specific intents either in the form of text or actions. Actions can be anything either calling the backend or some third party API’s.

## happy path
* greet
- find_language_types
- slot{"language":"telugu"}
* inform{"language": "telugu"}
- find_movie_names
- slot{"movie_name":"Bahubali"}
* inform{"movie_name":"Bahubali"}
- find_available_dates
- slot{"planned_date":"13-05-20"}
* inform{"planned_date":"13-05-20"}
- find_theater_names
- slot{"theater_name":"Asian Cinemas"}
* inform{"theater_name":"Asian Cinemas"}
- find_show_timings
- slot{"planned_time":"10:00 AM"}
* inform{"planned_time":"10:00 AM"}
- find_no_of_tickets
- slot{"no_of_tickets":"5"}
* inform{"no_of_tickets":"5"}
- ticket_booking_form
- form{"name": "ticket_booking_form"}
- form{"name": null}
* goodbye
- utter_goodbye
## happy path 1
* inform{"language": "telugu", "movie_name":"Bahubali"}
- find_available_dates
- slot{"planned_date":"13-05-20"}
* inform{"planned_date":"13-05-20"}
- find_theater_names
- slot{"theater_name":"Asian Cinemas"}
* inform{"theater_name":"Asian Cinemas"}
- find_show_timings
- slot{"planned_time":"10:00 AM"}
* inform{"planned_time":"10:00 AM"}
- find_no_of_tickets
- slot{"no_of_tickets":"5"}
* inform{"no_of_tickets":"5"}
- ticket_booking_form
- form{"name": "ticket_booking_form"}
- form{"name": null}
* goodbye
- utter_goodbye

From the above code, we are teaching our assistant to once the greet intent is identified, execute the action(find_language_types) and fill the slot language. Language slot can be filled with any value.

Slot is nothing but a variable which holds the values entered by the user throughout the session and the slot values can be passed through next conversation.

Step 4 :

domain.yml file defines the universe where your assistant lives in. It contains all the list of intents, entities, slots, actions, responses.

session_config:
session_expiration_time: 60
carry_over_slots_to_new_session: false
intents:
- greet
- goodbye
- affirm
- deny
- mood_great
- mood_unhappy
- bot_challenge
- search_movies
- inform
entities:
- language
- movie_name
- planned_date
- theater_name
- planned_time
- no_of_tickets
slots:
language:
type: text
movie_name:
type: text
no_of_tickets:
type: text
planned_date:
type: text
planned_time:
type: text
status:
type: unfeaturized
theater_name:
type: text
responses:
utter_greet:
- text: Hey! Iam Bot. I can assist you in booking movie tickets. Please choose one of the following language of movies you wanted to go for?utter_cheer_up:
- text: 'Here is something to cheer you up:'
image: https://i.imgur.com/nGF1K8f.jpg
utter_did_that_help:
- text: Did that help you?
utter_happy:
- text: Great, carry on!
utter_goodbye:
- text: Bye
utter_iamabot:
- text: I am a bot, Assist you in booking movie tickets.
utter_ask_movie_name:
- text: I understand you like to go for {language} movies. Please enter the Movie Name.
utter_select_movie_name:
- text: I understand you like to go for {language} movies. Please select the Movie Name.
utter_ask_planned_date:
- text: Please enter the date in the format of dd-mm-yy
utter_select_planned_date:
- text: Please select the date.
utter_ask_theater_name:
- text: Please enter the theater name.
utter_select_theater_name:
- text: Please select the theater name.
utter_ask_planned_time:
- text: Please enter the time in the format of hh:mm
utter_select_planned_time:
- text: Please select the show time.
utter_ask_no_of_tickets:
- text: How many tickets you want to book?
utter_select_no_of_tickets:
- text: Please select number of tickets you want to book.
utter_booking_status:
- text: As per your interest, {no_of_tickets} tickets for {movie_name} {language}movie in {theater_name} on {planned_date} at {planned_time} booked successfully.
actions:
- utter_greet
- utter_cheer_up
- utter_did_that_help
- utter_happy
- utter_goodbye
- utter_iamabot
- find_language_types
- find_movie_names
- find_available_dates
- find_theater_names
- find_show_timings
- find_no_of_tickets
- utter_ask_theater_name
- utter_select_theater_name
- utter_select_planned_time
- utter_ask_movie_name
- utter_select_movie_name
- utter_ask_no_of_tickets
- utter_select_no_of_tickets
- utter_booking_status
- utter_ask_planned_date
- utter_select_planned_date
- utter_ask_planned_time
forms:
- ticket_booking_form

Thus the user enters the message, Rasa predicts the user intention and identifies the intent from nlu.md file and based on the intent the respective utterance will be triggered as per we have mentioned in stories.md file.

So if the utterance is response then the respective utterance response(“Bye”) will be executed as per domain.yml file and if the utterance is action then respective action will be triggered from actions.py file.

Example: Let’s assume, If the user enters the message “bye” the Rasa predicts the intent as “goodbye” from nlu.md file and “utter_goodbye” will be triggered as per stories.md file and finally the utterance response(“Bye”) will be executed as per domain.yml file.

In the same way, If the user enters the message “hello”, the Rasa predicts the intent as “greet” from nlu.md file and the action “find_language_types” will be triggered as per stories.md file which we will be implementing now in actions.py.

Step 5 :

actions.py contains all the custom actions. If your bot wants to display a simple response then you can manage simply by adding the responses in the domain.yml file. Whereas if you want to do some action when a specific intent is triggered then you can implement the custom actions in actons.py file.

## Importing the required librariesfrom rasa_sdk.forms import FormAction
from rasa_sdk import Action, Tracker
from rasa_sdk.executor import CollectingDispatcher
from typing import Any, Text, Dict, List
from rasa_sdk.events import SlotSet, Form
import logging
import datetime
LANGUAGES = {
"telugu":
{
"name": "telugu",
"resource": "tl"
},
"english":
{
"name": "english",
"resource": "en"
},
"hindi":
{
"name": "hindi",
"resource": "hn"
}
}
def _resolve_name(languages, resource) ->Text:
for key, value in languages.items():
if value.get("resource") == resource:
return value.get("name")
return ""
class FindLanguageTypes(Action):
"""This action class allows to display buttons for languages to choose."""
def name(self) -> Text:
"""Unique identifier of the action"""
return "find_language_types"def run(self,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any]) -> List:

buttons = []
for t in LANGUAGES:
language = LANGUAGES[t]
payload = "/inform{\"language\": \"" + language.get(
"name") + "\"}"
buttons.append({"title": "{}".format(language.get("name").title()),
"payload": payload})
# TODO: update rasa core version for configurable `button_type`
dispatcher.utter_button_template("utter_greet", buttons, tracker)
return []

The above function displays buttons to choose available language movies. Instead of considering the Languages dictionary, you can call the API to fetch the data.

So if you run the application and enter a message “hi”, then “greet” intent will be identified by Rasa and then “find_language_types” action will be executed and displays buttons as below.

Let’s assume, If you click on “telugu”, then the “/inform{“language”: “telugu”}”(which we have appended the payload to the buttons in the find_language_types action) intent will be identified and then corresponding action “find_movie_names” will be called. The complete code is available in my github.

Step 6:

Credentials file contains credentials of different platforms in which your bot is running.In our example, we will be running our bot in a simple webapage which uses socket connection to connect the bot. A Socket is a bi-directional protocol which listens continuously and it is helpful to send/receive messages.

Add the below code for running our bot through socket channel:

socketio:
user_message_evt: user_uttered
bot_message_evt: bot_uttered
session_persistence: true/false

Step 7 :

endpoints.yml contains different endpoints your bot can use.By adding the below code into the endpoints file, we are telling the bot to listen our actions from the host — localhost, through the port — 5055 and /webhook is the endpoint.

action_endpoint:
url: "http://localhost:5055/webhook"

Step 8 :

Config.yml file contains all the configurations related to NLU and the Rasa core. Such as in which language our bot runs and it also contains different pipelines which are used to predict the specific intent and extract the entities. The policies are used to respond to how and what the next action should be.

Step 9 :

Run the bot with the following command.

rasa run -m models --enable-api --cors "*" --debug

So with the above command our bot will run in http://localhost:5005

And parallely run the rasa actions with the below command

rasa run actions

You can test your bot with Rasa UI by running below command and click on top left icon talk to your bot.

rasa x
Running bot with Rasa UI

Run the below command to know how the execution is happening.

rasa interactive

Open the url in browser to see the execution flow http://localhost:5006/visualization.html

Execution Flow

Step 10:

You can integrate your bot into any webpage or into your existing website.

Create an index.html page in the project directory and place the below code.

<head>
<link rel="stylesheet" href="https://npm-scalableminds.s3.eu-central-1.amazonaws.com/@scalableminds/chatroom@master/dist/Chatroom
.css
" />
</head>
<body>
<div class="chat-container"></div>
<script src="https://npm-scalableminds.s3.eu-central-1.amazonaws.com/@scalableminds/chatroom@master/dist/Chatroom.js"/> </script>
<script type="text/javascript">
var chatroom = new window.Chatroom({
host: "http://localhost:5005",
title: "Movie Ticket Booking",
container: document.querySelector(".chat-container"),
welcomeMessage: "Hi, I am Movie ticket Booking bot. How may I help you?"
});
chatroom.openChat();
</script>
</body>

The above code is taken a reference from here.

So finally, you can build a simple movie ticket booking bot by following with these steps and Please give a clap if you like it.

Don’t forget to give us your 👏 !

--

--