Dialogflow 代理获取并告知 mysql 数据库的数据

Dailogflow agent gets and tells data of mysql database

首先非常感谢这个很棒的社区。 我不得不说我对编程很陌生(我更像是一名统计学家)但到目前为止它似乎非常具有挑战性和乐趣! 最近,我一直在挑战自己,尝试创建 Dialogflow 代理,以便在被询问时从数据库中检索数据。我正在使用 node.js。 当然,为了构建我试图在互联网上查看代码并根据我的需要连贯地修改它们但是三天以来我被卡住了!

我不知道是什么问题,请帮忙!!!1

在我的代码下方找到:

'use strict';

const functions = require( 'firebase-functions' );
const mysql = require( 'mysql' );
const {WebhookClient} = require( 'dialogflow-fulfillment' );
const {Text, Card, Image, Suggestion, Payload} = require( 'dialogflow-fulfillment' );

process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements

// Wikipedia link and image URLs
const mysiteurl = 'site URL';


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 infohub personal assistant, my name is Isobel` );
    agent.add( new Card( {
        title: `mysite`,
        imageUrl: mysiteurl,
        text: `Did you know already mysite if not visit it now! `,
        buttonText: 'mysite',
        buttonUrl: mysiteurl
      } )
    );
    agent.add( `I can help you get information already contained in mysite` );
    agent.add( new Suggestion( `population` ) );
    agent.add( new Suggestion( `avgincome` ) );
    agent.add( new Suggestion( `thisyeargdp` ) );
  }

  function getinfo( agent ){
    // Get parameters from Dialogflow to convert
    const country = agent.parameters.country;
    const info = agent.parameters.info;
    console.log( `User requested to get info on  ${info} in ${country}` );


    if( action === 'get.data' ){

      //Call the callDBJokes method
      output = callDB().then( ( output ) =>{
        // Return the results of the weather API to API.AI
        response.setHeader( 'Content-Type', 'application/json' );
        response.send( JSON.stringify( output ) );
      } ).catch( ( error ) =>{
        // If there is an error let the user know
        response.setHeader( 'Content-Type', 'application/json' );
        response.send( JSON.stringify( error ) );
      } );

    }


    // Sent the context to store the parameter information
    // and make sure the followup 
    agent.setContext( {
      name: 'info',
      lifespan: 1,
      parameters: {country: country, info: info}
    } );

    // Compile and send response
    agent.add( ` ${info} in ${country} is ${output}` );

    agent.add( `Would you like to know something else?` );
    agent.add( new Suggestion( `population` ) );
    agent.add( new Suggestion( `avgincome` ) );
    agent.add( new Suggestion( `thisyeargdp` ) );
  }


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

  function callDB( info, country ){
    return new Promise( ( resolve, reject ) =>{

        try{

          var connection = mysql.createConnection( {
            host: "sql7.freemysqlhosting.net",
            user: "sql7243950",
            password: "XXXXXXXX",
            database: "sql7243950"
          } );


          connection.query( 'SELECT' + info + 'FROM mocktable WHERE country=' + country, function( error, results, fields ){
            if( !error ){

              let response = "The solution is: " + results[0];
              response = response.toString();
              let output = {'speech': response, 'displayText': response};
              console.log( output );
              resolve( output );

            } else{

              let output = {
                'speech': 'Error. Query Failed.',
                'displayText': 'Error. Query Failed.'
              };
              console.log( output );
              reject( output );

            }
          } );
          connection.end();

        } catch
          ( err ){
          let output = {
            'speech': 'try-cacth block error',
            'displayText': 'try-cacth block error'
          };
          console.log( output );
          reject( output );

        }

      }
    )
      ;
  }


  let intentMap = new Map(); // Map functions to Dialogflow intent names
  intentMap.set( 'Default Welcome Intent', welcome );
  intentMap.set( 'get info about mycountry', getinfo );
  intentMap.set( 'Default Fallback Intent', fallback );
  agent.handleRequest( intentMap );
} )
;

这里有一些问题,有些相关,有些无关。让我们来看看其中的一些。

对于初学者,你有一个比较

if( action === 'get.data' ){

但 'action' 未在任何地方定义或分配。所以这个块将永远不会被执行(并且永远不会调用数据库,它看起来像)。

不清楚您是如何完成某些作业的。当您获得查询的输出时,您的行是

output = callDB().then( ( output ) =>{

这似乎混合了取回 Promise 和尝试使用 Promise 完成的结果。我怀疑第二个 "output" 是你想要的而不是第一个,原因我希望稍后会更清楚一些。

在那个 then() 子句中,您要发回 JSON,但随后(在 then() 子句之外)尝试使用 Dialogflow 库设置上下文,设置回复,提供建议筹码。混合使用这两种方法不起作用 - 发送 JSON 或使用库。

这是复合的,因为 callDB()(您在 then() 之前调用)生成要发回的 JSON。再次 - 选择一种方法或另一种方法。我怀疑更好的方法是让 callDB() 实际调用数据库并可能进行按摩,并且 return 一个 Promise 将调用方法的结果格式化为您希望用户使用的格式 hear/see .

说到 Promise,很好 callDB() return 是一个 Promise。但是,您没有以两种方式正确对待该承诺:

首先,由于 getInfo() 异步调用 运行 的东西(即 - 对 callDB() 的调用)它也必须 return 一个 Promise。这就是为什么您可能不想像我上面提到的那样从 callDB() 捕获结果。最简单的方法是让您的代码执行类似

的操作
return callDB().then( output => {
  // Output things are fine.
}).catch( err => {
  // Output the world is ending.
};

关于您如何处理 Promises 的第二个问题是,您当前的 getInfo() 实现在这个块 之后有代码。目前,这是您执行所有 agent.setContext()agent.add() 调用的地方。那些 必须 then() 块内。 (上面是我的 "things are fine" 评论。)