简体   繁体   English

错误:未设置响应。 Cloud Functions for Actions on Google Assistant

[英]Error: No response has been set. Cloud Functions for Actions on Google Assistant

I am building an Assistant app for Google Home, using Dialogflow , Cloud Functions and the new NodeJS Client Library V2 for Actions on Google .我正在为 Google Home 构建助手应用程序,使用DialogflowCloud Functions和新的NodeJS Client Library V2 for Actions on Google In fact I am in the process of migrating my old code built with V1 to V2.事实上,我正在将使用 V1 构建的旧代码迁移到 V2。

The Context上下文

I am trying to get the user's location using two seperate intents: Request Permission (Intent that triggers/send permission request to the user) and User Info (Intent that checks if the user granted permission and then returns the data requested by the assistant to continue.我正在尝试使用两个单独的意图获取用户的位置: Request Permission (触发/向用户发送权限请求的意图)和User Info (检查用户是否授予权限然后返回助手请求的数据以继续的意图) .

The Issue问题

The problem is that the same code that was working just fine on V1 isn't working on V2.问题是在 V1 上运行良好的相同代码在 V2 上不起作用。 So I had to do some refactoring.所以我不得不做一些重构。 And when I deploy my cloud function I am able to successfully request the user's permission, get his location and then using an external library ( geocode ), I can convert the latlong to a human readable form.当我部署我的云功能时,我能够成功请求用户的许可,获取他的位置,然后使用外部库( geocode ),我可以将geocode转换为人类可读的形式。 but for some reasons (I think its promises) I can't resolve the promise object and show it to the user但由于某些原因(我认为它的承诺)我无法解析承诺对象并将其显示给用户

The Error错误

I get the error below:我收到以下错误:

在此处输入图片说明

The Code编码

Below is my Cloud function code.下面是我的云函数代码。 I have tried multiple versions of this code, using the request library, https library, etc. No luck...No luck我已经尝试了此代码的多个版本,使用request库、 https库等。没有运气...没有运气

    const {dialogflow, Suggestions,SimpleResponse,Permission} = require('actions-on-google')  
    const functions = require('firebase-functions'); 
    const geocoder = require('geocoder');

    const app = dialogflow({ debug: true });

    app.middleware((conv) => {
        conv.hasScreen =
            conv.surface.capabilities.has('actions.capability.SCREEN_OUTPUT');
        conv.hasAudioPlayback =
            conv.surface.capabilities.has('actions.capability.AUDIO_OUTPUT');
    });

    function requestPermission(conv) {
        conv.ask(new Permission({
            context: 'To know who and where you are',
            permissions: ['NAME','DEVICE_PRECISE_LOCATION']
        }));
    }

    function userInfo ( conv, params, granted) {

        if (!conv.arguments.get('PERMISSION')) {

            // Note: Currently, precise locaton only returns lat/lng coordinates on phones and lat/lng coordinates 
            // and a geocoded address on voice-activated speakers. 
            // Coarse location only works on voice-activated speakers.
            conv.ask(new SimpleResponse({
                speech:'Sorry, I could not find you',
                text: 'Sorry, I could not find you'
            }))
            conv.ask(new Suggestions(['Locate Me', 'Back to Menu',' Quit']))
        }

        if (conv.arguments.get('PERMISSION')) {

            const permission = conv.arguments.get('PERMISSION'); // also retrievable with explicit arguments.get
            console.log('User: ' + conv.user)
            console.log('PERMISSION: ' + permission)
            const location = conv.device.location.coordinates
            console.log('Location ' + JSON.stringify(location))

            // Reverse Geocoding
            geocoder.reverseGeocode(location.latitude,location.longitude,(err,data) => {
                if (err) {
                    console.log(err)
                }


                // console.log('geocoded: ' + JSON.stringify(data))
                console.log('geocoded: ' + JSON.stringify(data.results[0].formatted_address))
                conv.ask(new SimpleResponse({
                    speech:'You currently at ' + data.results[0].formatted_address + '. What would you like to do now?',
                    text: 'You currently at ' + data.results[0].formatted_address + '.'
                }))
                conv.ask(new Suggestions(['Back to Menu', 'Learn More', 'Quit']))

            })

        }

    }


    app.intent('Request Permission', requestPermission);
    app.intent('User Info', userInfo);

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

Any help is very much appreciated.很感谢任何形式的帮助。 Thanks谢谢

You're right on your last guess - your problem is that you're not using Promises.你最后的猜测是对的 - 你的问题是你没有使用 Promises。

