CoderSchool's Applied Frontier Technology (AFT) Tutorial Series

Chatbots can provide wonderful, fluid, and conversational experiences for many software products. They can also provide extremely frustrating experiences when implemented poorly! We'll try to avoid recreating ELIZA, instead using Google's DialogFlow to create a smart bot (known as an agent, like Agent Smith from the Matrix), and we'll hook this all up to a React Native UI.

We chose DialogFlow mainly because you don't need a credit card to sign up for DialogFlow, unlike Microsoft Bot Framework and AWS Lex. Thank you, Google Overlords.

We'll create a restaurant booking bot, partially because it is this author's humble opinion that calling to make reservations at a restaurant really sucks. Let's disrupt that already, people.

The main technologies we'll be using are DialogFlow and Gifted Messenger. But before we get into chatbots, let's start with an homage to the original chatbot: Zork, the Great Underground Empire. Viewer discretion is advised as the content may be inappropriate for anyone under the age of 45.

Step 1: Set up React Native

Assuming you've followed the instructions to set up Expo and React Native, the first step is to add two libraries: react-native-gifted-messenger and react-native-dialogflow-text.

npm install -S react-native-gifted-messenger react-native-dialogflow-text

Then, you can replace all of App.js with the following boilerplate code:

We've  done nothing more than instantiate a GiftedMessenger component with its basic accoutrements, and initialized our program's state with a base message of Hello CoderSchool Fan!. Now, you should see a basic screen where you can talk excitedly to yourself.

Step 2: Setup Google DialogFlow

Log into DialogFlow. Set up an account (again, no credit card necessary!) and click on "Create your first agent". We'll resist our urges to name it Agent Amith and instead name it restaurant_bot.

You'll be taken automatically to the Intents screen, where you can create an intent. An Intent is a collection of inputs / sentences with the same meaning, which our agent will know how to process.

In other words, the Intent is how we map sentences to what we expect the bot to do (ex: we tell the bot to “make a booking” and we expect a booking to be made and to receive a confirmation). The collection of sentences, also called Training Phrases, are how we ask the bot to trigger the Intent.

We'll name our intent restaurant.booking.create, and seed it with a few Training Phrases:

Book a table
Make reservations
Reserve a table
Book a table for 3
Make reservations for 5
Reserve a table for 2

As you type these in, you'll see Google automatically start to highlight the numbers in yellow. Google is detecting these numbers to be significant; they are being recognized as an Entity.  An Entity is a keyword extracted from Training Phrases. The value can then be further used as a parameter. It is not necessary to create entities for every word, just the ones that are important for our final result (our fulfillment).

Click on the parameter name, and rename our entity from number to guests, and tick the box to make this parameter required. Doing so will create a "prompts" column, where we can have our bot prompt for when the user does not enter in a value for $guests.

Enter in some prompts of your choice; DialogFlow will choose randomly from the list to prompt the user when $guests cannot be extracted from the input.

For how many guests?
How many guests will be joining?
How many guests will be seated at the table?

Finally, we're ready to add Responses. We can use the value of our entity, $guests, in the response.

Remember to hit the save button in the upper right.

Step 3: Connect back to React Native

Remember the react-native-dialogflow-text package? Time to use that now. (FYI - we created forked and published that library just for you, dear reader). But first, a few steps in DialogFlow, so we can use V2 of the DialogFlow API:

  • Go to Settings (the gear icon, next to your agent's name in the left menu).
  • Click Add service account. If you don't see this option, make sure you've set your version to V2 (and saved afterwards).
  • Click the Service account.

Once in the service account, find the account that's named Dialogflow Integrations, and scroll to the right until you see the three dots. Click on this menu, and click Create Key. Download it as JSON, and open that file in an editor. Note your:

  • client email
  • private key
  • project id

Now, back in React Native: create a new function called componentDidMount, and supply it with the following (replace the values from your JSON file)L

Dialogflow_V2.setConfiguration(
        "your client email,
        "your private key",
        Dialogflow_V2.LANG_ENGLISH_US,
        "your project id"
);

Now, in our onSend function, add the following line at the end to send the text of the message to your agent.

let text = messages[0].text;
Dialogflow_V2.requestQuery(
      text,
      result => this.handleGoogleResponse(result),
      error => console.log(error)
    );

To handle the response, we'll create a handleGoogleResponse function:

// Not quite production ready ;)
handleGoogleResponse(result) {
	let text = result.queryResult.fulfillmentMessages[0].text.text[0];
    this.sendBotResponse(text);
  }

That's it, folks.

What next?

As with any hastily written software project, there are many more features we could add, both to the agent, and to our application.

  • Rich Fulfillment Options (having photos, maps)
  • Validation on guests (e.g. not allowing 0 guests)
  • Voice integration
  • Asking for the time and date
  • Conversing if requested options aren't available (e.g. you can't make a reservation at 2 a.m.)

The list goes on. If you have anything to add, fire a pull request - the whole application is available on GitHub, or leave something in the comments! Thank you.