Chapter 10: How to build a Google Home App with DialogFlow | Fulfillment via Cloud Datastore

Moses Sam Paul
Aug 16, 2018 · 6 min read

In this chapter we are gonna see how to connect google cloud’s datastore to have a set of quotes with different categories and pull them based on the user inputs.



Let’s understand what datastore is and how is it different first.

What’s Google Cloud Datastore ?

Google Cloud Datastore is a NoSQL document database built for automatic scaling, high performance, and ease of application development.

What’s a NoSQL database?

A NoSQL (originally referring to “non SQL” or “non relational”) database provides a mechanism for storage and retrieval of data that is modeled in means other than the tabular relations used in relational databases.

Comparison with traditional databases

While the Cloud Datastore interface has many of the same features as traditional databases, as a NoSQL database it differs from them in the way it describes relationships between data objects. Here’s a high-level comparison of Cloud Datastore and relational database concepts:

Unlike rows in a relational database table, Cloud Datastore entities of the same kind can have different properties, and different entities can have properties with the same name but different value types. These unique characteristics imply a different way of designing and managing data to take advantage of the ability to scale automatically.

Enough with the theory, let’s begin.


Let’s setup our datastore now

Step 1: Login to your google cloud console:

Step 2: Select your project and Click on Datastore.

Step 3: Create Entity

Remember entity is just an item (row). Kind (QuoteTable) is the table name. Leave the name space as default.

Quote, QuoteID & QuoteType are the properties [columns] . Make sure that the QuoteType and QuoteId are indexed as we’ll be using these properties for filtering based on the user input.

Now that a basic data store is setup in the next chapter we’ll see how to pull data from this from our cloud function.


Let’s go back to our inline editor.

Till now we have edited only the index.js file, but this cloud datastore is a dependecy that has to be added to the package.json file.

"@google-cloud/datastore": "1.1.0"

Back to index.js file.

Am gonna make the code as simple as possible, don’t expect coding standards :)

  1. instantiate the object
const Datastore = require('@google-cloud/datastore');
// Instantiate a datastore client
const datastore = Datastore();

2. Define the queries

const query1 = datastore.createQuery('QuoteTable').filter('QuoteType', '=', 'Motivational');
const query2 = datastore.createQuery('QuoteTable').filter('QuoteType', '=', 'Friendship');
const query3 = datastore.createQuery('QuoteTable').filter('QuoteType', '=', "Romantic");

3. Run the query, capture the return JSON file and print a specific Quote.

app.intent(LOOKING_FOR_QUOTE_INTENT, (conv) => {
const quote_type = conv.parameters[QUOTE_TYPE_ENTITY].toLowerCase();
if (quote_type == "motivational") {
return datastore.runQuery(query1).then(results => {
conv.ask(results[0][1].Quote);
});
} else if (quote_type == "friendship") {
return datastore.runQuery(query2).then(results => {
conv.ask(results[0][1].Quote);
});
} else if (quote_type == "romantic") {
return datastore.runQuery(query3).then(results => {
conv.ask(results[0][0].Quote);
});
} else {
conv.ask("get off your ass and work instead of talking to me");
}
});

Let us take one piece of this and understand.

if (quote_type == "friendship") {
return datastore.runQuery(query2).then(results => {
conv.ask(results[0][1].Quote);
});

The results is a JSON object that has two parts. The first part hold the filtered data and the second part holds some info. If we print these values and see the firebase log, we’ll find the below.

so we take the first object and within that am hard-coding the second quote to be shown all the time, this is shitty programming but you can always loop and show a random quote.

4. Final code within index.js

// See https://github.com/dialogflow/dialogflow-fulfillment-nodejs
// for Dialogflow fulfillment library docs, samples, and to report issues
'use strict';

const functions = require('firebase-functions');
const {dialogflow} = require ('actions-on-google');
const Datastore = require('@google-cloud/datastore');
// Instantiate a datastore client
const datastore = Datastore();
const WELCOME_INTENT = 'Default Welcome Intent';
const FALLBACK_INTENT = 'Default Fallback Intent';
const LOOKING_FOR_QUOTE_INTENT = 'LookingForQuote';
const QUOTE_TYPE_ENTITY = 'QuoteType';
const app = dialogflow();app.intent(WELCOME_INTENT, (conv) => {
conv.ask("welcome to Dr.Motivation! Ask for a quote about friendship or romance or motivation");
});
app.intent(FALLBACK_INTENT, (conv) => {
conv.ask("Stop mumbling & speak up");
});
const query1 = datastore.createQuery('QuoteTable').filter('QuoteType', '=', 'Motivational');
const query2 = datastore.createQuery('QuoteTable').filter('QuoteType', '=', 'Friendship');
const query3 = datastore.createQuery('QuoteTable').filter('QuoteType', '=', "Romantic");
app.intent(LOOKING_FOR_QUOTE_INTENT, (conv) => {
const quote_type = conv.parameters[QUOTE_TYPE_ENTITY].toLowerCase();
if (quote_type == "motivational") {
return datastore.runQuery(query1).then(results => {
conv.ask(results[0][1].Quote);
});
} else if (quote_type == "friendship") {
return datastore.runQuery(query2).then(results => {
conv.ask(results[0][1].Quote);
});
} else if (quote_type == "romantic") {
return datastore.runQuery(query3).then(results => {
conv.ask(results[0][0].Quote);
});
} else {
conv.ask("get off your ass and work instead of talking to me");
}
});
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);

5. Deploy & Test

Cool, so what did we do here?

Instead of hard-coding quotes within the code, we are now pulling quotes from the google cloud data store using the Fulfillment’s inline editor.

Well, this isn’t enough, is it ? When we are writing complex functions we might need better debugging and better control over the code and the packages we are leveraging. So it’s better to set up a development environment and start tinkering our code over there

In the next chapter, we’ll see how to use the firebase command line interface and a JS editor to move the development to our local machine and deploy it as a cloud function and use webhook to do the same.



This story is published in The Startup, Medium’s largest entrepreneurship publication followed by 358,974+ people.

Subscribe to receive our top stories here.

The Startup

Medium's largest active publication, followed by +477K people. Follow to join our community.

Moses Sam Paul

Written by

Bachelor: Information Technology; Master: Public Policy; Now: Head of Growth at www.heptagon.in; Building #PeopleChain -The Frictionless Skill Movement Platform

The Startup

Medium's largest active publication, followed by +477K people. Follow to join our community.