app.intent() expects the handler function ( userInfo in your case) to return a Promise if it is using async calls. app.intent()期望处理函数(在您的情况下为userInfo在使用异步调用时返回一个 Promise。 (If you're not, you can get away with returning nothing.) (如果你不是,你可以不返回任何东西。)

The normal course of action is to use something that returns a Promise.正常的操作过程是使用返回 Promise 的东西。 However, this is tricky in your case since the geocode library hasn't been updated to use Promises, and you have other code that in the userInfo function that doesn't return anything.但是,这在您的情况下很棘手,因为地理编码库尚未更新为使用 Promises,并且您在userInfo函数中还有其他不返回任何内容的代码。

A rewrite in this case might look something like this (I haven't tested the code, however).在这种情况下,重写可能看起来像这样(但是,我还没有测试过代码)。 In it, I break up the two conditions in userInfo into two other functions so one can return a Promise.在其中,我将userInfo的两个条件分解为另外两个函数,以便可以返回一个 Promise。

function userInfoNotFound( conv, params, granted ){
  // Note: Currently, precise locaton only returns lat/lng coordinates on phones and lat/lng coordinates 
  // and a geocoded address on voice-activated speakers. 
  // Coarse location only works on voice-activated speakers.
  conv.ask(new SimpleResponse({
    speech:'Sorry, I could not find you',
    text: 'Sorry, I could not find you'
  }))
  conv.ask(new Suggestions(['Locate Me', 'Back to Menu',' Quit']))
}

function userInfoFound( conv, params, granted ){
  const permission = conv.arguments.get('PERMISSION'); // also retrievable with explicit arguments.get
  console.log('User: ' + conv.user)
  console.log('PERMISSION: ' + permission)
  const location = conv.device.location.coordinates
  console.log('Location ' + JSON.stringify(location))

  return new Promise( function( resolve, reject ){
    // Reverse Geocoding
    geocoder.reverseGeocode(location.latitude,location.longitude,(err,data) => {
      if (err) {
        console.log(err)
        reject( err );
      } else {
        // console.log('geocoded: ' + JSON.stringify(data))
        console.log('geocoded: ' + JSON.stringify(data.results[0].formatted_address))
        conv.ask(new SimpleResponse({
          speech:'You currently at ' + data.results[0].formatted_address + '. What would you like to do now?',
          text: 'You currently at ' + data.results[0].formatted_address + '.'
        }))
        conv.ask(new Suggestions(['Back to Menu', 'Learn More', 'Quit']))
        resolve()
      }
    })
  });

}

function userInfo ( conv, params, granted) {
  if (conv.arguments.get('PERMISSION')) {
    return userInfoFound( conv, params, granted );
  } else {
    return userInfoNotFound( conv, params, granted );
  }
}

Thanks to @Prisoner, I was able to make it work.感谢@Prisoner,我能够让它发挥作用。 i didn't have to modify my Dialogflow structure or anything.我不必修改我的 Dialogflow 结构或任何东西。 All I had to do was change the Reverse Geocoding section to what @Prisoner suggested.我所要做的就是将反向地理编码部分更改为@Prisoner 建议的内容。 And it worked for me.它对我有用。

//Reverse Geocoding

return new Promise( function( resolve, reject ){
    // Reverse Geocoding
    geocoder.reverseGeocode(location.latitude,location.longitude,(err,data) => {
      if (err) {
        console.log(err)
        reject( err );
      } else {
        // console.log('geocoded: ' + JSON.stringify(data))
        console.log('geocoded: ' + JSON.stringify(data.results[0].formatted_address))
        conv.ask(new SimpleResponse({
          speech:'You currently at ' + data.results[0].formatted_address + '. What would you like to do now?',
          text: 'You currently at ' + data.results[0].formatted_address + '.'
        }))
        conv.ask(new Suggestions(['Back to Menu', 'Learn More', 'Quit']))
        resolve()
      }
   })
});

I can now move on to other things!我现在可以继续做其他事情了!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 “尚未做出回应。 使用js的异步调用中没有使用它吗?” - “No response has been set. Is this being used in an async call that was not returned as a promise to the intent handler?” using js Google Cloud Functions 标头响应 - Google Cloud Functions Headers response 对Google Assistant使用Actions SDK - Use Actions SDK for Google Assistant 错误:尚未为上下文加载模块名称“@google-cloud/vision”:_。 使用 require([]) - Error: Module name "@google-cloud/vision" has not been loaded yet for context: _. Use require([]) 平台浏览器已经设置。 用 [object Object] 覆盖平台。 在电子应用程序中使用 tfjs-node 时 - Platform browser has already been set. Overwriting the platform with [object Object]. when using tfjs-node in electron app Google Cloud Functions - Nodejs 错误,永远加载 - Google Cloud Functions - Nodejs error , forever loading 使用谷歌云函数语法错误的问题 - issue with syntax error using google cloud functions 无法部署谷歌云功能(错误:ELIFECYCLE) - Cannot deploy google cloud functions (error: ELIFECYCLE) 我的一组函数执行完后该怎么办? - How to do something after my set of functions has been executed? 使用 Google Cloud Functions 抓取时 page.evaluate 不返回响应? - page.evaluate not returning response when scraping with Google Cloud Functions?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM