错误:未设置响应。 Google智能助理上的操作的云功能 [英] Error: No response has been set. Cloud Functions for Actions on Google Assistant

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

问题描述

我正在使用 Dialogflow 云功能和新的 NodeJS客户端智能助理应用>图书馆V2用于 Google上的操作。事实上,我正在将使用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.

上下文

我试图用两个单独的位置获取用户的位置意图:请求权限(触发/向用户发送权限请求的意图)和用户信息(检查是否有意图)用户授予权限,然后返回助理请求的数据以继续。

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

错误

我收到以下错误:

代码

以下是我的云功能代码。我已经尝试了这个代码的多个版本,使用请求库, 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 ) case)如果使用异步调用则返回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智能助理上的操作的云功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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