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);
我正在使用 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);