### Dialogflow代理获取并告知MySQL数据库数据

首先,非常感谢这个出色的社区。我必须说我对编程非常新手(我更像是一名统计学家),但到目前为止,这似乎既具有挑战性又有趣!最近,我一直在挑战自己,尝试创建一个从数据库中检索数据的Dialogflow代理。我使用的是Node.js。当然,为了构建,我尝试在网上查看代码,并根据我的需求进行连贯的修改,但三天以来我一直卡住了!

我搞不清楚问题出在哪里,请帮帮我!!!

请查看下面的代码:

'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 URLsconst 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()实际调用数据库,并可能处理和返回一个Promise,包含结果供调用方法格式化为用户希望听到/看到的内容。

说到Promise,callDB()返回一个Promise是好的。然而,你在两个方面没有正确处理这个Promise:

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

return callDB().then( output => {  // 输出一切正常。}).catch( err => {  // 输出世界末日。};

处理Promise的第二个问题是,你当前的getInfo()实现在这个块之后还有代码。这里是你进行所有agent.setContext()agent.add()调用的地方。这些必须then()块内。(在我的“一切正常”评论上方的地方。)

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注