Get Google Assistant Action to respond to "Quit" or "Cancel" - actions-on-google

I've tried to follow the documentation about App Exit handling, but it doesn't seem to be working correctly. (See the screen shot of my Intent below).
When I do it this way, it seems to resort to my Default Fallback Intent, although it does indicate that the resolvedQuery is actions_intent_CANCEL, which should be correct. (See the JSON body below.)
Am I doing something wrong, or is the documentation wrong?
Intent trying to handle it:
JSON Body:
{
"originalRequest": {
"source": "google",
"version": "2",
"data": {
"isInSandbox": true,
"surface": {
"capabilities": [
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.SCREEN_OUTPUT"
}
]
},
"inputs": [
{
"rawInputs": [
{}
],
"intent": "actions.intent.CANCEL"
}
],
"user": {
"locale": "en-US",
"userId": "AETml1QP6omTPEXBfrOBdvNlwHxY"
},
"conversation": {
"conversationId": "1509314271837",
"type": "ACTIVE",
"conversationToken": "[]"
},
"availableSurfaces": [
{
"capabilities": [
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.SCREEN_OUTPUT"
}
]
}
]
}
},
"id": "bbd363aa-f555-4543-a748-294751194fa9",
"timestamp": "2017-10-29T21:58:00.691Z",
"lang": "en-us",
"result": {
"source": "agent",
"resolvedQuery": "actions_intent_CANCEL",
"speech": "",
"action": "input.unknown",
"actionIncomplete": false,
"parameters": {},
"contexts": [
{
"name": "actions_intent_cancel",
"parameters": {},
"lifespan": 0
},
{
"name": "actions_capability_screen_output",
"parameters": {},
"lifespan": 0
},
{
"name": "actions_capability_audio_output",
"parameters": {},
"lifespan": 0
}
],
"metadata": {
"intentId": "25f6e14b-a92c-479b-8943-76c4b6914579",
"webhookUsed": "true",
"webhookForSlotFillingUsed": "false",
"nluResponseTime": 2,
"intentName": "Default Fallback Intent"
},
"fulfillment": {
"speech": "I'm sorry. I didn't quite grasp what you just said.",
"messages": [
{
"type": 0,
"id": "535c3b80-f13d-4b61-8c1d-bb58fa3f5e44",
"speech": "I'm a bit confused by that last part."
}
]
},
"score": 1
},
"status": {
"code": 200,
"errorType": "success"
},
"sessionId": "1509314271837"
}

In addition to the steps in the documentation, I found that I had to tell the simulator to update to the most recent version!
Here is my video outlining the steps I took.
https://www.youtube.com/watch?v=ZvZDokjhUIY

Although this isn't what the documentation suggests, I've found a workaround that seems to be correct.
Since there doesn't seem to be any spoken input registered, it looks like it would make sense for a Fallback Intent. Since Fallback Intents other than the default one require a Context, and not just an Event, and it looks like the actions_intent_cancel context is created, it seems reasonable to use it.
A Fallback Intent for this might look something like this:

Related

Pass callback_id without attachments in Slack

I'm using Slack Api to send message.
So, I have this block message:
{
"blocks": [
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "Do you have access ?"
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"emoji": true,
"text": "Yes"
},
"style": "primary",
"value": "click_me_123"
},
{
"type": "button",
"text": {
"type": "plain_text",
"emoji": true,
"text": "Skip"
},
"style": "danger",
"value": "click_me_123"
}
]
}
]
}
As you see, this is block message and it have no any attachments. So, it doesn't send any callback_id when click button Yes or No. But I need send callback_id when click button Yes or No. How can do that?
Or another hack. Anyway to remove border left of attachments?
Thanks.
Am assuming you are looking to have a way to let your code parse the choices when the button is pressed. You need to assign the unique value that you can parse and determine the choice. Something like
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"emoji": true,
"text": "Yes"
},
"style": "primary",
"value": "yes"
},
{
"type": "button",
"text": {
"type": "plain_text",
"emoji": true,
"text": "Skip"
},
"style": "danger",
"value": "skip"
}
]
}

How to tell Google to not send EXECUTE intents for sensor?

EDIT The bug in the validator was fixed however there are still on/off buttons in the Home App which trigger EXECUTE events
I have a Switch with a OnOff trait and want to tell Google to not send any EXECUTE intents. According to the device attributes I can set queryOnlyOnOff to true but when I try doing that the validator tells me: data.payload.devices[1].attributes.queryOnlyOnOff is not a valid key.
Here's my SYNC response:
"requestId": "12519994412830690644",
"payload": {
"agentUserId": "0c3760df-3e43-4522-b1c2-16d1c4ca8b04",
"devices": [
{
"id": "dev0",
"type": "action.devices.types.SENSOR",
"traits": [
"action.devices.traits.OnOff"
],
"attributes": {
"commandOnlyOnOff": false,
"queryOnlyOnOff": true
},
"name": {
"name": "device1"
},
"willReportState": true
},
{
"id": "dev1",
"type": "action.devices.types.SWITCH",
"traits": [
"action.devices.traits.OnOff"
],
"attributes": {
"commandOnlyOnOff": true,
"queryOnlyOnOff": true
},
"name": {
"name": "device2"
},
"willReportState": true
}
]
}
}

