0

Overview

I am using the Node.js library actions-on-google client to build a smarthome action for the Garage Door device type. This action is deployed as a Cloud Function in GCP. I can confirm that the following works perfectly so far:

  • Accounting linking with our OAuth flow
  • Responding to sync intents (ie. onSync() in the client)
  • Responding to execute intents (ie. onExecute() in the client)

Problem

Despite that other callbacks (onSync() and onExecute()) work fine, we do not see any evidence of onQuery() being called no matter what. There aren't any errors showing in Stackdriver nor are their any logs being generated in Stackdriver under the "Google Actions" filter either.

We expect onQuery() to run when we ask Google Assistant things like is the garage door open? and is Matt's Door closed?

  • We tried removing async to see if the call was hanging
  • We tried removing headers in the lambda
  • We tried removing all other code and redploying to isolate onQuery()

Code

The following code shows the simple onQuery() callback. onExecute() and onSync code has been removed for clarity.

'use strict';

const functions = require('firebase-functions');
const {smarthome} = require('actions-on-google');

const app = smarthome({
  jwt: require('./XXXXXXXXX-XXXXXXXXXX.json'),
  debug: true,
});

//
// Note: Removed onSync() and onExecute() for clarity
//

app.onQuery(async (body, headers) => {

  // Expecting to see these logging statements in
  // Stackdriver like we do for onExecute() and 
  // onSync() ... but nothing ever shows up.
  
 console.info('=== onQuery.body', body);
 console.info('=== onQuery.headers', headers);

  // We have hardcoded the following ID and a "closed" 
  // state. It matches a valid device ID to the testing 
  // account we are using.

  return {
    requestId: body.requestId,
    payload: {
      devices: {
        '2489e4a92799728292b8d5a8b1c9d177': {
          on: true,
          online: true,
          openPercent: 0,
        }
      }
    }
  };
});

exports.smarthome = functions.https.onRequest(app);

We considered the possibility that the JSON returned in the call to onSync() might be missing a trait or something that prevents it from responding to a query intent properly but we have not been able to identify anything that might be incorrect or missing. Here is the JSON payload returned from onSync():

{
 "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
 "payload": {
  "agentUserId": "1836.15267389",
  "devices": [{
   "id": "1234",
   "type": "action.devices.types.GARAGE",
   "traits": [
    "action.devices.traits.OpenClose"
   ],
   "name": {
    "defaultNames": ["Smart Garage Door"],
    "name": "Matt's Door",
    "nicknames": ["Matt's Door"]
   },
   "willReportState": true,
   "attributes": {
    "openDirection": [
     "UP",
     "DOWN"
    ]
   },
   "deviceInfo": {
    "manufacturer": "ABC Corp",
    "model": "test",
    "hwVersion": "1.0",
    "swVersion": "1.0"
   }
  }]
 }
}

Expected Result

We expect Google Assistant to respond with "Garage door is closed" or some other equivalent. Instead, we receive "Sorry, I can't reach Matt's Door right now. Please try again."

devunwired
  • 62,780
  • 12
  • 127
  • 139
dziczkzw
  • 31
  • 1
  • 3
  • Is this potentially a naming issue? If it had a generic nickname like `Garage Door` would it work? – Nick Felker Dec 12 '19 at 16:37
  • 1
    @NickFelker - it definitely was an issue with the `name` in the JSON returned from a sync intent. Ultimately, I ended up using something like the code below and the action started responding to query intents as I expect. Answering my own question in case others bump into this! – dziczkzw Dec 14 '19 at 00:43
  • Oh... and thanks @NickFelker for pointing out my mistake. :) Much appreciated. – dziczkzw Dec 14 '19 at 00:50

1 Answers1

0

Answering my own question here in case anyone else has this trouble. The reason why my action was handling the SYNC and EXECUTE intents but not the QUERY intent came down to what default/user names I assigned each device in the SYNC response.

Ultimately, I started using the following and my action began responding to QUERY intents as expected again:

...

name: {
  defaultNames: ['Garage Door'],
  name: door.name,
  nicknames: [door.name, 'Garage Door']
},

...

where door.name is a name which is set by the user and is returned by an API call.

dziczkzw
  • 31
  • 1
  • 3