错误:未设置响应。 Google智能助理上的操作的云功能

时间:2018-04-18 21:42:36

标签: javascript node.js asynchronous google-cloud-functions actions-on-google

我正在使用 Dialogflow 云功能和新的 NodeJS客户端智能助理应用>图书馆V2用于 Google上的操作。事实上,我正在将使用V1构建的旧代码迁移到V2。

上下文

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

问题

问题是在V1上工作正常的相同代码并不适用于V2。所以我不得不做一些重构。当我部署我的云功能时,我能够成功请求用户的权限,获取他的位置,然后使用外部库(User Info),我可以将latlong转换为人类可读的形式。但由于某些原因(我认为它的承诺),我无法解决承诺对象并将其显示给用户

错误

我收到以下错误:

enter image description here

守则

以下是我的云功能代码。我已经尝试了这个代码的多个版本,使用geocode库,request库等。没有运气......没有运气

https

非常感谢任何帮助。感谢

2 个答案:

答案 0 :(得分:10)

你的最后一次猜测是正确的 - 你的问题是你没有使用Promises。

app.intent()期望处理程序函数(在您的情况下为userInfo)如果使用异步调用则返回Promise。 (如果你不是,你就可以逃避任何回报。)

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

在这种情况下重写可能看起来像这样(但我没有测试过代码)。在其中,我将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 );
  }
}

答案 1 :(得分:2)

感谢@Prisoner,我能够让它发挥作用。我没有必要修改我的Dialogflow结构或任何东西。我所要做的就是将反向地理编码部分改为@Prison建议的部分。它对我有用。

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

我现在可以转向其他事情了!