首页 > 解决方案 > 如何使用 dialoglow 创建个性化回复?

问题描述

我正在尝试构建一个带有对话框流的聊天机器人,它能够为用户提供书籍建议。但我真的不知道如何在 python 文件中构建响应。我的意思是,我希望如果意图是“搜索书”,那么它将根据用户所说的性别发送几本书。实际上,我的 python 文件在那里:

# -*- 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()

对于 Google 图书 API,我发现了这个,它正在工作: https ://github.com/hoffmann/googlebooks

我已经创建了一个名为“gender”的实体和一个名为“search-book”的意图

标签: python-3.xactionwebhooksdialogflow-esgoogle-books

解决方案


你需要做的是你需要为你的意图实现一个webhook(一个 web 服务)。

在此处将 url 设置为您的 webhook

在此处输入图像描述

然后转到您的意图并为该意图启用 webhook

在此处输入图像描述

因此,当有人查询您的意图时,您的 webhook 将收到一个带有 josn body 的 post 请求

{
  "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": {}
}

你可以得到意图名称

body.queryResult.intent.displayName

你也可以得到参数

body.queryResult.parameters

因为现在你有了你需要的参数,你可以调用你的 googlebooks api 并将结果发送回 google dialogflow

响应json应该是这样的

{
  "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"
    }
  }
}

我用 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";
 }

在 getbookDetails 函数中,您可以调用 api 获取书籍并格式化字符串并返回字符串。我们应该同样适用于 python。只有语法会有所不同。


推荐阅读