1

Setting up a Google Assistant App via the NodeJS Google Actions SDK is done this way:

It seems that these are synchronous functions (per the documentation given on https://developers.google.com/actions/reference/nodejs/ActionsSdkApp#ActionsSdkApp

const app = new App({request: req, response: res});
function pickOption (app) {
   /*A bunch of steps here*/
}
function optionPicked (app) {
   /*Another bunch of steps here*/
}

const actionMap = new Map();
actionMap.set(app.StandardIntents.TEXT, pickOption);
actionMap.set(app.StandardIntents.OPTION, optionPicked);

app.handleRequest(actionMap);

Is it possible for pickOption and optionPicked to be asynchronous functions? i.e., would it be correct to have pickOption be implemented as

function pickOption(){
   var pickOptionPromise = Q.defer();
   pickOptionPromise.resolve({
     /*Some results here*/
   });
   return pickOptionPromise.promise;
}

2 Answers2

1

Yes, there are two functions you'll use most of the time to return a response to the Assistant. app.ask and app.tell. These wrap your response into a JSON object and return it to Google.

Your pickOption and optionPicked functions can be run asynchronously and run app.tell after your logic is completed.

Nick Felker
  • 11,536
  • 1
  • 21
  • 35
1

For starters, there is no requirement that you use app.handleRequest() at all. (You don't even need to use app, but that's not your question.) It is there as a convenience method to map intents to functions, but you're free to do that task via other means. I tend to do things like

function handler1( app ){
  // Does the logic asynchronously, but no voice response for some situation.
  // Returns a Promise that resolves to an Object about what we did
}

function handler2( app ){
  // Does the logic asynchronously, but no voice response for some situation.
  // Returns a Promise that resolves to an Object about what we did
}

function chooseHandler( app ){
  // Some logic which may be async, but which returns
  // a Promise that will resolve to either handler1 or 2
}

function sendResponse( app, handlerResult ){
  // Uses the handlerResult object to determine what to
  // send back to the user. This may involve async database calls.
  // Calls either app.ask(), or app.tell(), or a related call.
  // Returns a Promise indicating success
}

chooseHandler( app )
  .then( handler => handler( app ) )
  .then( result  => sendResponse( app, result ) )
  .catch( err => {
    // Log the error or something
  } );

(This is meant to be illustrative. It isn't actually tested, nor guaranteed to be the highest quality or best design for a particular purpose.)

In this, the chooseHandler() is usually synchronous, but could be async if we need to do things like check if the user has been with us before and choose a different handler based on that. The handlers are almost always async, and the important bit is that they don't actually pick the phrases that are sent back to the user - that is done in sendResponse() and also may involve a database call which is async.

Prisoner
  • 49,922
  • 7
  • 53
  • 105