I created a chatbot which informs the user about the members of my (extended) family and about where they are living. I have created a small database with MySQL which has these data stored and I fetch them with a PHP script whenever this is appropriate depending on the interaction of the user with the chatbot.
My chatbot contains two intents additionally to the Default Fallback Intent
and to the Default Welcome Intent
:
Names
Location_context
The first intent (Names
) is trained by phrases such as 'Who is John Smith?' and has an output context (called context
with duration of 10 questions). A possible answer to this question is 'John is my uncle.'. The second intent (Location_context
) is trained by phrases such as 'Where is he living?' and has an input context (from Names
). A possible answer to this question is 'John is living in New York.'
The Names
intent contains two parameters:
- parameter names: given-name, last-name.
- entities: @sys.given-name, @sys.last-name.
- value: $given-name, $last-name.
These two parameters represent the full name given by the user. The Location_context
intent does not contain any parameters.
The PHP script is the following:
<?php
$dbServername = '******************';
$dbUsername = '******************';
$dbPassword = '******************';
$dbName = '******************';
$conn = mysqli_connect($dbServername, $dbUsername, $dbPassword, $dbName);
// error_reporting(E_ALL);
// ini_set('display_errors', 'on');
header('Content-Type: application/json');
$method = $_SERVER['REQUEST_METHOD'];
if($method == 'POST'){
$requestBody = file_get_contents('php://input');
$json = json_decode($requestBody);
$action = $json->result->action;
$first_name = $json->result->contexts[0]->parameters->{'given-name'};
$last_name = $json->result->contexts[0]->parameters->{'last-name'};
$lifespan = $json->result->contexts[0]->lifespan;
$sql = "SELECT * FROM family WHERE name LIKE '%$first_name%$last_name%';";
$result = mysqli_query($conn, $sql);
$resultCheck = mysqli_num_rows($result);
if ($resultCheck > 0) {
while ($row = mysqli_fetch_assoc($result)) {
$person = $row;
}
switch ($action) {
case 'Name':
$speech= "$first_name is my" . $person["name"] . ".";
break;
case 'Location':
$speech = "$first_name is living in {$person["location"]}.";
break;
default:
$speech = "Please ask me something more relevant to my family";
break;
}
}
else {
$speech = "Sorry, $first_name $last_name is not a member of my family.";
}
$response = new \stdClass();
$response->speech = $speech;
$response->displayText = $speech;
$response->source = "agent";
echo json_encode($response);
}
else
{
echo "Method not allowed";
}
?>
In Dialogflow, after asking e.g. "Who is John Smith?" and getting the correct answer "John is my uncle." then I am asking "Where is he living?" and I am getting the correct answer "John is living in New York.". The json response from Dialogflow for the second question is:
{
"id": "*****************************",
"timestamp": "2018-04-04T08:26:39.993Z",
"lang": "en",
"result": {
"source": "agent",
"resolvedQuery": "Where is he living"
"action": "Location",
"actionIncomplete": false,
"parameters": {},
"contexts": [
{
"name": "context",
"parameters": {
"given-name.original": "John",
"last-name.original": "Smith",
"given-name": "John",
"last-name": "Smith"
},
"lifespan": 9
}
],
"metadata": {
"intentId": "*****************************",
"webhookUsed": "true",
"webhookForSlotFillingUsed": "false",
"webhookResponseTime": 93,
"intentName": "Location_context"
},
"fulfillment": {
"speech": "John is living in New York.”,
"displayText": "John is living in New York.",
"messages": [
{
"type": 0,
"speech": "John is living in New York."
}
]
},
"score": 1
},
"status": {
"code": 200,
"errorType": "success",
"webhookTimedOut": false
},
"sessionId": "*****************************"
}
However, when I enter exactly the same questions (after entering Talk to my test app
) in Google assistant, I am getting the same answer at the first question but I am getting "is living in Los Angeles." for the second question. Notice two things in this answer. Firstly, the variable $first_name
does not have any value (because it is not set) and that the location 'Los Angeles' is the location of the family member which is last in the database. Therefore this location is returned because $first_name
and $last_name
have no value assigned (as they are not set) in the mysql query and for some reason the location of the last person of the database is returned.
It is quite frustrating that I cannot inspect the json response of Google Assistant as I can easily do it in Dialogflow. However, after experimenting a bit I found out that in Google Assistant $lifespan
is always 0 (both in the first and the second question) and that $first_name
and $last_name
are not set at all in the json response of the second question even though in Dialoglow they are set and they contain the full name as it shown above in the json response I posted. Also Google Assistant returns actions_capability_screen_output
for $json->result->contexts[0]->name
in both questions while obviously in Dialogflow $json->result->contexts[0]->name
is context
(the name of the context).
Therefore, the contexts
branch of the json response in the second question in Google Assistant seems to be like this:
"contexts": [
{
"name": "actions_capability_screen_output",
"parameters": {},
"lifespan": 0
}
]
On the other hand, as I showed above, the contexts
branch of the json response in the second question in DIalogflow is:
"contexts": [
{
"name": "context",
"parameters": {
"given-name.original": "John",
"last-name.original": "Smith",
"given-name": "John",
"last-name": "Smith"
},
"lifespan": 9
}
]
Why Google Assistant does not recognise context
and it does not process the same json response as shown by Dialoglow?
How can I inspect the entire json response from Google Assistant as I do it in Dialogflow?