Dialogflow response with output context crashes PHP/Symfony server - symfony

TL;DR
My PHP/Symfony server crashes when Dialogflow sends a response with output context, but works fine when the response does not have any output context.
Why is that so and how can I prevent my server from crashing ?
Some context
I'm working on a old project made by a colleague who left the company a few months ago.
The project uses Dialogflow and a PHP/Symfony server to create a chatbot.
Back in January, the project worked well, but when I tried to test it last week, I discovered our server had been irremediably removed from the host.
I reuploaded and reinstalled the server code but I cannot be 100% sure that the backup code was exactly the same as the hosted code.
Correct behaviour
I send "hey" to the server
The server transmits the message to Dialogflow
Dialogflow determines that the intent is "Welcome"
Dialogflow sends back "Salutations" to the server
I get the response "Salutations"
Faulty behaviour
I send "help" to the server
The server transmits the message to Dialogflow
Dialogflow determines that the intent is "Help"
Dialogflow sends back "[some long text]" to the server
The server crashes and returns a generic error 500
Same goes for the default fallback intent, if I send a request like "blah blah blah".
The difference
The Welcome intent does not provide output context, nor does it reset the context.
The Help intent does provide output context.
The Fallback intent does not provide output context, but does reset the context.
I verified, if I provide output context with the Welcome intent, the server crashes, and if I remove the output context from the Help intent, everything works fine.
The questions
What is going on with this project ? Why is the output context crashing my server ? How can I fix it ?
I can't just remove the output contexts from the intents, of course.
The code
<?php
namespace AppBundle\Controller;
use Ramsey\Uuid\Uuid;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Google\Cloud\Dialogflow\V2\SessionsClient;
use Google\Cloud\Dialogflow\V2\TextInput;
use Google\Cloud\Dialogflow\V2\QueryInput;
class DefaultController extends Controller
{
/**
* #Route("/messenger", name="homepage")
*
*/
public function indexAction(Request $request)
{
return $this->render('#App/messenger.twig', array());
}
/**
* #param Request $request
*
* #Route("/messenger/call/{intent}", options={"expose"=true}, name="call_assistant")
* #throws \Google\ApiCore\ValidationException
* #throws \Google\ApiCore\ApiException
* #throws \Exception
*/
public function callAssistantAction(Request $request, $intent) {
$sessionDialogFlow = $this->get('session')->get('dialogFlow_session');
if ($sessionDialogFlow === null) {
$sessionDialogFlow = Uuid::uuid4()->toString();
$this->get('session')->set('dialogFlow_session', $sessionDialogFlow);
}
$sessionClient = new SessionsClient(array(
'credentials' => realpath($this->getParameter('kernel.root_dir'). "/../web/authentDialogFlow.json")
));
$session = $sessionClient->sessionName("<my session name>", $sessionDialogFlow);
$textInput = new TextInput();
$textInput->setText($intent);
$textInput->setLanguageCode('fr-FR');
$queryInput = new QueryInput();
$queryInput->setText($textInput);
$response = $sessionClient->detectIntent($session, $queryInput); // <- this line is where the crash happens
$queryResult = $response->getQueryResult();
$fulfillmentText = $queryResult->getFulfillmentText();
return new JsonResponse(array("response" => $fulfillmentText));
}
}
The Welcome dialogflow output
{
"queryText": "hey",
"action": "input.welcome",
"parameters": {},
"fulfillmentText": "Salutations !",
"fulfillmentMessages": [
{
"text": {
"text": [
"Salutations !"
]
},
"lang": "fr"
}
],
"intent": {
"id": "<id>",
"displayName": "Default Welcome Intent",
"priority": 500000,
"events": [
"WELCOME"
],
"action": "input.welcome",
"messages": [
{
"text": {
"text": [
"Hi! How are you doing?",
"Hello! How can I help you?",
"Good day! What can I do for you today?",
"Greetings! How can I assist?"
]
},
"lang": "en"
},
{
"text": {
"text": [
"Salut !",
"Bonjour !",
"Salutations !",
"Bienvenue !"
]
},
"lang": "fr"
}
]
},
"intentDetectionConfidence": 1,
"languageCode": "fr",
"slotfillingMetadata": {
"allRequiredParamsPresent": true
},
"id": "<id>",
"sessionId": "<id>",
"timestamp": "2019-07-15T07:41:28.778Z",
"source": "agent",
"webhookStatus": {
"webhookEnabledForAgent": true
},
"agentEnvironmentId": {
"agentId": "<id>",
"cloudProjectId": "<id>"
}
}
The Help dialogflow output
{
"queryText": "aide",
"parameters": {},
"fulfillmentText": "<long text>",
"fulfillmentMessages": [
{
"text": {
"text": [
"<long text>"
]
},
"lang": "fr"
}
],
"intent": {
"id": "<id>",
"displayName": "Help",
"priority": 500000,
"messages": [
{
"text": {
"text": [
"<long text>"
]
},
"lang": "fr"
}
]
},
"intentDetectionConfidence": 1,
"languageCode": "fr",
"slotfillingMetadata": {
"allRequiredParamsPresent": true
},
"id": "<id>",
"sessionId": "<id>",
"timestamp": "2019-07-15T13:05:25.255Z",
"source": "agent",
"webhookStatus": {
"webhookEnabledForAgent": true
},
"agentEnvironmentId": {
"agentId": "<id>",
"cloudProjectId": "<id>"
}
}
Feel free to ask for additional information.

