web-dev-qa-db-ja.com

エラー:応答が設定されていません。 Googleアシスタントでのアクションのためのクラウド機能

DialogflowCloud Functionsを使用して、Google Home用のアシスタントアプリを構築しています)および新しいNodeJS ClientLibrary V2 forActions on Google。実際、私はV1で構築された古いコードをV2に移行している最中です。

コンテキスト

2つの別々のインテントを使用してユーザーの場所を取得しようとしています:Request Permission(ユーザーに許可要求をトリガー/送信するインテント)およびUser Info(ユーザーが権限を付与したかどうかを確認し、続行するためにアシスタントから要求されたデータを返すインテント。

問題

問題は、V1で正常に機能していた同じコードがV2で機能しないことです。そのため、リファクタリングを行う必要がありました。そして、クラウド関数をデプロイすると、ユーザーの許可を正常に要求し、ユーザーの場所を取得してから、外部ライブラリ(geocode)を使用して、latlongを人間が読める形式に変換できます。しかし、いくつかの理由で(私はその約束だと思います)約束オブジェクトを解決してユーザーに表示することができません

エラー

以下のエラーが発生します:

enter image description here

コード

以下は私のクラウド機能コードです。 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);

どんな助けでも大歓迎です。ありがとう

8
AllJs

あなたはあなたの最後の推測に正しいです-あなたの問題はあなたがPromisesを使用していないということです。

app.intent()は、ハンドラー関数(この場合はuserInfo)が非同期呼び出しを使用している場合にPromiseを返すことを期待しています。 (そうでない場合は、何も返さずに逃げることができます。)

通常の行動方針は、約束を返すものを使用することです。ただし、ジオコードライブラリがPromisesを使用するように更新されておらず、userInfo関数に何も返さない他のコードがあるため、これは注意が必要です。

この場合の書き直しは次のようになります(ただし、コードはテストしていません)。その中で、userInfoの2つの条件を他の2つの関数に分割して、1つが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 );
  }
}
10
Prisoner

@Prisonerのおかげで、私はそれを機能させることができました。 Dialogflowの構造などを変更する必要はありませんでした。私がしなければならなかったのは、逆ジオコーディングのセクションを@Prisonerが提案したものに変更することだけでした。そしてそれは私のために働いた。

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

これで他のことに移ることができます!

3
AllJs