I am trying to build a chatbot with dialogflow which is able to advice books for users. But I really don't find how to build the responses in a python file. I mean, I want that if the intent is "search-book", then it will send few books depending on the gender the user said. Actually, my python file is there :
# -*- coding:utf-8 -*-
# !/usr/bin/env python
# Copyright 2017 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import print_function
import os
import sys
import json
import yaml
try:
import apiai
except ImportError:
sys.path.append(
os.path.join(
os.path.dirname(os.path.realpath(__file__)),
os.pardir,
os.pardir
)
)
import apiai
CLIENT_ACCESS_TOKEN = '197ef97149d449a6962ba5bd5e488607'
def yaml_loader(filepath):
"""Loads a yaml file"""
with open(filepath, 'r') as file:
data = yaml.load(file)
return data
def yaml_dump(filepath, data):
"""Dumps data to a yaml file"""
with open(filepath, "w") as file:
yaml.dump(data, file)
def main():
ai = apiai.ApiAI(CLIENT_ACCESS_TOKEN)
filepath = "proxy.yaml"
data = yaml_loader(filepath)
proxy = data.get('proxy')
for proxy_protocol, proxy_host in proxy.items():
os.environ["" + proxy_protocol] = "" + proxy_host
while True:
print(u"> ", end=u"")
user_message = input()
if user_message == u"exit":
break
request = ai.text_request()
request.query = user_message
response = json.loads(request.getresponse().read())
result = response['result']
action = result.get('action')
actionIncomplete = result.get('actionIncomplete', False)
print(u"< %s" % response['result']['fulfillment']['speech'])
if action is not None:
if action == "search-book":
parameters = result['parameters']
text = parameters.get('text')
Gender = parameters.get('Gender')
print (
'text: %s, Gender: %s' %
(
text if text else "null",
Gender if Gender else "null",
)
)
if __name__ == '__main__':
main()
For Google books API I found this, and it is working: https://github.com/hoffmann/googlebooks
I already have created an Entity called "gender" and an intent named "search-book"
what you have to do is you need to implement a webhook (a web service) for your intent.
set the url to your webhook here
then go to your intent and enable the webhook for the intent
so when some one query for your intent your webhook will get a post request with bellow josn body
{
"responseId": "ea3d77e8-ae27-41a4-9e1d-174bd461b68c",
"session": "projects/your-agents-project-id/agent/sessions/88d13aa8-2999-4f71-b233-39cbf3a824a0",
"queryResult": {
"queryText": "user's original query to your agent",
"parameters": {
"param": "param value"
},
"allRequiredParamsPresent": true,
"fulfillmentText": "Text defined in Dialogflow's console for the intent that was matched",
"fulfillmentMessages": [
{
"text": {
"text": [
"Text defined in Dialogflow's console for the intent that was matched"
]
}
}
],
"outputContexts": [
{
"name": "projects/your-agents-project-id/agent/sessions/88d13aa8-2999-4f71-b233-39cbf3a824a0/contexts/generic",
"lifespanCount": 5,
"parameters": {
"param": "param value"
}
}
],
"intent": {
"name": "projects/your-agents-project-id/agent/intents/29bcd7f8-f717-4261-a8fd-2d3e451b8af8",
"displayName": "Matched Intent Name"
},
"intentDetectionConfidence": 1,
"diagnosticInfo": {},
"languageCode": "en"
},
"originalDetectIntentRequest": {}
}
you can get the intent name
body.queryResult.intent.displayName
also you can get the parameters
body.queryResult.parameters
since now you have the parameters you need, you can call to your googlebooks api and send the result back to the google dialogflow
the responce json should be something like this
{
"fulfillmentText": "This is a text response",
"fulfillmentMessages": [
{
"card": {
"title": "card title",
"subtitle": "card text",
"imageUri": "https://assistant.google.com/static/images/molecule/Molecule-Formation-stop.png",
"buttons": [
{
"text": "button text",
"postback": "https://assistant.google.com/"
}
]
}
}
],
"source": "example.com",
"payload": {
"google": {
"expectUserResponse": true,
"richResponse": {
"items": [
{
"simpleResponse": {
"textToSpeech": "this is a simple response"
}
}
]
}
},
"facebook": {
"text": "Hello, Facebook!"
},
"slack": {
"text": "This is a text response for Slack."
}
},
"outputContexts": [
{
"name": "projects/${PROJECT_ID}/agent/sessions/${SESSION_ID}/contexts/context name",
"lifespanCount": 5,
"parameters": {
"param": "param value"
}
}
],
"followupEventInput": {
"name": "event name",
"languageCode": "en-US",
"parameters": {
"param": "param value"
}
}
}
some thing i have done with node js
'use strict';
const http = require('http');
exports.bookWebhook = (req, res) => {
if (req.body.queryResult.intent.displayName == "search-book") {
res.json({
'fulfillmentText': getbookDetails(req.body.queryResult.parameters.gender)
});
}
};
function getbookDetails(gender) {
//do you api search for book here
return "heard this book is gooooood";
}
in getbookDetails function you can call to you api get the book and format the string and return the string.. same should be applied to python as we. only the syntax will be different.