получать данные json из базы данных в реальном времени во встроенный редактор Dialogflow (помощник Google) - PullRequest
0 голосов
/ 06 января 2019

Здесь я начинаю программировать, я работаю в свободное время над проектом, связанным с Google Assistant, впервые использую базу данных Firebase Realtime и не знаю, как получить данные оттуда. приведенный ниже код находится во встроенном редакторе Dialogflow, где 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

UPDATE Я использовал приведенный ниже код, например:

'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 голосов
/ 07 января 2019

Есть несколько вещей, которые вам нужно выучить.

Во-первых, как добавить Firebase Admin SDK в ваш проект.

Вам также необходимо научиться извлекать данные , используя библиотеку. Firebase использует метод, основанный на ссылочном пути, для извлечения данных, поэтому вам нужно убедиться, что вы правильно построили путь.

Наконец, поскольку вы делаете это в обработчике выполнения и делаете асинхронный вызов, вам необходимо убедиться, что вы возвращаете 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 ключом, который предоставит вам доступ через служебную учетную запись. Вы можете сгенерировать ключ и загрузить его, а затем указать папку, в которой вы его сохранили. (Похоже, вы только что внесли информацию, которая также работает.)

Ошибка «Неправильный ответ» означает, что ответ не был установлен. Это может быть связано с несколькими причинами, но обычно это означает, что ваша программа по какой-либо причине вызвала сбой или не смогла вызвать agent.add(). Обратитесь к журналам ваших действий для получения дополнительной информации. (Если вы используете встроенный редактор Dialogflow, вы можете перейти к журналам, выбрав https://console.firebase.google.com/,, выбрав свой проект, выбрав вкладку «Функции» слева и выбрав вкладку «Журналы».)

Обновление на основе кода и сообщения об ошибке.

Как следует из сообщения об ошибке, вы звонили admin.initializeApp() более одного раза. Это следует делать только при первой настройке функции, а не каждый раз, когда вызывается ваша функция. После однократной инициализации - его можно использовать несколько раз.

В вашем случае это можно сделать, переместив require, который импортирует firebase-admin и вызов admin.initializeApp(), из функции personFacts() и поместите их обоих ближе к вершине - вероятно, сразу после другого require() звонки.

...