Google Actions no execute - actions-on-google

I have written a simple Java application based on Google example code:
https://github.com/actions-on-google/smart-home-nodejs
and watched a lot of movies, took Google codelabs, but I'm stuck.
My application responses to required actions (intents: action.devices.SYNC, action.devices.QUERY, action.devices.EXECUTE) - chcecked with Google validator, JSON validators. I have also implemeted simple OAuth authorization, created Google Actions projects for Smart Home.
After few hours of debugging I have got:
my test application is listed in Add devices menu,
I can select my application from list and connect it,
Google performs OAuth checking and everythings is OK (I see this in Nginx logs and my application logs),
then Google Actions sends action.devices.SYNC request to my server,
I responde with a test device:
{
"requestId":"14182994871341693427",
"payload":{
"agentUserId":"rysiek",
"devices":[
{
"id":"dev1",
"type":"action.devices.types.LIGHT",
"traits":[
"action.devices.traits.OnOff"
],
"name":{
"name":"główne"
},
"willReportState":false,
"roomHint":"pokój dzienny"
}
]
}
}
I have also tryied with willReportState: true,
then it (Google Assistant) asks me to assign devices to room which I'm doing.
After this nothing more is working.
I'm trying to say to my phone Turn on light główne (in polish "Włącz światło główne", "Włącz światło główne w pokoju dziennym" etc - tried a lot of sentences), but it just shows me web search results. No request is send to my server (action.devices.EXECUTE) - I have everything behind a Nginx proxy, and no requests are done to my server (not request is visible in logs).
I have no idea, what to do to make it work. Any help will be appreciated.
BTW1. Google Assistant is available in Poland from this year (16.01.2019) from few days and I'm wondering if this is my problem or Google problem? Is this even possible?
For example I'm saying Ok Google, synchronize my devices (in polish: Ok Google, synchronizuj moje urządzenia), and I get response in english:
"Sorry, I didn't get any response.".
But I see that there was a request for SYNC, and my server responed.
BTW2. I have connected Google Chromecast to Google Assistant, and it works without a problem - I'm mean I saying Turn on TV (in polish: Włącz telewizor) and TV is started like expected.

Checking the list of supported languages for smart home traits, Polish is currently not included. While it does seem like your SYNC response does work, you won't be able to interact with devices in Polish right now. While this will likely happen in the future, you'll only be able to use one of the languages mentioned above for the moment.
Once Polish support for smart home actions are supported, you shouldn't need to do any extra work for commands to succeed.

Related

How can I resolve 400 bad request in Google Picker dialog in test application?

I'm running into trouble with test users and the Picker component in my web applicaton.
A subset of my test users are receiving a 400: The server cannot process the request because it is malformed when attempting to access the picker. Some of them experience a looping sign-in beforehand.
The picker is constructed in the following way inside of a useEffect in a React component:
// if there's a non-config related bug, I would imagine it must be related to getting the access token here.
const accessToken = gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse().access_token;
const view = new picker.DocsView(picker.ViewId.DOCUMENTS);
view.setIncludeFolders(true);
const pickerDisplay = new picker.PickerBuilder()
.enableFeature(picker.Feature.MULTISELECT_ENABLED)
.setAppId(appId)
.addView(view)
.addView(new picker.DocsUploadView())
.setOAuthToken(accessToken)
.setDeveloperKey(apiKey)
.setCallback(pickerCallback)
.build();
setPicker(pickerDisplay); // sets picker state
Because I am not receiving the error message and the application has not been verified, I believe this likely has something to do with the IAM.
I believe I've been able to eliminate managed browsers settings,
cookie settings, and extensions as possible sources of error.
I've also added the users to the GCP project with the Browser role, though
they did not receive invites. What do I need to try next to resolve
this issue?
I cannot provide a minimum reproducible example because this only seems to be confined to a subset of my users' browsers.
I reached out to Google support, but unfortunately this is not covered.
I need to get this application into production relatively soon, so I'm very seriously considering just writing my own Drive microservice and recreating the Picker. I would love to avoid this though.

How to prevent google action from closing the conversation?

I'm developing a Google Action through DialogFlow and a webhook (that will run on a Nest Hub) that I want to act like this:
the user invokes the action "Hey Google, talk to ACTIONAME"
through the Default Welcome Intent ("hooked" to my web service) the Action replies to the user and open a website
app.intent('Default Welcome Intent', conv => {
conv.ask('Hi! I'm opening your site')
conv.ask(new HtmlResponse({
url: 'https://MY_IOT_SITE'
}))
})
now, the user could be "silent" for mins or hours, but I'd like to prevent Google Actions to close the ACTIONNAME and return to the clock, while until now the action closes after a couple of minutes
Is it somehow possible?
Thank you.
This is not possible. The platform intentionally places an upper bound on how long an action can run without any user input. This is done so that an action cannot occupy the device longer than expected and prevent future inputs from unintentionally getting routed to your action rather than the Google Assistant.
You can take a look at additional guidelines when developing your web app.
Since your question refers to an IoT-related website, you may want to take a look at the Smart Home reference, which provides an alternative way to let users control smart home devices with their voice or built-in graphical widgets.

Serverless Watson Deployment? (Questions about integrations with other RESTful services)

Introduction:
I feel like I'm missing something terribly obvious about how Watson Assistant should be designed at an architecture level, but maybe I'm not.
The specific problem I'm having is that I can't seem to get API calls for information back into the conversation.
The bigger issue is that I'm not sure I setting this all up correctly for the long-haul of what I'm trying to accomplish.
Purpose:
I am building a 24/7 customer-service Tier 1 helpdesk for our managed networks. A user of one of our networks should, via SMS, Web chat, Facebook messenger, and eventually phone call, be able to ask for:
Instructions on how to connect their specific device (PC, Mac, Chromebook, Xbox, Apple TV, etc.)
Ask for help troubleshooting if the instructions don't result in a successful connection. (Step by step instructions for deleting the saved network, restarting the wireless card, etc.)
Help creating a case - at which point the conversation becomes Watson asking for a bunch of information, like what time and date they first experienced the problem, any other times/dates they experienced the problem, their MAC address, etc. etc.
Problems:
I have most of the dialog built and working well. Getting information via Entities, saving to context variables, spitting them back out to make the conversation work, digressions, etc. all working.
I cannot, for the life of me, figure out what I am doing wrong when trying to GET information from an external API.
We have a 'daily password' for our guest networks, and we would like a user who asks for the daily password to receive it. This involves a very simple GET request to a publicly accessible server.
I have built a BlueMix/IBM Cloud function that works perfectly, but I can't seem to successfully call or receive information back from it.
Watson Error:
Error when updating output with output of dialog node id [node_66_xxxxxxxxxx]. Node output is [{"text":{"values":["Today's password for <? $guestNetwork.ssid ?> is <? $guestNetwork.password ?>"],"selection_policy":"sequential"}}] SpEL evaluation error: Expression [ $guestNetwork.ssid ] converted to [ context['guestNetwork'].ssid ] at position 0: EL1007E: Property or field 'ssid' cannot be found on null (and there is 1 more error in the log)
This error leads me to believe I am not properly defining the result variable in Watson, or improperly trying to retrieve it in conversation - because I do know my code returns the SSID and Password when I run it in BlueMix Console.
JSON for the action itself (and yes, I am setting the credentials in the previous node):
{
"output": {
"text": {
"values": [
"Today's password for <? $guestNetwork.ssid ?> is <? $guestNetwork.psk ?>"
],
"selection_policy": "sequential"
}
},
"actions": [
{
"name": "get-http-resource/getGuestNetworkPassword",
"type": "server",
"credentials": "$private.myCredentials",
"result_variable": "$guestNetwork"
}
]
}
Question:
Is my idea of a 'serverless' Watson possible by using Watson <-> IBM Cloud <-> external services? We don't currently have an 'application' or a server, it's all integrations between existing services.
Can anyone help me understand what I'm doing wrong when trying to access that variable?
Bonus points: How do I know to access the variable only after the action has completed successfully in IBM cloud? Basically, if accessing the information via the IBM Cloud function I wrote takes 1.5 seconds, do I need to pause the dialog for 1.5 seconds? Or am I completely missing the point for how to get external info in and out of Watson?
EDIT:
After watching Mitch's video, I have changed a couple things around, and the error message has evolved to this:
"Error when updating output with output of dialog node id
[node_66_1533646714776]. Node output is [{"text":{"values":["Today's
password for is "],"selection_policy":"sequential"}}] SpEL evaluation error:
Expression [ $guestNetwork['ssid'] ] converted to [
context['guestNetwork']['ssid'] ] at position 24: EL1012E: Cannot
index into a null value" error.
Without seeing your dialog, its a guess, but most common error I see is that you just need to jump to a child dialog node after doing the action call. You cannot do the action call and show the response in the same dialog node, as dialog needs a chance to run the action.
Its outlined in my video here:
https://ibm-dte.mybluemix.net/ibm-watson-assistant?refresh
see the video on dialog callouts. Its 13 minutes long I'm sure you only need about 2 of them, but still, should help.
What you are trying to do is definitely possible, especially if it works from within the cloud function environment.
We re-created the action using the default package (not having it in a sub-package), and it started working immediately.
Things to note: Watson dialog editor does not like dashes in the package name.
Thanks Mitch!

Parse Signup Problems

So, I wanted to create a new social media app using Swift and Parse. When I go to the Parse site, and click on dashboard, it gives me a login screen. I don't have an account, so I click on the "I don't have a parse account" button. When I click on that, it just takes me back to the home page. I did manage to get the code and frameworks and stuff that I needed from the docs, but that didn't quite work. It gave me this for the initialize code:
let configuration = ParseClientConfiguration {
$0.applicationId = "YOUR_APP_ID"
$0.server = "http://YOUR_PARSE_SERVER:1337/parse"
}
In the tutorial I'm watching, rather than "YOUR_APP_ID" and "http://YOUR_PARSE_SERVER:1337/parse" it just had a bunch of letters and numbers, which I would assume are the app ID and Parse server. My guess is, that I need an account to get those. Would that be correct? And, does anyone know why I can't seem to get an account? Thanks.
Parse.com is shutting down, so that's why you are not allowed to create new accounts on the service. Check the blog post.
They open sourced a nodeJS implementation, which you should definitely check out at link, and here is an example to get you started. You can easily use the deploy buttons to host the server on services like Heroku, AWS, Azure, etc. You can also deploy a server locally, for testing purposes.
Although it's true that Parse is discontinuing early next year, you can still setup a new app if you want to use the service for a shorter term project. Replace your code with the following.
Parse.setApplicationId("YOUR-APP-ID", clientKey: "YOUR-CLIENT-ID")
You can find your App ID and Client ID in your app's settings > security & keys.
EDIT: You definitely need an account for this to work.

Windows Phone 8 facebook login (Beta)

I've been going through the instructions here trying to implement the FB login via the FB Beta application: http://facebooksdk.net/docs/phone/sso/
I had it working for a while, however ever since the last Beta update, something started failing.
Whenever i get a callback to MapUri from the FB application, i don't get the proper Uri being passed in. The following code always fails (the uri contains mundane URIs of pages within the application, not what i expected).
AppAuthenticationHelper.IsFacebookLoginResponse(uri)
I might have changes something on the web-configuration of the application, or on the WP8, however going over the settings, nothing seems to be working.
I checked the usual suspects (AppIds, ProductIds etc...) and it seems to be running properly, so that changing one of those IDs throws the error like i expect it to, however when i have setup everything properly, i get the facebook application to open my application, however the UriMapperBase when it get's called never has the proper Uri in it.
Here is the configuration for the WMAppManifest for the extension:
<Extensions>
<Protocol Name="msft-54045783c54e4c3a9f2b470c5b7ba353" NavUriFragment="encodedLaunchUri=%s" TaskID="_default" />
</Extensions>
Any ideas?
P.S. I am testing this on real devices with the latest FB Beta application.
UPDATE: Seems to only affect Samsung phones, no issues with HTC, haven't tried other ones.