ホーム>source

DialogFlow で簡単なチャットボットを構築しようとしています 。

私の目的は、次のようなユーザーの質問から情報を提供することです。 2つのパラメーター( croatiawaterline )およびスラックラインの場所のリスト。

そのため、パラメーターから情報を取得するデータベースが必要です。 DialogFlowは Firebase でのフルフィルメントを許可します 。場所(名前、国、スラックの種類)でデータベースを構築し、 webhook を有効にします  私の意図を求めます。

インラインエディターを使用してindex.js

const parameters = request.body.queryResult.parameters;
var country = parameters.country.toString();
function show(snap) {
   console.log('snap');
   agent.add(JSON.stringify(snap.val(),null,2));
}
function slkplc(agent) {
     var testRef;
     firebase.database().ref('slackplace').once('value',show);
}
// Run the proper function handler based on the matched Dialogflow intent name
let intentMap = new Map();
intentMap.set('slack place', slkplc);
agent.handleRequest(intentMap);

しかし、DialogFlowまたはGoogle Assistantで試してみると、期待した結果が得られません。関数showは非同期に呼び出されますが、遅すぎて、応答が利用できませんDialogFlow :

この問題に対処する3つの方法があります。

  1. データベースへのブロック呼び出しを使用:別のデータベース?
  2. DialogFlowで非同期メッセージを処理する???
  3. エラーが発生したというユーザーへの応答。

3番目に選択したものですが、常にエラーが発生しています。

データベース応答からのデータを待機するためにいくつかのことを試みた後、私が管理した唯一のことは、応答をフリーズすることです。したがって、DialogFlow-5s-およびFirebase-60s-のタイムアウトに達しました。

回避策

もう1つの方法は、DialogFlowからデータベースの取得と要求/応答を分離することです。データベースのデータは dialogflowFirebaseFulfillment の外部で収集されます

var data;
var inidata = firebase.database().ref().on('value',function(snap) {
     console.log('snap');
     data = snap.val();
 });
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
 const agent = new WebhookClient({ request, response });
 ...
 function slkplc(agent) {
     agent.add(JSON.stringify(data,null,2));
 }
  // Run the proper function handler based on the matched Dialogflow intent name
  let intentMap = new Map();
  intentMap.set('slack place', slkplc);
  agent.handleRequest(intentMap);
}

これで、データを使用して必要なことができるようになり、クロアチアで喫水線を練習できる場所を見つけることができました。しかし、常に奇妙な何かがあり、データベースのデータが複製されています...

あなたの答え
  • 解決した方法 # 1

    「正しい」解決策は、提案するオプション2です。非同期呼び出しを行っているため、dialogflow-fulfillmentライブラリを使用する場合は、これを正しく処理する必要があります。

    基本的に、ハンドラーが非同期呼び出しを行う場合、同様に非同期である必要があります。 handleRequest() に示すため  ハンドラが非同期であるメソッドの場合、Promiseオブジェクトを返す必要があります。

    Firebaseの once()  メソッドは、コールバック関数を渡さないとPromiseを返します。これを利用できますが、その約束を返す、また、 .then() の一部としてあなたがやりたいことを処理します  句。次のようになります。

    function slkplc(agent) {
      var testRef;
      return firebase.database().ref('slackplace').once('value')
        .then( snap => {
          var val = snap.val();
          return agent.add( JSON.stringify( val, null, 2 ) );
        });
    }
    
    

    重要な部分は、Promiseを使用するだけでなく、そのPromiseを返すことでもあります。

  • 前へ java - JPAクエリ:サブクエリをグループ化条件に結合する
  • 次へ java - データセットを含むオブジェクトをシリアル化します