After days of gloom, it turned out my server was missing PHP extension bcmath needed by google/protobuf. I enabled it in my php.ini and everything worked fine.
You can find a bit more information on the Github issue : https://github.com/googleapis/google-cloud-php/issues/2120

Related

Exception in function does not return exceptions on functions in function monitor

The azure function is a .net core class library that will receive the message based on the namespace of the model being sent (in the filter as eventType) as an . All deployments are being done using arm templates, which is where this struggle is originating from. The function and eventgrid are deployed fine, but I don't know what i'm doing wrong with the subscription. If I create the subscription in the portal then the handler receives the message and displays traffic on the monitor. If I create the subscription as below then it appears exactly the same in the portal as the portal created one but nothing shows up in the monitor. Am I missing a resource or connection that still needs to be created? I read about system topics and how they're made implicitly in some instances but can be made explicitly, is that what I'm missing? This would be easier to debug if there was a place to export the template for those subscriptions but I don't see them.
Function handler
[FunctionName("FunctionName")]
public async Task Run([EventGridTrigger]EventGridEvent eventGridEvent)
{
...
}
}
eventgrid creation
{
"type": "Microsoft.EventGrid/topics",
"apiVersion": "2020-06-01",
"name": "[variables('EventGridName')]",
"location": "[resourceGroup().location]"
}
subscription creations
{
"name": "[concat(variables('eventSubscriptions')[copyIndex()].eventGridName, '/Microsoft.EventGrid/', variables('eventSubscriptions')[copyIndex()].name)]",
"type": "Microsoft.EventGrid/topics/providers/eventSubscriptions",
"apiVersion": "2020-01-01-preview",
"location": "[resourceGroup().location]",
"copy": {
"name": "subscriptionCopy",
"count": "[length(variables('eventSubscriptions'))]"
},
"properties": {
"topic": "[concat('/subscriptions/', subscription().subscriptionId,'/resourcegroups/', resourceGroup().name, '/providers/Microsoft.EventGrid/topics/', variables('eventSubscriptions')[copyIndex()].eventGridName)]",
"destination": {
"endpointType": "AzureFunction",
"properties": {
"resourceId": "[concat('/subscriptions/', subscription().subscriptionId,'/resourcegroups/', resourceGroup().name, '/providers/Microsoft.Web/sites/', variables('eventSubscriptions')[copyIndex()].functionApp, '/functions/' , variables('eventSubscriptions')[copyIndex()].functionName)]",
"maxEventsPerBatch": 1,
"preferredBatchSizeInKilobytes": 64
}
},
"filter": {
"includedEventTypes": [
"[variables('eventSubscriptions')[copyIndex()].eventType]"
]
},
"labels": [],
"eventDeliverySchema": "EventGridSchema"
},
"dependsOn": [
]
}

keycloak impossible to get client-roles inside access_token

I'm new with keycloak and following a tutorial over internet, I've configured a new realm "example" with a client "app-backend", related role "admin" (not composed) and realm role "app-admin"(composed with the client role "admin").
I've also created one user and I've assigned the realm role "admin".
All ok at this point but, when I ask for access token with the POST API call to keycloak server(http://localhost:8080/auth/realms/barber-reservation/protocol/openid-connect/token), I've noticed that client roles are not contained inside the "resource_access" object, instead I've found "account" object inside it.
This strange behavior is making fail all authorization verification from my spring boot app.
Following the acess token received:
{
"exp": 1608478284,
"iat": 1608477984,
"jti": "5ce17d4d-e3b3-4207-8010-45c0895a9a6a",
"iss": "http://localhost:8080/auth/exmple/app-backend",
"aud": [
"app-backend"
],
"sub": "d3fcc7df-878e-4363-91d6-f06437de5f90",
"typ": "Bearer",
"azp": "app-frontend",
"session_state": "dad4ab85-850a-4c63-8a26-7b3b6de9f821",
"acr": "1",
"allowed-origins": [
"*"
],
"realm_access": {
"roles": [
"app-admin"
]
},
"resource_access": {
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
},
"app-backend": {
"roles": [
"admin"
]
}
},
"scope": "openid email profile",
"email_verified": true,
"name": "Name Surname",
"preferred_username": "user#email.com",
"locale": "it",
"given_name": "Name",
"family_name": "Surname",
"email": "user#email.com"
}
I was expecting that the client roles section was contained inside the "resource_access" object like this:
"resource_access": {
"app-backend": {
"roles": [
"admin"
]
}
}
Any Ideas on how to correct this strange behaviour?
Thank you.
There is nothing strange here, your client role admin from the client "app-backend" is on the resource_access object:
"resource_access":
{
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
},
"app-backend": {
"roles": [
"admin"
]
}
},
The resource_access is a list of Key Values, i.e., client and their roles.

