•January 14th 2020
This tutorial will teach you how to build your own customer-support chat experience and create a serverless chatbot! The end result will look much like this:
The customer-facing chat experience is shown on the left, and the screen on the right shows the interface for support agents.
Here’s a GIF of the chatbot in action:
In order to help you achieve this end result and understand how you did so, we’ll walk you through the following sections:
Part 1 - React Chat Customer Service Chatbot
Part 2 - React Chat Agent View
Part 3 - LUIS Training for Your Chatbot
Part 4 - Webhook Integration with Stream
Part 5 - Serverless Azure Hello World
Part 6 - Serverless Webhook Handler Using Azure
The final code is stored in a GitHub repo; we encourage you to take the time to go through the process below in order to understand how to produce your very own chatbot, however, if you get stuck at any point during this tutorial you can look up the source code in the GitHub repo.
Part 1 - React Chat Customer Support Chatbot Tutorial
As a first step, we’re going to build the React interface that enables customers to ask questions. The end result of this part of the tutorial will look like this:
Setting up the frontend for customer support is easy. In this case, we’ll use React. If you want to use a different platform you’ll want to check out these tutorials: React Chat Tutorial, React Native Chat Tutorial, iOS/Swift chat Tutorial, and, Android Chat Tutorial.
Step 1: Create a New React App
Make sure you have
http://localhost:3000 and you should see the default Create React App screen:
Step 2: Get A Stream API Key
Visit Stream and register to get an API key.
For the purpose of this tutorial, we’ll disable auth and permissions checks (note you should obviously not do this in a production app, but it allows you to focus on your chat experience instead of integrating your auth system). Open your Stream Dashboard, click your app, select “Chat” and disable authentication & permissions:
Important: You will need to click on your application and enable the “Disable Auth Checks” toggle as well as the “Disable Permissions Checks” toggle.
- Open your Stream Dashboard and copy your API key to your
You can create your
.env file in your favorite editor and add the Stream API key. The full path of the file where you’ll want to add your API key is
chatbot-tutorial/chat-frontend/.env. The line where you add your API to your
.env file should be formatted as such:
Step 3: Edit App.js
As a first step, we’ll add a toggle button in the bottom right corner that prompts the user to click it to start or continue a chat session. To start, replace the code in
src/App.js with the following code snippet:
Note: At first, you will get warning messages about unused imports; to keep things simple, we included all imports now so that it is easier to follow this tutorial. Once our app is completed, you should not see these warnings again.
After you’ve updated your
App.js file, open
src/index.css and replace the CSS with the following:
By now, your chat experience should look like this:
You can toggle the button, but it doesn’t do anything just yet. Note how clean the App.js code is, as a result of using React Hooks!
Step 4: Guest User Interface
For the purpose of this demo, we will ask the user to provide their name and email. Stream Chat supports 3 types of user authentication, and it depends on your use case as to which one works best:
Regular users (Use this if the user asking support questions is already logged in – especially for in-app support it’s common for users to be logged in)
Guest Users (Allow users to set a guest name and email)
Anonymous Users (Allow users to chat without providing any details)
To begin the process of gathering information to authenticate the user, go ahead and open up
src/App.js and add the
GuestUserInput component to the file (just above your
Next, we need to change the
App component to render the
GuestUserInput and the chat interface. We’ll update our
App component to look like this:
By now, your chat experience should show you an interface to set up your guest user:
If you submit your details, you’ll get an API error logged, since we didn’t create a user account for the support agent yet; let’s do that now!
Step 5: Create a User Account for the Support Agent
Start by installing the
yarn global add getstream-cli
Next, configure your account:
It will automatically ask you for some configs. Be sure to use your own API key and secret:
And, finally, create the user with a
userID of “support-agent-123”:
stream chat:user:create -u support-agent-123 --role user
Step 6: Render a Chat Interface
You will notice that you see an empty screen after entering your details. As a next step, we’ll add the actual chat components.
Replace the dummy
renderChat function in your
App component in
src/App.js with the following:
You’ll now see a functional chat interface when you fill in your user details:
Note how easy it is to build a chat interface by leveraging the
MessageInput components. All of these are fully customizable, and you can write your own if you want to! Have a look at the React Chat Tutorial to learn more.
Step 7: User Presence & Showing Who Is Online
It would be nice to show a
ChannelHeader that shows who is currently online... So, let’s create a custom
ChannelHeader component called
Next we’ll add the
MyChannelHeader to the
renderChat function. The updated function now looks like this:
yarn start in the chat-frontend directory and visit
http://localhost:3000. You’ll now see a functional chat experience with a header which shows who is currently online:
Part 2 - Dashboard for the Live Chat
For the agent, we want an interface that allows them to productively talk to many people at once. To begin to create this, we’ll start with a Create React App app, again:
Step 1: Create a New React App
Make sure that you are in the
chatbot-tutorial directory, and run:
Step 2: Create Your .env.development
.env file from the frontend project:
cp ../chat-frontend/.env .env
The API key is the same as you used in Part 1. In the case that you’ve forgotten what it was, head over to Stream’s dashboard to look it up again (or check the
.env file you created in the last section).
Step 3: Edit src/App.js
chat-agent-dashboard/src/App.js and replace the contents with:
Step 4: Run yarn start
Be sure to run yarn start in the chat-agent-dashboard directory and visit http://localhost:3001. Your agent interface will now look like this:
Note: If you get an error about an invalid token, be sure to disable auth and permissions checks in the dashboard.
Some cool features to note:
- File Uploads
You can upload files to the chat via drag & drop, copy/pasting or manually selecting a file:
- Rich URL Previews
If you post a URL, you’ll see a rich preview in the chat interface:
- Typing Indicators
When either user is typing, a dot animation will pop up to indicate this to the opposite party:
- Online Status for Agent and Customer
The customer will be able to see which agents are online at the top of the interface:
Part 3 - LUIS Azure Training for Your Chatbot
To begin setting up the questions/statements your chatbot will be able to address and the responses it should have, head over to https://www.luis.ai/ to set up your Language Understanding Service (LUIS). LUIS analyzes messages and tells you what the intent is. Here are some examples:
For the purpose of this blog post, we’ll teach LUIS to recognize the “restaurant reservation” intent and we’ll teach it the answer to life the universe and everything.
Step 1: Create an App
Sign in to the LUIS dashboard and create an application. Once logged in, click “Create new app” as shown in the screenshot below:
When prompted, specify the following for your chatbot (and, then, click “Done”):
Step 2: Create a New Intent
As a next step, we’ll create a new Intent called “Answer”, inspired by the amazing Hitchhiker's Guide to the Galaxy. Click on the “Build” button at the top right, and then click on “Create new intent”:
You will be prompted for the intent name (“Answer”). Once loaded, specify your “utterances” to LUIS:
- What’s the answer to life the universe and everything
- What’s the answer
- The answer please
- Tell me the answer
- What’s the meaning of life
- What’s the answer to the universe
Step 3: Leverage a Built-In Intent
We’ll also add a built-in Intent. Click on the Intents button to take you to the previous page. From there, click the “Add prebuilt domain intent” button.
Select the RestaurantReservation.Reserve intent and then click the “Done” button.
Step 4: Train the Model
Now that we’ve updated the settings, we’ll want to train the model. Hit the “Train” button in the top right corner:
Step 5: Publish the Model to Production
Hit the “Publish” button and select Production. This is important; if you select “Staging”, the next steps in the tutorial will fail. Wait a few seconds for your model to be published.
In the meantime, let’s take note of 3 settings... To access them, click Manage -> Application Information:
- Your application ID:
- Your primary key and (3) region:
Part 4 - Learn How to Use Stream Webhooks
As a next step, we’ll connect Stream’s webhook to Azure. To do this, we’ll leverage the Stream CLI.
Step 1: Verify Stream-CLI is installed
Verify that you have Stream’s CLI installed (you used it to configure the user in Part 1 of this tutorial):
$ stream version
If you don’t have it installed yet, you can install the CLI by running the following
$ yarn global add getstream-cli
And set up your API key like this:
$ stream config:set
Step 2: Test the Webhook
To test the webhook integration, we’ll create a new request bin (it doesn’t need to be private).
Next, configure your new request bin as your webhook URL for Stream. Be sure to replace the URL in the following command with the request bin URL you’ve just created:
$ stream chat:push:webhook --url https://enfspya8mur9f.x.pipedream.net
If you visit http://localhost:3000 and leave a chat message you should see the message.new event shows up in the request bin:
Awesome! Now that you’ve learned how to set up Stream’s webhooks, we’ll continue to the serverless part of this tutorial.
Part 5 - Serverless Azure Chat
We’ll want to leverage an Azure Function app to connect Stream & LUIS. The function needs to do these 3 things:
Parse the Stream webhook data
Run intent analysis with LUIS
Send a reply on the channel if we recognize the intent
Follow along with the steps below to get your Azure Function up and running:
Step 1: Set Up Azure
Go to https://portal.azure.com and set up your account. You get $200 in credits when you sign up so you can complete this tutorial without setting up any billing. Microsoft recently changed Azure to ask you to verify your phone number & credit card in the next step. (which is a bit annoying...)
Step 2: Create a Function App
Search for “Function App” and select it:
Click Add and once on the next screen, you’ll want to select the following:
Function App Name: ChatbotTutorial
Runtime Stack: Node
and click Review & Create.
Now, hit Create to spin up your function app! This takes anywhere from a few seconds to a few minutes.
Your function app should now be provisioned:
Great! Now that we’ve created our function app, it’s time to write a little bit of code:
Step 3: Verify Azure Functionality
Make sure you have azure functions core tools up and running:
$ yarn global add azure-functions-core-tools
You can verify it worked by running
func version. As of January 2020, the current version is 2.7.1948.
Step 4: Set Up Serverless Directory
Set up your serverless directory using the following shell commands:
Step 5: Create New Message Handler Function
In this next step, we’ll create a handler function called
$ func new -t "HTTP trigger" --name "NewMessageTrigger"
Step 6: Test New Message Handler Function
Next, we’ll want to test our
NewMessageTrigger function locally:
$ func start
Note: If you receive an error about your version of Node.js, you can fix that using the following installing node v10.14.1 or by using NVM as shown below.
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash $ nvm install 10.14.1 $ nvm alias default 10.14.1 $ yarn install
You should now be able to try out your local function by visiting:
Part 6 - Serverless Webhook Handler with Azure
Ok, now that we’ve got the basics in place, let’s connect all the dots! Remember, we want to accomplish the following:
Handle the incoming data from Stream’s webhook platform
Run intent analysis using Azure’s LUIS
Reply to the user in the chat
Step 1: Create Your Serverless Project
Go to the serveless folder and install the dependencies:
$ yarn add stream-chat axios dotenv
Step 2: Set Up Your Function Handler
Replace the code in
NewMessageTrigger/index.js with the following:
Let’s take a moment to understand the above code... We start by receiving the request; the body of the request (
req.body) has the information from Stream’s webhook. When we receive an event of type
message.new, and (this is important) the message is not written by a bot, we run intent analysis via LUIS. If we understand the intent, the bot replies on the channel.
Step 3: Create a Local .env File
Create a file called
.env, the full path is
serverless/.env with the following settings:
Step 4: Configure Your Production .env
To go live, we’ll want to configure those same environment settings in Azure’s web interface. First click “Go to resource”:
Next click “Function app settings”:
And select “Manage application settings”:
On this page you can add the same 5 environment variables you’ve just added to your
Login to Azure using the following command:
$ az login
You will be prompted to authenticate via your browser as shown in the screenshot below (this is really well done):
And deploy the function using this command:
$ func azure functionapp publish ChatbotTutorial
Note: If you run into an error, ensure that you have installed the azure-cli:
$ brew update && brew install azure-cli
Note: The invocation URL will be provided in the response body after publishing your function (as shown in the above screenshot).
When you run the above command, you’ll receive an “invoke url”; you’ll want to update your webhook URL to point to your invocation URL a shown below:
$ stream chat:push:webhook --url yourinvokeurl
After following this last step, your bot will be fully connected to the chat interface! Try it out by typing something such as:
“What’s the answer?”
“make a reservation”
In the chat interface:
A side note on Debugging with NGROK
Webhooks can be a little bit hard to work with. A tool that helps with local debugging is NGROK, which gives you a public URL for your local endpoint.
To utilize NGROK, first, ensure that your server is running by running:
Next, install NGROK by following the instructions on their site:
Then, expose your local web server using
$ ngrok http 7071
This makes it easier to test changes (rather than you having to deploy to Azure while you’re coding). Let’s see if it works by configuring Stream’s webhook:
$ stream chat:push:webhook --url http://<YOUR_NGROK_URL>/api/NewMessageTrigger\?name\=thierry
Concluding the Chatbot Tutorial
After following the above tutorial you should have a fully functional chatbot for your application! It should look very similar to this:
If at some point you got stuck, head over to the GitHub repo to check out the end result of this tutorial and compare to the code you’ve written.
Additionally, this tutorial used React for the user interface. Have a look at the React Native Chat Tutorial, iOS/Swift Chat Tutorial or Android/Kotlin Chat Tutorial, if you want to use a different platform!
To learn more you might want to check out: