agent.add 不工作,而 console.log 是

agent.add not working while console.log is

我正在使用 Dialogflow 内联编辑器调用 API。当我使用 console.log 记录来自 API 的一些数据时,它起作用了。但是,当我将 agent.add 与相同的变量一起使用时,它会出错。

我阅读了一些关于此问题的其他计算器,其中人们使用了 promise 和 resolve 调用。我试图在我的代码中实现这一点。但是,我不确定我是否以正确的方式使用它。

这是我的代码:

'use strict';
const axios = require('axios');
 
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 randomHandler(agent){
    const regio = agent.parameters.regio;
    if (regio != "Alkmaar" && regio != "Schiphol"){
      agent.add(`Deze regio bestaat helaas niet binnen NH nieuws, kies een andere regio of kies voor het nieuws uit heel Noord-Holland`);
    } else {
        return axios.get(`https://api.datamuse.com/words?rel_rhy=book`)
    .then((result) => {
        
      result.data.map (res => {
        const dataArray = ""; // An array with the results. However we got it
        const words = dataArray.map( entry => entry.word );  // Get just the "word" field from each entry in the dataArray
        const wordsString = words.join(', ');   // Put commas in between each word
        agent.add( `The results are: ${wordsString}`);
      });
      });
    }
  }
  

  // Run the proper function handler based on the matched Dialogflow intent name
  let intentMap = new Map();
  intentMap.set('Default Welcome Intent', welcome);
  intentMap.set('Default Fallback Intent', fallback);
  intentMap.set('random', randomHandler);
  agent.handleRequest(intentMap);
});
    

这是我的 package.json:

{
  "name": "dialogflowFirebaseFulfillment",
  "description": "This is the default fulfillment for a Dialogflow agents using Cloud Functions for Firebase",
  "version": "0.0.1",
  "private": true,
  "license": "Apache Version 2.0",
  "author": "Google Inc.",
  "engines": {
    "node": "10"
  },
  "scripts": {
    "start": "firebase serve --only functions:dialogflowFirebaseFulfillment",
    "deploy": "firebase deploy --only functions:dialogflowFirebaseFulfillment"
  },
  "dependencies": {
    "actions-on-google": "^2.2.0",
    "firebase-admin": "^5.13.1",
    "firebase-functions": "^2.0.2",
    "dialogflow": "^0.6.0",
    "dialogflow-fulfillment": "^0.5.0",
    "axios" : "0.20.0"
  }
}



 

如您所料 - 问题出在 Promises 上。

rhymingWordHandler() 中有一个异步操作(使用 axios 的网络调用),但您没有 returning Promise。

幸运的是,axios.get()return一个承诺。你可以知道,因为你正在调用 .then() 什么是 returned,而 .then() return 是一个 Promise 等等.我喜欢这个作为“Promise-chain”。将其更改为 return 一个 Promise 相对简单:

return axios.get(`https://api.datamuse.com/words?rel_rhy=${word}`)
  .then( /* and so forth */ )

但是,您的代码还不够。您不需要在 .then() 函数中创建 Promise,这样做只会造成混淆。

请记住,Intent 名称区分大小写 - 您需要在 UI 和 intentMap.set() 中使用的名称中使用完全相同的大写字母。您目前在一个地方有“Rhymingword”,在另一个地方有“RhymingWord”(一个 W 大写,另一个不是)。

您可能还有一个小问题,您可能无法多次调用 agent.add(rhyme)。一些代理只能处理一个或两个文本响应。相反,您需要从结果数组构建响应字符串。

如何构建这样的字符串取决于您的具体内容。最简单的(虽然在语法上不正确)是在它们之间加上逗号。我经常分步进行,所以它可能看起来像这样:

  const dataArray = // An array with the results. However we got it
  const words = dataArray.map( entry => entry.word );  // Get just the "word" field from each entry in the dataArray
  const wordsString = words.join(', ');   // Put commas in between each word
  agent.add( `The results are: ${wordsString}`. );

这有很多问题,一个好的解决方案可以处理以下情况:

  • 没有结果怎么办?
  • 当只有一个词时,您是否应该在列表前使用不同的短语?
  • 如果有两个结果怎么办?
  • 您应该为三个或更多结果应用正确的 grammar/punctuation 规则。

但这应该是确保您只调用 agent.add() 一次的开始。

已解决,问题是我调用了 agent.add 超过 2 次(这是最大值)。此代码对我有用:

const { conversation } = require('@assistant/conversation');
const functions = require('firebase-functions');
const axios = require('axios').default;
const app = conversation();

var titels = [];

axios.get(`YOUR-API`)
  .then((result)=> {
    titels.push(result.data.categories[0].news[0].title);
    /* result.data.map(wordObj => {
      titels.push(wordObj.categories.news.title);
    });*/ 
  }); 
  
app.handle('rhymeHandler', conv => {
  console.log(titels[0]);
  conv.add(titels[0]); 
});

exports.ActionsOnGoogleFulfillment = functions.https.onRequest(app);    

/* for (i = 1; i < 4; i++) {
  conv.add(words[i]);
  } */
  //console.log(words);