Hands-on: Create a TV guide Google Chat with Google Workspace and Dialogflow

1. Introduction

Now that you've built a Dialogflow chatbot for a TV Guide in the previous codelab, we're going to show you how to extend it to Google Chat. You will learn how to construct dynamic, interactive cards for this platform and have a bot that has multiple integrations.

What you will build

We will build a Dialogflow chatbot that can respond in your G Suite domain with customizable responses.

2e16770ceed20cb2.png

What you'll learn

  • How to deploy and configure a Hangouts Chatbot
  • How to build display cards in Hangouts Chat
  • How to build custom payloads in Dialogflow fulfillment

What you'll need

  • Complete the first codelab in this 2-part series.
  • A web browser and an email address to log into the Dialogflow console
  • Chat enabled in your Google Workspace domain

2. Enable and Configure Hangouts Chat

We will start with the Dialogflow Agent you have created in the previous codelabs.

  1. In the Dialogflow console, click d7d792687e597dd5.png.
  2. In the General tab, scroll to Project ID, then click Google Cloud f2bffd4fcdb84fa9.png.

cb893582402e4092.png

  1. In the Google Cloud Console, click Navigation menu ☰ > APIs & Services > Library.
  2. Search for "Hangouts Chat API," then click Enable to use the API on your Google Cloud project.
  3. Now we will configure your chatbot, navigate to the Configuration page for the API. Please note each GCP project can have at most one chatbot. 85794eaaaedc7eb5.png
  4. You should see the Dialogflow fields populating the configuration options.
  5. Change the Avatar URL field to this tv image: [https://fonts.gstatic.com/s/i/googlematerialicons/tv/v5/black-48dp/1x/gm_tv_black_48dp.png](https://fonts.gstatic.com/s/i/googlematerialicons/tv/v5/black-48dp/1x/gm_tv_black_48dp.png)
  6. Enable your bot for both direct messages and rooms 9d439f492c8b71bb.png

Click Save and exit the Cloud Console.

Additionally Dialogflow Integrations. Hangouts Chat is enabled by default but if you would like a bot to serve multiple platforms, you may navigate to the Integrations page in the Dialogflow Console to enable them.

63296523b678ff8d.png

3. Test in Google Chat

Now that your chatbot is configured, let's add it to a chat room and test it out. Open Hangouts Chat and create a test chat room. In the upper right corner of the room click the drop down and select Add people & bots.

f0dd1f5e205ef8e2.png

Search for tvguide and add the bot to the room.

e60fa78fdd020304.png

You can now interact with the bot you already have built in Hangouts by simply typing @tvguide in the room. Type @tvguide hello to test it out.

e8399e33185c63ec.png

Next we will use the customizations in Hangouts to add richer responses.

4. Custom Hangouts Chat Cards

With Hangouts Chat, you can have your bot return the user a basic Text Response or a Card Response which allows you a richer interface built by different widgets including images, buttons, etc. Now that we have connected your Dialogflow Agent to a Hangouts Chat bot, you simply need to return the JSON in the correct format to display in Hangouts in your fulfillment code. Let's look at some JSON examples.

The basic text response looks like:

{
  "text": "Welcome, I am the TV Guide agent. I can tell you what is currently playing on a TV channel. For example, you can ask me: What is on MTV?"
}

e8399e33185c63ec.png

A sample card response with widgets looks like:

{
  "cards": [
    {
      "sections": [
        {
          "widgets": [
            {
              "image": { "imageUrl": "https://freesvg.org/img/fttv.png" }
            },
            {
              "buttons": [
                {
                  "textButton": {
                    "text": "Check Listings",
                    "onClick": {
                      "openLink": {
                        "url": "https://tvlistings.com/..."
                      }
                    }
                  }
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

c390a0cb75486fe0.png

5. Custom Payloads and Chat Cards

Custom payloads in Dialogflow allow for platform-specific rich response messages. This is where we will add our Hangout Chat JSON cards where they will be served back to the user by the agent.

Let's start by adding a basic card for the welcome intent. In the Dialogflow Console, navigate to the Default Welcome Intent and scroll down to the responses section.

9624208f0d266afd.png

Click on Hangouts and unselect Use responses from the DEFAULT tab as the first responses, then ADD RESPONSES > Custom Payload.

You will see a JSON skeleton.

bb064f7ec1237fd3.png

Copy and paste the following code below. We have set up a card with a TextParagraph widget.

{
  "hangouts": {
    "header": {
      "title": "TV Guide Bot"
    },
    "sections": [
      {
        "widgets": [
          {
            "textParagraph": {
              "text": "Welcome, I am the TV Guide agent. I can tell you what is currently playing on a TV channel. For example, you can ask me: What is on MTV?"
            }
          }
        ]
      }
    ]
  }
}

Hit Save then let's go to your test chat room to see this card is rendered. In the chat room, type ‘@tvguide hello'

6941003ee06e4655.png

Next we will add a custom payload in the fulfillment code so we can dynamically generate the content with our code.

To learn more about cards please see the Message Format documentation. In the next section we will add cards to our chatbot.

6. Adding a Card in Fulfillment

Now we will create a card with widgets to show TV listings. Let's add a function called getHangoutsCard where we will render the resulting listing information. We will use keyValue and button widgets to construct the card response.

Add the function below to your code in index.js at the bottom.

/**
*  Return a Hangouts Chat Card in JSON
* @param {Object} JSON tv results
*/
var getHangoutsCard = function(tvresults) {
   console.log('In hangouts card, tv results: ' + JSON.stringify(tvresults));

   if(tvresults['Listings'][0]) {
       let channelName = tvresults['Name'];
       let currentlyPlayingTime = getShowTime(tvresults['Listings'][0]['Time']);
       let laterPlayingTime = getShowTime(tvresults['Listings'][1]['Time']);

       const cardHeader = {
           title: channelName + ' Shows',
       };

       const currentWidget = {
           keyValue: {
               content: `${tvresults['Listings'][0]['Title']}`,
               bottomLabel: `${currentlyPlayingTime}`,
           }
       };

       const laterWidget = {
           keyValue: {
               content: `${tvresults['Listings'][1]['Title']}`,
               bottomLabel: `${laterPlayingTime}`
           }
       };

       const buttonWidget = {
           buttons: [
             {
               textButton: {
                 text: 'View Full Listing',
                 onClick: {
                   openLink: {
                     url: TVGUIDE_WEBSERVICE + '/' + tvresults['ID'],
                   },
                 },
               },
             },
           ],
         };

       return {
           'hangouts': {
               header: cardHeader,
               sections: [{widgets: [currentWidget, laterWidget, buttonWidget]}],
           }
       };
   } else {
       const errorWidget = {
           keyValue: {
               content: 'No listings found',
               bottomLabel: 'Please try again.'
           }
       };
       return {
           'hangouts': {
               'sections': {widgets: [errorWidget]},
           }
       };
   }
}

Now we need to call this method so the agent can get the response to send back to the user. In the function channelHandler, replace the contents of the function with the code below.

function channelHandler(agent) {
   console.log('in channel handler');
   var jsonResponse = `{"ID":10,"Listings":[{"Title":"Catfish Marathon","Date":"2018-07-13","Time":"11:00:00"},{"Title":"Videoclips","Date":"2018-07-13","Time":"12:00:00"},{"Title":"Pimp my ride","Date":"2018-07-13","Time":"12:30:00"},{"Title":"Jersey Shore","Date":"2018-07-13","Time":"13:00:00"},{"Title":"Jersey Shore","Date":"2018-07-13","Time":"13:30:00"},{"Title":"Daria","Date":"2018-07-13","Time":"13:45:00"},{"Title":"The Real World","Date":"2018-07-13","Time":"14:00:00"},{"Title":"The Osbournes","Date":"2018-07-13","Time":"15:00:00"},{"Title":"Teenwolf","Date":"2018-07-13","Time":"16:00:00"},{"Title":"MTV Unplugged","Date":"2018-07-13","Time":"16:30:00"},{"Title":"Rupauls Drag Race","Date":"2018-07-13","Time":"17:30:00"},{"Title":"Ridiculousness","Date":"2018-07-13","Time":"18:00:00"},{"Title":"Punk'd","Date":"2018-07-13","Time":"19:00:00"},{"Title":"Jersey Shore","Date":"2018-07-13","Time":"20:00:00"},{"Title":"MTV Awards","Date":"2018-07-13","Time":"20:30:00"},{"Title":"Beavis & Butthead","Date":"2018-07-13","Time":"22:00:00"}],"Name":"MTV"}`;
   var results = JSON.parse(jsonResponse);
   var listItems = {};
   textResults = getListings(results);


   for (var i = 0; i < results['Listings'].length; i++) {
       listItems[`SELECT_${i}`] = {
           title: `${getShowTime(results['Listings'][i]['Time'])} - ${results['Listings'][i]['Title']}`,
           description: `Channel: ${results['Name']}`
       }
   }

   if (agent.requestSource === 'hangouts') {
        const cardJSON = getHangoutsCard(results);
        const payload = new Payload(
           'hangouts',
           cardJSON,
           {rawPayload: true, sendAsMessage: true},
       );
       agent.add(payload);
   } else {
       agent.add(textResults);
   }
}

Take note of the code at the bottom where the hangouts response is added. If the agent's request source is identified as this platform we construct the JSON payload with the tag ‘hangouts'. This is important for correctly passing back the payload in fulfillment.

Now go back to your chat room and test it out. Type @tvguide What is on MTV?. You should see a similar response.

2e16770ceed20cb2.png

7. Congratulations

You have created your first Google Chatbot with Dialogflow!

What's next?

Enjoyed this code lab? Have a look into these great labs!