So after successful Google Account linking in my app, I tested it using an Android device without any problem. I used the "in conversation prompt" technique to request the user to authenticate to proceed further. In other words, I was successfully able to receive the "user" property of response from Dialogflow with valid accessToken (among other info).
Now, I tried it on a Google Home device. The device is configured with the same email Id I used on the Android mobile device. The G.Home successfully loads the app when I invoke it. But the missing part here is the accessToken in the user property (JSON below). I have assumed the following in the above scenario:
Since I have already signed in successfully on the Android mobile device, the next time I try to invoke the app on the same device, the app doesn't prompts for the "sign in" because it already has the accessToken (until it is expired). And since I am using the same gmail address on the G. Home device, I should have gotten the same accessToken as well.
As long as the same gmail address is used, it doesn't matter what device/surface I use to Google auth myself, I will always get the accessToken if it has not expired.
The setup/configuration for the whole Google Account linking is detailed in the above link I've shared. Here is the JSON I've received on G. Home and Android device respectively:
{
"originalRequest": {
"source": "google",
"version": "2",
"data": {
"isInSandbox": true,
"surface": {
"capabilities": [
{
"name": "actions.capability.MEDIA_RESPONSE_AUDIO"
},
{
"name": "actions.capability.AUDIO_OUTPUT"
}
]
},
"inputs": [
{
"rawInputs": [
{
"query": "continue",
"inputType": "VOICE"
}
],
"arguments": [
{
"rawText": "continue",
"textValue": "continue",
"name": "text"
}
],
"intent": "actions.intent.TEXT"
}
],
"user": {
"lastSeen": "2018-07-17T10:33:57Z",
"locale": "en-US",
"userId": "15229245xxx"
},
"conversation": {
"conversationId": "153182806xxx",
"type": "ACTIVE",
"conversationToken": "[\"disclaimer_option\"]"
},
"availableSurfaces": [
{
"capabilities": [
{
"name": "actions.capability.SCREEN_OUTPUT"
},
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.WEB_BROWSER"
}
]
}
]
}
},
"id": "9459d297-4746-4ffe-99fa-xxx",
"timestamp": "2018-07-17T11:49:02.693Z",
"lang": "en-us",
"result": {
"source": "agent",
"resolvedQuery": "continue",
"speech": "",
"action": "v00.authentication.pin",
"actionIncomplete": false,
"parameters": {
"CallEnum": "Login"
},
"contexts": [
{
"name": "disclaimer_option",
"parameters": {
"CallEnum": "Login",
"CallEnum.original": ""
},
"lifespan": 0
},
{
"name": "pin",
"parameters": {
"CallEnum": "Login",
"CallEnum.original": ""
},
"lifespan": 1
},
{
"name": "google_assistant_input_type_voice",
"parameters": {
"CallEnum": "Login",
"CallEnum.original": ""
},
"lifespan": 0
},
{
"name": "actions_capability_audio_output",
"parameters": {
"CallEnum": "Login",
"CallEnum.original": ""
},
"lifespan": 0
},
{
"name": "actions_capability_media_response_audio",
"parameters": {
"CallEnum": "Login",
"CallEnum.original": ""
},
"lifespan": 0
}
],
"metadata": {
"intentName": "v00.authentication.pin",
"isResponseToSlotfilling": false,
"intentId": "146f0d7d-0194-43cb-90e4-xxx",
"webhookUsed": "true",
"webhookForSlotFillingUsed": "false",
"nluResponseTime": 87
},
"fulfillment": {
"speech": "",
"messages": []
},
"score": 1
},
"status": {
"code": 200,
"errorType": "success"
},
"sessionId": "15318280xxx"
}
and
{
"originalRequest": {
"source": "google",
"version": "2",
"data": {
"isInSandbox": true,
"surface": {
"capabilities": [
{
"name": "actions.capability.MEDIA_RESPONSE_AUDIO"
},
{
"name": "actions.capability.WEB_BROWSER"
},
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.SCREEN_OUTPUT"
}
]
},
"inputs": [
{
"rawInputs": [
{
"query": "Continue",
"inputType": "TOUCH"
}
],
"arguments": [
{
"rawText": "Continue",
"textValue": "Continue",
"name": "text"
}
],
"intent": "actions.intent.TEXT"
}
],
"user": {
"lastSeen": "2018-07-17T09:44:08Z",
"accessToken": "6IlPNz0YFb_stP0quM1xxx",
"locale": "en-US",
"userId": "15229245xxx"
},
"conversation": {
"conversationId": "153182082xxx",
"type": "ACTIVE",
"conversationToken": "[\"disclaimer_option\"]"
},
"availableSurfaces": [
{
"capabilities": [
{
"name": "actions.capability.WEB_BROWSER"
},
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.SCREEN_OUTPUT"
}
]
}
]
}
},
"id": "ae2e3ff8-f351-497b-9429-xxx",
"timestamp": "2018-07-17T09:47:54.999Z",
"lang": "en-us",
"result": {
"source": "agent",
"resolvedQuery": "Continue",
"speech": "",
"action": "v00.authentication.pin",
"actionIncomplete": false,
"parameters": {
"CallEnum": "Login"
},
"contexts": [
{
"name": "google_assistant_input_type_touch",
"parameters": {
"CallEnum": "Login",
"CallEnum.original": ""
},
"lifespan": 0
},
{
"name": "pin",
"parameters": {
"CallEnum": "Login",
"CallEnum.original": ""
},
"lifespan": 1
},
{
"name": "disclaimer_option",
"parameters": {
"CallEnum": "Login",
"CallEnum.original": ""
},
"lifespan": 0
},
{
"name": "actions_capability_screen_output",
"parameters": {
"CallEnum": "Login",
"CallEnum.original": ""
},
"lifespan": 0
},
{
"name": "actions_capability_audio_output",
"parameters": {
"CallEnum": "Login",
"CallEnum.original": ""
},
"lifespan": 0
},
{
"name": "actions_capability_media_response_audio",
"parameters": {
"CallEnum": "Login",
"CallEnum.original": ""
},
"lifespan": 0
},
{
"name": "actions_capability_web_browser",
"parameters": {
"CallEnum": "Login",
"CallEnum.original": ""
},
"lifespan": 0
}
],
"metadata": {
"intentName": "v00.authentication.pin",
"isResponseToSlotfilling": false,
"intentId": "146f0d7d-0194-43cb-90e4-xxx",
"webhookUsed": "true",
"webhookForSlotFillingUsed": "false",
"nluResponseTime": 87
},
"fulfillment": {
"speech": "",
"messages": []
},
"score": 1
},
"status": {
"code": 200,
"errorType": "success"
},
"sessionId": "153182082xxx"
}
My question is, where can I get the accessToken when I am using the Google Home device?
Related
I am trying to follow the developer guide for a air booking process found in the documentation. https://developer.sabre.com/guides/travel-agency/workflows/air-booking
Here, I have used token based authentication (v2) and I could successfully search and book using the rest api. However, Upon hitting the revalidate itinerary api with the example found in the documentation https://developer.sabre.com/docs/rest_apis/air/search/revalidate_itinerary/reference-documentation
Here, I am getting following error. (Note: I have changed the pcc code in here. The original request uses the correct pnr.)
Response:
{
"groupedItineraryResponse": {
"version": "6.3.0",
"messages": [
{
"severity": "Info",
"type": "WORKERTHREAD",
"code": "TRANSACTIONID",
"text": "3019835637227710880"
},
{
"severity": "Info",
"type": "SERVER",
"code": "ASE032LPSCIL668.ATSE.CERT.ASCINT.SABRECIRRUS.COM",
"text": "27038"
},
{
"severity": "Info",
"type": "DRE",
"code": "RULEID",
"text": "25961"
},
{
"severity": "Info",
"type": "DEFAULT",
"code": "RULEID",
"text": "25959"
},
{
"severity": "Error",
"type": "IF2",
"code": "PROCESS",
"text": "PCC EPCC: Revalidate Itinerary not requested."
},
{
"severity": "Error",
"type": "ERR",
"code": "ERR",
"text": "Error during Processing"
}
],
"statistics": {
"itineraryCount": 0
}
}
}
API URL: https://api-crt.cert.havail.sabre.com/v3/shop/flights/revalidate
Request json:
{
"OTA_AirLowFareSearchRQ": {
"OriginDestinationInformation": [
{
"RPH": "0",
"DepartureDateTime": "2021-08-14T00:00:00",
"OriginLocation": {
"LocationCode": "KRK"
},
"DestinationLocation": {
"LocationCode": "WAW"
}
}
],
"POS": {
"Source": [
{
"PseudoCityCode": "EPCC",
"RequestorID": {
"CompanyName": {
"Code": "TN"
},
"ID": "1",
"Type": "1"
}
}
]
},
"TPA_Extensions": {
"IntelliSellTransaction": {
"RequestType": {
"Name": "200ITINS"
}
}
},
"TravelPreferences": {
"TPA_Extensions": {
"DataSources": {
"NDC": "Disable",
"ATPCO": "Enable",
"LCC": "Disable"
},
"NumTrips": {}
}
},
"TravelerInfoSummary": {
"AirTravelerAvail": [
{
"PassengerTypeQuantity": [
{
"Code": "ADT",
"Quantity": 1
}
]
}
],
"SeatsRequested": [
1
]
},
"Version": "3"
}
}
You need to list all the flights with booking classes in TPA_Extension under OriginDestinationInformation.
So, your OriginDestinationInformation should look something like this:
"OriginDestinationInformation": [
{
"RPH": "0",
"DepartureDateTime": "2021-10-11T14:50:00",
"OriginLocation": {
"LocationCode": "BEG"
},
"DestinationLocation": {
"LocationCode": "ZRH"
},
"TPA_Extensions": {
"SegmentType": {
"Code": "O"
},
"Flight": [
{
"Number": 1417,
"DepartureDateTime": "2021-10-11T14:50:00",
"ArrivalDateTime": "2021-10-11T16:40:00",
"Type": "A",
"ClassOfService": "K",
"OriginLocation": {
"LocationCode": "BEG"
},
"DestinationLocation": {
"LocationCode": "ZRH"
},
"Airline": {
"Operating": "LX",
"Marketing": "LX"
}
}
]
}
}
],
I am developing fanSpeed and colorSetting trait for Google Actions, but whenever I execute command for setting fan speed or setting light colour, it fails. Here is my JSON for sync,query and execute step:
sync
{
"requestId":"d25ty67q-98jui-581aa-j891-b1f6dhuas"
"payload":{
"devices": [
{
"id": "AA96A0#16",
"type": "action.devices.types.FAN",
"traits": [
"action.devices.traits.OnOff",
"action.devices.traits.FanSpeed"
],
"roomHint": "ROOM",
"deviceInfo": {
"manufacturer": "smart Homes"
},
"name": {
"defaultNames": [
"fan"
],
"name": "fan"
},
"willReportState": true,
"customData": {
},
"attributes": {
"commandOnlyOnOff": false,
"commandOnlyFanSpeed": false,
"reversible": false,
"availableFanSpeeds": {
"speeds": [
{"speed_name": "speed_low", "speed_values": [{"speed_synonym": ["low", "low speed", "slow"], "lang": "en"}]},
{"speed_name": "speed_medium", "speed_values": [{"speed_synonym": ["medium", "medium speed", "med"], "lang": "en"}]},
{"speed_name": "speed_high", "speed_values": [{"speed_synonym": [ "high speed", "high"], "lang": "en"}]},
{"speed_name": "speed_highest", "speed_values": [{"speed_synonym": [ "highest speed", "highest"], "lang": "en"}]}
],
"ordered": true
}
}
},
{
"id": "240A50#0",
"type": "action.devices.types.LIGHT",
"traits": [
"action.devices.traits.OnOff",
"action.devices.traits.ColorSetting"
],
"roomHint": "ROOM",
"deviceInfo": {
"manufacturer": "smart Homes"
},
"name": {
"defaultNames": [
"light"
],
"name": "light"
},
"willReportState": false,
"customData": {
},
"attributes": {
"commandOnlyColorSetting": true,
"colorModel": "hsv"
}
}
],
"agentUserId": "Home555"
}
}
Execute Fan:
{
"commands": [
{
"ids": [
"AA96A0#16"
],
"status": "SUCCESS",
"states": {
"online": true,
"on": true,
"currentFanSpeedSetting": "speed_highest"
}
}
]
}
Query Fan:
{
"requestId":"167278043664013971",
"payload":{
"devices": {
"AA96A0#16": {
"status": "SUCCESS",
"online": true,
"on": true,
"currentFanSpeedSetting": "speed_highest"
}
}
}
}
Execute color-light:
{
"commands": [
{
"ids": [
"240A50#0"
],
"status": "SUCCESS",
"states": {
"online": true,
"on": true,
"color": {
"spectrumHSV": {
"hue": 120,
"saturation": 1,
"value": 1
}
}
}
}
]
}
Query color-light:
{
"requestId":"167278043664013971",
"payload":{
"devices": {
"240A50#0": {
"status": "SUCCESS",
"online": true,
"on": true,
"color": {
"spectrumHSV": {
"hue": 0,
"saturation": 0,
"value": 1
}
}
}
}
}
}
Speaker response: Sorry, it looks like smart homes is unavailable right now.
However my request is always executing and I can see state change on my device. Can anyone point out Why it is failing?
The json for execute for both the fan and the bulb has missing values for requestId. This might be causing the failures with the execution commands.
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.
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.
I am using jira rest api's in my application.
I have found the api for getting the meta-data for creating jira issue but that API doesn't return default values of the fields for example :-
This is the request :-
http://kelpie9:8081/rest/api/latest/issue/createmeta?projectKeys=QA&issuetypeNames=Bug&expand=project.issuetypes.fields
the default value of priority field is set to "major" and the description of priority is also customized but the return from api is:-
{
"expand": "projects",
"projects": [
{
"expand": "issuetypes",
"self": "http://kelpie9:8081/rest/api/2/project/QA",
"id": "10010",
"key": "QA",
"name": "QA",
"avatarUrls": {
"16x16": "http://kelpie9:8081/secure/projectavatar?size=small&pid=10010&avatarId=10011",
"48x48": "http://kelpie9:8081/secure/projectavatar?pid=10010&avatarId=10011"
},
"issuetypes": [
{
"expand": "fields",
"self": "http://kelpie9:8081/rest/api/2/issuetype/1",
"id": 1,
"name": "Bug",
"iconUrl": "http://kelpie9:8081/images/icons/bug.gif",
"fields": {
"summary": {
"required": true,
"schema": {
"type": "string",
"system": "summary"
},
"operations": [
"set"
]
},
"timetracking": {
"required": false,
"operations": [ ]
},
"issuetype": {
"required": true,
"schema": {
"type": "issuetype",
"system": "issuetype"
},
"operations": [ ],
"allowedValues": [
{
"id": "1",
"name": "Bug",
"description": "A problem which impairs or prevents the functions of the product.",
"iconUrl": "http://kelpie9:8081/images/icons/bug.gif"
}
]
},
"priority": {
"required": false,
"schema": {
"type": "priority",
"system": "priority"
},
"name": "Priority",
"operations": [
"set"
],
"allowedValues": [
{
"self": "http://172.19.30.101:18080/rest/api/2/priority/1",
"iconUrl": "http://172.19.30.101:18080/images/icons/priority_blocker.gif",
"name": "Blocker",
"id": "1"
},
{
"self": "http://172.19.30.101:18080/rest/api/2/priority/2",
"iconUrl": "http://172.19.30.101:18080/images/icons/priority_critical.gif",
"name": "Critical",
"id": "2"
},
{
"self": "http://172.19.30.101:18080/rest/api/2/priority/3",
"iconUrl": "http://172.19.30.101:18080/images/icons/priority_major.gif",
"name": "Major",
"id": "3"
},
{
"self": "http://172.19.30.101:18080/rest/api/2/priority/4",
"iconUrl": "http://172.19.30.101:18080/images/icons/priority_minor.gif",
"name": "Minor",
"id": "4"
},
{
"self": "http://172.19.30.101:18080/rest/api/2/priority/5",
"iconUrl": "http://172.19.30.101:18080/images/icons/priority_trivial.gif",
"name": "Trivial",
"id": "5"
}
]
},
"customfield_10080": {
"required": false,
"schema": {
"type": "array",
"items": "string",
"custom": "com.atlassian.jira.plugin.system.customfieldtypes:labels",
"customId": 10080
},
"operations": [ ]
},
"customfield_10010": {
"required": false,
"schema": {
"type": "array",
"items": "string",
"custom": "com.atlassian.jira.plugin.system.customfieldtypes:labels",
"customId": 10010
},
"operations": [ ]
},
"customfield_10071": {
"required": false,
"schema": {
"type": "array",
"items": "string",
"custom": "com.atlassian.jira.plugin.system.customfieldtypes:textfield",
"customId": 10071
},
"operations": [ ]
}
}
}
]
}
]
}
There is nothing like default value or description in priority field, how will I get those values?