从实时数据库获取JSON数据到Dialogflow内联编辑器(Google助手)

时间:2019-01-06 12:05:57

标签: node.js json firebase dialogflow actions-on-google

这里是编程的入门者,我正在从事与Google Assistant相关的项目的业余时间,这是我第一次使用Firebase Realtime数据库,却不知道如何从那里获取数据,下面的代码在Dialogflow的内联编辑器中,其中group1中的person1 2和3(组)是具有学分的学生。我进行了一些更改,并将这三个(person1 2和3)放在下面的数据库图片中,我想从代码中删除这三个组并将其替换为实时数据库中的那些。

因为这是我第一次使用该数据库,所以我不知道如何使用nodejs从那里获取数据。

'use strict';
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements 
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
  const agent = new WebhookClient({ request, response });
  console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
  console.log('Dialogflow Request body: ' + JSON.stringify(request.body)); 
  function welcome(agent) {
    agent.add(`Welcome to my agent!`);
  } 
  function fallback(agent) {
    agent.add(`I didn't understand`);
    agent.add(`I'm sorry, can you try again?`);
  }
      function personFacts(agent) {
        const persons =  {
          person1: {"Alex" : 25, "Jennifer" : 45, "Justin" : 35, "Peter" : 89},
          person2: {"Alex" : 95, "Jennifer" : 75, "Justin" : 85, "Peter" : 59},
          person3: {"Alex" : 67, "Jennifer" : 55, "Justin" : 45, "Peter" : 15},
        };
        const personId = agent.parameters["personId"];
        const personMeasurement = agent.parameters["personMeasurement"];        
        const person = persons[personId];
        const result = person[personMeasurement];       
        agent.add(`${personId}'s ${personMeasurement} is ${result}`); 
      }

      let intentMap = new Map();
      intentMap.set('Default Welcome Intent', welcome);
      intentMap.set('Default Fallback Intent', fallback);
      intentMap.set('person', personFacts);
      agent.handleRequest(intentMap);
    });

enter image description here

更新 我使用了下面的代码,如下所示:

'use strict';
const functions = require( 'firebase-functions' );
const {WebhookClient} = require( 'dialogflow-fulfillment' );
const {Card, Suggestion} = require( 'dialogflow-fulfillment' );
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
exports.dialogflowFirebaseFulfillment = functions.https.onRequest( ( request, response ) =>{
  const agent = new WebhookClient( {request, response} );
  console.log( 'Dialogflow Request headers: ' + JSON.stringify( request.headers ) );
  console.log( 'Dialogflow Request body: ' + JSON.stringify( request.body ) );

  function welcome( agent ){
    agent.add( `Welcome to my agent!` );
  }

  function fallback( agent ){
    agent.add( `I didn't understand` );
    agent.add( `I'm sorry, can you try again?` );
  }

  function personFacts( agent ){
    const personId = agent.parameters["personId"];
    const personMeasurement = agent.parameters["personMeasurement"];
    var admin = require( 'firebase-admin' );
    admin.initializeApp( {
      credential: admin.credential.cert( {
        projectId: ' ',
        clientEmail: ' ',
        privateKey: ' '
      } ),
      databaseURL: 'https://*****.firebaseio.com'
    } );
    var db = admin.database();
    var ref = db.ref( `person/${personId}/${personMeasurement}` );
    return ref.once( "value" ).then( snapshot =>{
      var result = snapshot.value();
      agent.add( `${personId}'s ${personMeasurement} is ${result}` );
    } )
      .catch( err =>{
        agent.add( 'uh oh, something went wrong.' );
        console.error( err );
      } );
  }

  let intentMap = new Map();
  intentMap.set( 'Default Welcome Intent', welcome );
  intentMap.set( 'Default Fallback Intent', fallback );
  intentMap.set( 'factory', factoryFacts );
  agent.handleRequest( intentMap );
} );
收到错误消息:'MalformedResponse 由于语音响应为空,无法将Dialogflow响应解析为AppResponse。日志错误:

