iansltx/dialogflow-bridge

一组中间件和辅助工具,用于响应 Dialogflow 网钩

0.3 2017-11-13 17:51 UTC

This package is auto-updated.

Last update: 2024-09-06 17:55:40 UTC


README

中间件和辅助对象,用于响应 Dialogflow 网钩。

需求 + 安装

为了充分利用这个库,你需要

  1. 一个兼容 PSR-11(以前称为 Container Interop)的容器来拉取依赖项。
  2. 一个使用双遍历中间件(例如 Slim 3)或建议的 PSR-15 中间件(例如 Zend Expressive 2.0+),使用 PSR-7 请求和响应来使用中间件组件的框架。

要安装,请使用 Composer

composer require iansltx/dialogflow-bridge

入门

将此库集成到支持(微)框架中作为路由中间件是最简单的方法。例如,使用 Slim 3

<?php

use iansltx\DialogflowBridge\{Middleware, Router, Question, Answer};

// require Composer autoloader here

$app = new Slim\App();
$app->post('/hook', new Middleware\DoublePass(Router::buildFromClosureArray([
    'hello' => function(Question $question, Answer $answer) : Answer {
        return $answer->withSpeechAndText("Hello {$question->getParam('name', 'world')}!");
    }
])));
$app->run();

要查看您的应用程序的实际运行情况,请将 Dialogflow 的网钩配置指向您托管应用程序的地方的 /hook,创建一个带有(或没有)name 参数的意图,在该意图中将操作名称设置为 hello,勾选使用 Web Hook 进行满足的框,然后调用您的新意图。

现在,让我们分解刚刚发生的事情

  1. Dialogflow 调用我们的网钩,Slim 将其路由到 DoublePass 中间件。
  2. 该中间件将请求转交给 Router,它将 QuestionAnswer 类进行打包。
  3. Router 发现 Question 的操作为 hello,这与它传递给它的处理程序之一匹配,因此它调用了处理程序,返回了一个 Answer
  4. RouterAnswer 返回给中间件,中间件使用适当的 JSON 有效载荷更新了 HTTP Response

您可以在本文件的稍后部分了解有关这些组件的更多信息。

添加回退

此库包含一个内置的、尽管是通用的、用于当传入的网钩请求中的操作与您的路由映射中的任何内容不匹配时的处理程序。函数签名与正常操作处理程序相同,任何可调用的(具有 __invoke() 的类、闭包等)都可以在这里使用。只需在创建 Router 时将可调用的作为附加参数传递即可。调整前面的示例

<?php

use iansltx\DialogflowBridge\{Middleware, Router, Question, Answer};

// require Composer autoloader here

$app = new Slim\App();
$app->post('/hook', new Middleware\DoublePass(Router::buildFromClosureArray([
    'hello' => function(Question $question, Answer $answer) : Answer {
        return $answer->withSpeechAndText("Hello {$question->getParam('name', 'world')}!");
    }
], function (Question $question, Answer $answer) : Answer {
    return $answer->withSpeechAndText("Sorry, I'm not sure what to do here.");
})));
$app->run();

随着您的应用程序变得更加复杂,您将想开始...

管理处理程序依赖项

一个匿名函数数组是开始处理网钩请求的快速方法,但随着您项目的增长,您可能希望将您的处理程序放入主应用程序 DI 容器中。在这种情况下,您将想要使用 Router::build() 而不是 Router::buildFromClosureArray()build() 接受三个参数

  1. 实现 PSR-11 ContainerInterface 的对象(例如 Slim 3 的容器)
  2. 操作名称(作为键)和容器键(作为值)之间的映射数组。这提供了一个白名单,以便传入的请求不会从容器中拉取随机服务,并允许您将多个操作名称映射到单个依赖项(如果愿意的话)。
  3. 可选的回退可调用。

在前面示例的基础上,假设我们已将 "hello" 处理程序移动到容器中作为 "helloHandler",我们最终会得到

<?php

use iansltx\DialogflowBridge\{Middleware, Router, Question, Answer};

// require Composer autoloader here

$app = new Slim\App();
$app->post('/hook', new Middleware\DoublePass(Router::build($app->getContainer(), [
    'hello' => 'helloHandler'
], function (Question $question, Answer $answer) : Answer {
    return $answer->withSpeechAndText("Sorry, I'm not sure what to do here.");
})));
$app->run();

当您切换到基于类的操作处理程序时,您可以(但不一定需要)实现 HandlerInterface 以确保您的处理程序方法具有正确的签名。

更多关于中间件的信息

可以像中间件一样使用DoublePass类,而不是作为Slim路由的调用者,根据需要;它的第三个参数未使用,也没有进行类型提示,以便于这样做。

如果您更愿意使用依赖于提议的PSR-15中间件规范的框架,请设置一个PSR15类的实例。在这种情况下,您需要一个Router实例(就像DoublePass一样)和一个可调用对象,该对象接受一个可JSON序列化的参数,并返回一个PSR-7 ResponseInterface,其中参数被JSON编码,并包含正确的Content-Type头部。如果您使用Zend Diactoros,构建中间件看起来像

$middleware = new Middleware\PSR15($router, function($data) {
    return new \Zend\Diactoros\JsonResponse($data);
});

对象

这个库提供了一些不可变对象,使与Dialogflow Web钩子交互变得更容易。

问题

问题包装了Dialogflow的Web钩子请求JSON,允许更干净地访问参数、上下文和其他Web钩子请求的方面。通常您将由路由器提供问题,但您也可以独立构建一个问题

/** @var \Psr\Http\Message\ServerRequestInterface $request */
$question = Question::fromRequest($request); // from a PSR-7 request

/** @var array $data */
$question = new Question($data); // from an array, e.g. by JSON-decoding the web hook request body

查看Question类中的方法文档块以获取更多信息。

答案

可以将答案直接传递给json_decode()以生成Dialogflow Web钩子调用所需的响应体。通常这会通过在问题上调用getBaseAnswer()来生成。这样做会通知答案当前设置了哪些上下文,如果需要,它们可以被删除。这是路由器处理问题和答案的方式,但您也可以直接调用new Answer()

查看Answer类中的方法文档块以获取更多信息。