Perseo rule can't be created: Event type not found

I'm emulating a dummy scenario to play around with Perseo and Orion. I'm using 4 docker containers: Mongo, Orion, Perseo FE, and Perseo Core. All of them running healthy.
The steps that I'm doing are:
First, I create the entity with POST to Orion (localhost:1026/v2/entities). This entity looks like this:
{
"id": "DummyEvent1",
"type": "DummyEvent",
"identification": {
"value": "default",
"type": "String"
}
}
Second, I create a subscription with a POST to Orion (localhost:1026/v2/subscriptions) in order to push this DummyEvent from Orion to Perseo:
{
"description": "A subscription to get info about DummyEvent1",
"subject": {
"entities": [
{
"id": "DummyEvent1",
"type": "DummyEvent"
}
],
"condition": {
"attrs": [ ]
}
},
"notification": {
"http": {
"url": "http://perseo-fe:9090/notices"
},
"attrs": [
"identification"
]
}
}
Third, If I GET all the subscriptions in Orion (localhost:1026/v2/subscriptions), I can see that Orion is forwading the DummyEvent correctly to Perseo:
{
"id": "5ca5c18ab07f5ae96aa12152",
"description": "A subscription to get info about DummyEvent1",
"status": "active",
"subject": {
"entities": [
{
"id": "DummyEvent1",
"type": "DummyEvent"
}
],
"condition": {
"attrs": []
}
},
"notification": {
"timesSent": 1,
"lastNotification": "2019-04-04T08:34:18.00Z",
"attrs": [
"identification"
],
"attrsFormat": "normalized",
"http": {
"url": "http://perseo-fe:9090/notices"
},
"lastSuccess": "2019-04-04T08:34:18.00Z",
"lastSuccessCode": 200
}
}
Fourth, But the problem appears when I try to POST a rule in Perseo (localhost:8080/perseo-core/rules) using this DummyEvent:
{
"name": "dummy_rule",
"text": "select * from DummyEvent",
"action": {
"type": "update",
"parameters": {
"name": "identification",
"value": "updatedValue",
"type": "string"
}
}
}
Perseo tells me this:
{
"error": "Failed to resolve event type: Event type or class named 'DummyEvent' was not found [select * from DummyEvent]"
}
What am I doing wrong?
Thanks!

Google Assistant : account linking and Actions sdk : fail to see sign in message

