错误:未设置响应.用于 Google 助理操作的 Cloud Functions [英] Error: No response has been set. Cloud Functions for Actions on Google Assistant

查看:27
本文介绍了错误:未设置响应.用于 Google 助理操作的 Cloud Functions的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 DialogflowCloud Functions 和新的 NodeJS 客户端 为 Google Home 构建 Assistant 应用> Actions on Google 库 V2.事实上,我正在将使用 V1 构建的旧代码迁移到 V2.

I am building an Assistant app for Google Home, using Dialogflow, Cloud Functions and the new 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.

背景

我正在尝试使用两个单独的意图获取用户的位置:Request Permission(触发/向用户发送权限请求的意图)和 User Info(意图检查用户是否授予权限,然后返回助手请求的数据以继续.

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.

问题

问题在于,在 V1 上运行良好的代码在 V2 上却无法运行.所以我不得不做一些重构.当我部署我的云功能时,我能够成功地请求用户的许可,获取他的位置,然后使用外部库(geocode),我可以将 latlong 转换为人类可读的形式.但由于某些原因(我认为它的承诺)我无法解析承诺对象并将其展示给用户

The problem is that the same code that was working just fine on V1 isn't working on 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. but for some reasons (I think its promises) I can't resolve the promise object and show it to the user

错误

我收到以下错误:

守则

下面是我的云功能代码.我已经尝试了此代码的多个版本,使用 request 库、https 库等.没有运气...没有运气

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

    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

推荐答案

你猜对了——你的问题是你没有使用 Promises.

You're right on your last guess - your problem is that you're not using Promises.

app.intent() 期望处理函数(在您的情况下为 userInfo)在使用异步调用时返回 Promise.(如果你不是,你可以不返回任何东西.)

app.intent() expects the handler function (userInfo in your case) to return a Promise if it is using async calls. (If you're not, you can get away with returning nothing.)

正常的做法是使用返回 Promise 的东西.但是,这在您的情况下很棘手,因为地理编码库尚未更新为使用 Promises,并且您在 userInfo 函数中有其他代码不返回任何内容.

The normal course of action is to use something that returns a 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.

这种情况下的重写可能看起来像这样(不过我还没有测试过代码).在其中,我将 userInfo 中的两个条件分解为另外两个函数,这样一个函数就可以返回一个 Promise.

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.

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 );
  }
}

这篇关于错误:未设置响应.用于 Google 助理操作的 Cloud Functions的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