How can i save the fulfillmentText in dialogflow to firebase?

I am new in Learning Dialogflow, What i am trying is to save the conversation of user and the bot.
i can already save the user response to the bot but i also want to save the bot response to the firebase.
my code is like this
function HandleSaveToDB(agent){
return admin.database().ref('data').push({
bot_response: request.body.queryResult.queryText,
user_response: request.body.fulfillmentText
});
}
the bot_response is saving but the user_response is not saving.
here is the response of the JSON
{
"responseId": "50359194-cadb-44a4-b649-ebd8e4606fea-425db6e2",
"queryResult": {
"queryText": "Hi i am paul i need help",
"parameters": {
"given-name": "Paul",
"text": ""
},
"allRequiredParamsPresent": true,
"fulfillmentText": "Hi Paul how can i help you today?",
"fulfillmentMessages": [
{
"text": {
"text": [
"Hi Paul how can i help you today?"
]
}
}
],
"intent": {
"name": "projects/chatsimulator-rttunh/agent/intents/dbc7dbf8-ca8d-4f7a-86b5-a0e6eab7e0b5",
"displayName": "Greetings"
},
"intentDetectionConfidence": 1,
"diagnosticInfo": {
"webhook_latency_ms": 4992
},
"languageCode": "en"
},
"webhookStatus": {
"code": 4,
"message": "Webhook call failed. Error: DEADLINE_EXCEEDED."
}
}
I'm presuming you're talking about a Fulfillment function being hit here.
The fulfillmentText is actually located in request.queryResult.fulfillmentText, despite what you see as the output from the diagnostic info.
Please see the spec for the fulfillment request and the queryResult property of that request.

Sabre Hotel Content Rest API stopped working

POSTing to https://api.sabre.com/v1.0.0/shop/hotels/content?mode=content yesterday worked fine, but with the same Postman request is failing today.
The fault code is: "Client.InvalidCustomerAppId" (but the Http status code is 200.)
Nothing changed on our end, is it possible that I was using an account that no longer has access to this API?
Full JSON response is:
{
"Fault": {
"faultcode": "{http://schemas.xmlsoap.org/soap/envelope/}Client.InvalidCustomerAppId",
"faultstring": "Field CustomerAppId is invalid",
"detail": {
"StackTrace": [
"com.sabre.universalservices.base.exception.ApplicationException: errors.xml.USG_INVALID_CUSTOMER_APP_ID"
]
}
},
"Links": [
{
"rel": "self",
"href": "https://api.sabre.com/v1.0.0/shop/hotels/content?mode=content"
},
{
"rel": "linkTemplate",
"href": "https://api.sabre.com/<version>/shop/hotels/content?mode=<mode>"
}
]
}

How to map a user to a domain other than Federated in OpenStack federation?

I am trying to understand direct mapping on OpenStack. I want to map a user to a domain other than Federated domain. But I always get user mapped to Federated domain. Here follows the link for direct mapping that I am using:
https://specs.openstack.org/openstack/keystone-specs/specs/kilo/federated-direct-user-mapping.html
Here follows the rule for mapping that I am using:
[
{
"local": [
{
"user": {
"name": "{0}",
"domain": {"name": "Default"}
}
},
{
"group": {
"id": "GROUP_ID"
}
}
],
"remote": [
{
"type": "HTTP_OIDC_SUB"
}
]
}
]
I have configured OpenID connect Idp for federation.
Could someone help me how I can do direct mapping to map a federated user to a domain other than Federated ?
the only way I've been able to get it to not be in the 'Federate' domain, is to force the user to be of type local, but then they need to exist in the backend (SQL/LDAP).
[
{
"local": [
{
"user": {
"name": "{0}",
"type": "local",
"domain": {"name": "Default"}
}
},
{
"group": {
"id": "GROUP_ID"
}
}
],
"remote": [
{
"type": "HTTP_OIDC_SUB"
}
]
}
]
The following bit of code in keystone is the culprit for doing this:
if user_type is None:
user_type = user['type'] = UserType.EPHEMERAL
if user_type == UserType.EPHEMERAL:
user['domain'] = {
'id': CONF.federation.federated_domain_name
}
It Basically overrides the domain to a pre-configured domain if your user doesn't have a type, or is ephemeral.

Resources