I want to enable account linking on an Google Assistant application using Actions Sdk.
I have already provided the information in the Account Linking section of the AoG Console :
The grant Type is Authorization code.
I use Auth0 as Oauth Server and i checked that the endpoints are functional.
When the application is invoked using the simulator, the server application send the following json response :
{
"expectUserResponse": true,
"finalResponse": null,
"expectedInputs": [{
"possibleIntents": [{
"intent": "actions.intent.SIGN_IN",
"inputValueData": null
}],
"inputPrompt": {
"richInitialPrompt": {
"items": [{
"simpleResponse": {
"textToSpeech": "Merci de vous authentifier",
"ssml": null,
"displayText": "Merci de vous authentifier"
}
}]
}
}
}],
"conversationToken": null,
"isInSandbox": false
}
I expected then to see the message like : it looks like your account … is not linked
Instead of that, the assistant immediately sends the following request to the server :
{
"user": {
"userId": "ABwppHGK6fClByrbLlS8WDM4xfY0qEck5i_kOGMhlJtuj64SjC-8qDqlH3xZ3BN7f9Yz1JDza-sc",
"locale": "fr-CA",
"lastSeen": "2018-04-23T14:12:02Z"
},
"conversation": {"conversationId": "1524493058716", "type": "NEW"},
"inputs": [{
"intent": "actions.intent.SIGN_IN",
"rawInputs": [{"inputType": "KEYBOARD"}],
"arguments": [{
"name": "SIGN_IN",
"extension": {
"#type": "type.googleapis.com/google.actions.v2.SignInValue",
"status": "ERROR"
}
}]
}],
"surface": {
"capabilities": [
{"name": "actions.capability.WEB_BROWSER"},
{"name": "actions.capability.MEDIA_RESPONSE_AUDIO"},
{"name": "actions.capability.SCREEN_OUTPUT"},
{"name": "actions.capability.AUDIO_OUTPUT"}
]
},
"isInSandbox": true,
"availableSurfaces": [
{
"capabilities": [
{"name": "actions.capability.SCREEN_OUTPUT"},
{"name": "actions.capability.AUDIO_OUTPUT"}
]
}
]
}
Did someone have the same problem ? Thanks
I have a working example, but it might be different of what you are doing because I ask the sign-in with dialogflow Integrations' tab for Google Assistant, and not explicitely with the SDK. The code is for the V2 of Dialogflow, I also have one for the V1 but it is now legacy.
This is my BONJOUR intent that is triggered when my app is launched:
const rp = require('request-promise');
app.intent('BONJOUR', (conv) => {
console.log("Debug: SAY_HELLO");
const accessToken = conv.user.access.token;
console.log("Access Token = "+accessToken);
//========Auth with OAuth website========
if (!accessToken) {
conv.ask(new SignIn());
} else {
let options = {
method: 'GET',
url: '[...]',//Oauth URL
headers:{
authorization: 'Bearer ' + accessToken,
}
};
// I use the RP lib as we need Promises for the V2 of Dialogflow.
return rp(options).then((body) => {
let data = JSON.parse(body);
console.log("auth data ="+JSON.stringify(data));
//You can access the auth data easily here
// For example if you want the name, it's in data.given_name, etc...
//Use conv.ask() to say something here
}).catch((error) => {
console.log("Error in auth request"+error);
})
}
});
Update:
This is my JSON mais the SignIn() is called, as I just tested it, it doesn't work (I created an intent that receives the actions_intent_SIGN_IN event from an example. And it never asks for sign In , I'm always in the else.)
Response {
"payload": {
"google": {
"expectUserResponse": true,
"richResponse": {
"items": [
{
"simpleResponse": {
"textToSpeech": "PLACEHOLDER"
}
}
]
},
"userStorage": "{\"data\":{}}",
"systemIntent": {
"intent": "actions.intent.SIGN_IN",
"data": {
"#type": "type.googleapis.com/google.actions.v2.SignInValueSpec"
}
}
}
},
"outputContexts": [
{
"name": [...],
"lifespanCount": 99,
"parameters": {
"data": "{}"
}
}
]
}
Then the request after that is:
Request {
"responseId": "5a711f0e-be66-4311-b776-2085e81e9bde",
"queryResult": {
"queryText": "actions_intent_SIGN_IN",
"parameters": {},
"allRequiredParamsPresent": true,
"fulfillmentMessages": [
{
"text": {
"text": [
""
]
}
}
],
"outputContexts": [
{
"name": "..."
},
{
"name": ".../actions_intent_sign_in",
"parameters": {
"SIGN_IN": {
"#type": "type.googleapis.com/google.actions.v2.SignInValue",
"status": "ERROR"
}
}
},
{
"name": "...",
"lifespanCount": 98,
"parameters": {
"data": "{}"
}
},
{
"name": "..."
},
{
"name": "..."
},
{
"name": "..."
},
{
"name": "..."
}
],
"intent": {
"name": "...",
"displayName": "Get Signin"
},
"intentDetectionConfidence": 1,
"diagnosticInfo": {},
"languageCode": "fr-fr"
},
"originalDetectIntentRequest": {
"source": "google",
"version": "2",
"payload": {
"isInSandbox": true,
"surface": {
"capabilities": [
{
"name": "actions.capability.WEB_BROWSER"
},
{
"name": "actions.capability.MEDIA_RESPONSE_AUDIO"
},
{
"name": "actions.capability.SCREEN_OUTPUT"
},
{
"name": "actions.capability.AUDIO_OUTPUT"
}
]
},
"inputs": [
{
"rawInputs": [
{
"inputType": "KEYBOARD"
}
],
"arguments": [
{
"extension": {
"#type": "type.googleapis.com/google.actions.v2.SignInValue",
"status": "ERROR"
},
"name": "SIGN_IN"
}
],
"intent": "actions.intent.SIGN_IN"
}
],
"user": {
"userStorage": "{\"data\":{}}",
"lastSeen": "2018-04-24T12:21:19Z",
"locale": "fr-FR",
"userId": "ABwppHHXrOc7N24RC5YS1dMvt7C-MbpzTb5TtzmufeIpGTCINVlReIMb8RKo4SGQMgBY7BUvO1qhn0B-"
},
"conversation": {
"conversationId": "1524572717282",
"type": "ACTIVE",
"conversationToken": "[\"_actions_on_google\"]"
},
"availableSurfaces": [
{
"capabilities": [
{
"name": "actions.capability.SCREEN_OUTPUT"
},
{
"name": "actions.capability.AUDIO_OUTPUT"
}
]
}
]
}
},
"session": "..."
}
I hope it can help you somehow.

I need receive the messages created in response texts in some intentions of the API.AI

My issue:
I have two responses, but my chat return only one specified "the speech", but i need that return the two, like do the console of api
example of response JSON from API:
{
"id": "XXXXXXXXXXX",
"timestamp": "2017-07-12T20:08:48.101Z",
"lang": "es",
"result": {
"source": "agent",
"resolvedQuery": "Hello how are you?",
"action": "",
"actionIncomplete": false,
"parameters": {},
"contexts": [
{
"name": "intent",
"parameters": {},
"lifespan": 1
}
],
"metadata": {
"intentId": "XXXXXXXXXXXXXXXXXXXXXXXX",
"webhookUsed": "false",
"webhookForSlotFillingUsed": "false",
"intentName": "welcome"
},
"fulfillment": {
"speech": "Hello!",
"messages": [
{
"type": 0,
"speech": "Hello!"
},
{
"type": 0,
"speech": "Bye!"
}
]
},
"score": 1
},
"status": {
"code": 200,
"errorType": "success"
},
"sessionId": ""
}
I need show the black messages.