{
 insertId:  "v*****2"  
 labels: {
  channel:  "preview"   
  querystream:  "GOOGLE_USER"   
  source:  "JSON_RESPONSE_VALIDATION"   
 }
 logName:  "projects/****/logs/actions.googleapis.com%2Factions"  
 receiveTimestamp:  "2019-01-07T14:45:29.274840871Z"  
 resource: {
  labels: {
   action_id:  "actions.intent.TEXT"    
   project_id:  "******"    
   version_id:  ""    
  }
  type:  "assistant_action"   
 }
 severity:  "ERROR"  
 textPayload:  "MalformedResponse: Failed to parse Dialogflow response into AppResponse because of empty speech response"  
 timestamp:  "2019-01-07T14:45:29.266062732Z"  
 trace:  "projects/383182941858/traces/ABwppHFK_PehMj1XEs_Arng9VL7_zShy-EWvoziK0Ro6v74TaduNG1cJaRMnGAZMoLZhtILdG2hEBkDvJQ"  
}

这是日志中的错误:

Error: The default Firebase app already exists. This means you called initializeApp() more than once without providing an app name as the second argument. In most cases you only need to call initializeApp() once. But if you do want to initialize multiple apps, pass a second argument to initializeApp() to give each app a unique name. 
at FirebaseAppError.Error (native) 
at FirebaseAppError.FirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:39:28) 
at FirebaseAppError.PrefixedFirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:85:28) 
at new FirebaseAppError (/user_code/node_modules/firebase-admin/lib/utils/error.js:119:28) 
at FirebaseNamespaceInternals.initializeApp (/user_code/node_modules/firebase-admin/lib/firebase-namespace.js:68:23) 
at FirebaseNamespace.initializeApp (/user_code/node_modules/firebase-admin/lib/firebase-namespace.js:362:30) 
at personFacts (/user_code/index.js:34:11) 
at WebhookClient.handleRequest (/user_code/node_modules/dialogflow-fulfillment/src/dialogflow-fulfillment.js:303:44) 
at exports.dialogflowFirebaseFulfillment.functions.https.onRequest (/user_code/index.js:91:9) 
at cloudFunction (/user_code/node_modules/firebase-functions/lib/providers/https.js:57:9)

1 个答案:

答案 0 :(得分:0)

您需要学习几件事。

第一个是如何add the Firebase Admin SDK进入您的项目。

您还需要学习如何retrieve the data使用该库。 Firebase使用基于引用路径的方法来获取数据,因此您需要确保正确构建路径。

最后,由于要在履行处理程序中执行此操作,并且要进行异步调用,因此需要确保返回Promise。幸运的是,获取数据还涉及返回一个Promise,因此您可以返回此Promise。

部分代码可能看起来像这样(未经测试):

  function personFacts(agent) {
    const personId = agent.parameters["personId"];
    const personMeasurement = agent.parameters["personMeasurement"];        

    var db = admin.database();
    var ref = db.ref(`person/${personId}/${personMeasurement}`);
    return ref.once("value")
      .then( snapshot => {
        var result = snapshot.val();
        agent.add(`${personId}'s ${personMeasurement} is ${result}`); 
      })
      .catch( err => {
        agent.add('uh oh, something went wrong.');
        console.error( err );
      });

  }

如前所述,您需要使用一个密钥来初始化Firebase管理库,该密钥将使您可以通过服务帐户进行访问。您可以generate the key并下载它,然后指向保存它的文件夹。 (看来您刚刚插入了信息,这也起作用。)

“格式错误的响应”错误表示未设置任何响应。这可能是由于多种原因造成的,但是通常意味着您的程序由于某种原因而崩溃或无法调用agent.add()。有关更多信息,请查阅运行操作的日志。 (如果使用的是Dialogflow内联编辑器,则可以转到https://console.firebase.google.com/,选择项目,选择左侧的“功能”标签,然后选择“日志”标签,以获取日志。)

更新基于代码和错误消息。

如错误消息所示,您多次致电admin.initializeApp()。仅应在首次配置该功能时执行此操作,而不是在每次调用该功能时执行此操作。初始化一次-可以多次使用。

对于您而言,这可以通过将导入firebase-admin的require和对admin.initializeApp()的调用移出personFacts()函数,并将它们都移到顶部来完成。 -可能紧接其他require()个电话之后。