8000 Dialogflow middleware using api v2 by eclips16 · Pull Request #1010 · botman/botman · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Dialogflow middleware using api v2 #1010

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: 2.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
"mpociot/pipeline": "^1.0",
"react/socket": "~1.0",
"spatie/macroable": "^1.0",
"psr/container": "^1.0"
"psr/container": "^1.0",
"google/cloud-dialogflow": "^0.17.2"
},
"require-dev": {
"codeigniter/framework": "~3.0",
Expand Down
138 changes: 138 additions & 0 deletions src/Middleware/DialogFlowV2.php
10000
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<?php


namespace BotMan\BotMan\Middleware;

use BotMan\BotMan\BotMan;
use BotMan\BotMan\Interfaces\MiddlewareInterface;
use BotMan\BotMan\Messages\Incoming\IncomingMessage;
use BotMan\BotMan\Middleware\DialogFlowV2\Client;
use Google\ApiCore\ApiException;

class DialogFlowV2 implements MiddlewareInterface
{
/**
* @var bool
*/
private $listenForAction;
/**
* @var Client
*/
private $client;

/**
* constructor.
* @param string $lang language
* @param Client $client
*/
public function __construct(Client $client)
{
$this->client = $client;
}

/**
* Create a new Dialogflow middleware instance.
* @return DialogflowV2
*/
public static function create($lang = 'en')
{
$client = new Client($lang);
return new static($client);
}

/**
* Restrict the middleware to only listen for dialogflow actions.
* @param bool $listen
* @return $this
*/
public function listenForAction($listen = true)
{
$this->listenForAction = $listen;

return $this;
}

/**
* Handle a captured message.
*
* @param IncomingMessage $message
* @param BotMan $bot
* @param $next
*
* @return mixed
*/
public function captured(IncomingMessage $message, $next, BotMan $bot)
{
return $next($message);
}

/**
* Handle an incoming message.
*
* @param IncomingMessage $message
* @param BotMan $bot
* @param $next
*
* @return mixed
* @throws ApiException
*/
public function received(IncomingMessage $message, $next, BotMan $bot)
{
$response = $this->client->getResponse($message);

$message->addExtras('apiReply', $response->getReply());
$message->addExtras('apiAction', $response->getAction());
$message->addExtras('apiActionIncomplete', $response->isComplete());
$message->addExtras('apiIntent', $response->getIntent());
$message->addExtras('apiParameters', $response->getParameters());
$message->addExtras('apiContexts', $response->getContexts());

return $next($message);
}

/**
* @param IncomingMessage $message
* @param $pattern
* @param bool $regexMatched Indicator if the regular expression was matched too
* @return bool
*/
public function matching(IncomingMessage $message, $pattern, $regexMatched)
{
if ($this->listenForAction) {
$pattern = '/^' . $pattern . '$/i';

return (bool)preg_match($pattern, $message->getExtras()['apiAction']);
}

return true;
}

/**
* Handle a message that was successfully heard, but not processed yet.
*
* @param IncomingMessage $message
* @param BotMan $bot
* @param $next
*
* @return mixed
*/
public function heard(IncomingMessage $message, $next, BotMan $bot)
{
return $next($message);
}

/**
* Handle an outgoing message payload before/after it
* hits the message service.
*
* @param mixed $payload
* @param BotMan $bot
* @param $next
*
* @return mixed
*/
public function sending($payload, $next, BotMan $bot)
{
return $next($payload);
}
}
153 changes: 153 additions & 0 deletions src/Middleware/DialogFlowV2/Client.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
<?php


namespace BotMan\BotMan\Middleware\DialogFlowV2;


use BotMan\BotMan\Messages\Incoming\IncomingMessage;
use BotMan\BotMan\Middleware\DialogFlowV2\Exception\DialogFlowV2NoIntentException;
use BotMan\BotMan\Middleware\DialogFlowV2\Exception\DialogFlowV2NoResultException;
use Google\ApiCore\ApiException;
use Google\Cloud\Dialogflow\V2\DetectIntentResponse;
use Google\Cloud\Dialogflow\V2\QueryInput;
use Google\Cloud\Dialogflow\V2\QueryResult;
use Google\Cloud\Dialogflow\V2\SessionsClient;
use Google\Cloud\Dialogflow\V2\TextInput;

class Client
{

/**
* @var SessionsClient
*/
private $sessionsClient;
/**
* @var string
*/
private $lang;

/**
* Client constructor.
* @param string $lang
* @param SessionsClient|null $sessionClient
*/
public function __construct(string $lang, SessionsClient $sessionClient = null)
{
$this->lang = $lang;
$this->sessionsClient = $sessionClient ?? new SessionsClient();
}


/**
* @param IncomingMessage $message
* @return Response
* @throws ApiException
*/
public function getResponse(IncomingMessage $message): Response
{
$queryInput = $this->queryInput($message->getText(), $this->lang);

$intentResponse = $this->getIntentResponse(md5($message->getConversationIdentifier()), $queryInput);

$queryResult = $intentResponse->getQueryResult();

if(null === $queryResult){
throw new DialogFlowV2NoResultException('No result from DialogFlow api.');
}

if(null === $queryResult->getIntent()){
throw new DialogFlowV2NoIntentException('No intent detected.');
}

$response = new Response();
$response
->setIntent($queryResult->getIntent()->getDisplayName())
->setParameters($this->getParameters($queryResult))
->setContexts($this->getContexts($queryResult))
->setAction($queryResult->getAction())
->setReply($queryResult->getFulfillmentText())
->setIsComplete(!$queryResult->getAllRequiredParamsPresent())
;

return $response;
}

/**
* @param $text
* @param string $languageCode
* @return QueryInput
*/
private function queryInput($text, string $languageCode): QueryInput
{
// create text input
$textInput = new TextInput();
$textInput->setText($text);
$textInput->setLanguageCode($languageCode);

// create query input
$queryInput = new QueryInput();
$queryInput->setText($textInput);
return $queryInput;
}

/**
* @param $sessionId
* @param $queryInput
* @return DetectIntentResponse
* @throws ApiException
*/
private function getIntentResponse($sessionId, $queryInput): DetectIntentResponse
{
$sessionName = $this->sessionsClient::sessionName(getenv('GOOGLE_CLOUD_PROJECT'),
$sessionId ?: uniqid('', true));

// get response and relevant info
$response = $this->sessionsClient->detectIntent($sessionName, $queryInput);

$this->sessionsClient->close();

return $response;
}

/**
* @param QueryResult $queryResult
* @return array
*/
private function getParameters(QueryResult $queryResult): array
{
$parameters = [];
$queryParameters = $queryResult->getParameters();
if (null !== $queryParameters) {
foreach ($queryParameters->getFields() as $name => $field) {
$parameters[$name] = $field->getStringValue();
}
}

return $parameters;
}

/**
* @param QueryResult|null $queryResult
* @return array
*/
private function getContexts(QueryResult $queryResult): array
{
$contexts = [];
foreach ($queryResult->getOutputContexts() as $context) {
$cparams = [];
$parameters = $context->getParameters();
if ($parameters !== null) {
foreach ($parameters->getFields() as $name => $field) {
$cparams[$name] = $field->getStringValue();
}
}

$contexts[] = [
'name' => substr(strrchr($context->getName(), '/'), 1),
'parameters' => $cparams,
'lifespan' => $context->getLifespanCount(),
];
}
return $contexts;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php


namespace BotMan\BotMan\Middleware\DialogFlowV2\Exception;


class DialogFlowV2NoIntentException extends \RuntimeException
{

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php


namespace BotMan\BotMan\Middleware\DialogFlowV2\Exception;


class DialogFlowV2NoResultException extends \RuntimeException
{

}
Loading
0