作者:黑铁1988 | 来源:互联网 | 2023-08-13 16:44
我是dialogflow和Javascript的新手,所以我真的不熟悉如何实现dialogflow的代码
这是我的if语句,用于检查用户参数是否与firebase中的值匹配,但是不起作用,并且触发了回退意图。情况是
如果答案= firebase值,则漫游器会回答它是正确的,添加分数并询问下一个问题。
function q1correct(agent){
const q1snapshot = admin.database().ref('quizanswers/q1').once('value');
if(q1snapshot.val() == agent.parameters.pikachu){
agent.add(`That's correct!`);
score = score + 1;
return admin.database().ref('quizquestions').once('value').then((snapshot) =>{
const value = snapshot.child('q2').val();
agent.add(`${value}`);
});
}
else{
agent.add(`Sadly,that is incorrect.`);
score = score;
return admin.database().ref('quizquestions').once('value').then((snapshot) =>{
const value = snapshot.child('q2').val();
agent.add(`${value}`);
});
}
}
if语句不起作用
如此处所示,我没有培训用语,因为如果数据库中的答案有变化,我可以让它动态化,这是不可能的吗?我需要训练短语吗?
听起来您在这里有两个不同的问题-一个与您期望Dialogflow如何检测Intents有关,另一个与您期望Firebase如何获取值有关。
对话流和检测意图
Dialogflow的目的是获取用户的短语,并通过将其与许多可能的语句进行匹配来确定其广泛的意图。这样,您就可以创建一个Intent,例如,用户可以说“是”,“确定”,“当然”或其他变体,而您的代码只需用一种方式处理它们即可。
有时我们会在答复中回答一个短语,但是该短语中的某些值会有所不同,因此我们可以设置参数。如果这些参数可以来自一组固定的值(或这些值的同义词),我们可以将它们设置为Entities。 Dialogflow定义了一些实体类型,我们可以定义自己的自定义类型。
如果您的问题需要多项选择答案,您甚至可以创建Session Entity,其中包含针对下一个问题的可能答案。这样,您将知道他们是否回答了您期望的事情,或者他们没有尝试。
如果您希望获得开放式答案,事情将变得更加困难。由于Dialogflow在用户回复时不知道任何模式,因此通常会以Fallback Intent结束。这是一个特殊的Intent,可与“所有其他不匹配的内容”匹配,通常用于用户说完全出乎意料的情况-尽管它可以用来收集自由格式的答案。
所有这一切发生在之前中,如果对您编写的实现网络挂钩中的语句进行了评估。一旦检测到一个Intent(或还原为选择“ Fallback Intent”),它将将该Intent,检测到的所有参数以及完整的短语发送到您的Webhook。
更新
请注意,您根本没有为自己的意图设置任何训练短语。如果您没有任何Events(在这种情况下您可能不想要),那么Dialogflow最终将永远无法匹配此Intent。
在这种情况下,该参数无关紧要。参数是词组中的占位符,当用户输入时,这些参数将被用词组的那部分填充。
您可以创建具有输入上下文的后备意图。仅当当前没有其他意图匹配和输入上下文部分中列出的所有 all 活动处于活动状态时,这才会触发回退意图。这将提供用户的整个短语,您可以在此后备意图的处理程序中的比较中使用该短语。
但是,这可能不是一个好主意。不提供培训短语和实体可能会使对话变得更加枯燥。听起来您可以为所有可能的宠物小精灵(例如@pokemon)创建一个Entity,并创建您的训练短语以接受以下内容:
这样Dialogflow可以将所有这些短语匹配到相同的Intent,而只需向您报告“皮卡丘”作为参数即可。
从Firebase获取价值
对于Firebase数据库,通过对数据库中的记录进行引用来获取值,然后使用once()
来获取该记录。 (您也可以使用on()
订阅记录的更新,但这对您来说是不必要的。)
创建引用是本地操作,因此它会立即返回。但是,获取值是异步操作的,因此您需要使用Promise,该Promise仅在网络操作完成时才能解决。对于足够现代的node版本(应该使用),可以使用async / await。
在if
测试中,您正在根据引用而不是 value 检查用户的值。要检查该值,您可能需要在异步函数中进行更多类似的操作(未经测试):
const db = admin.database();
const q1snapshot = await db.ref('quizanswers/q1').once('value');
if( q1snapshot.val() === agent.parameters.pikachu ){
// They got it right. Fetch and ask the next question
const q2snapshot = await db.ref('quizquestions/q2').once('value');
agent.add(q2snapshot.val());
} else {
// They got it wrong. Say so.
agent.add( "That isn't correct. Please try again." );
}
更新根据您更新的代码,并说您正在使用Dialogflow内联编辑器。
内联编辑器仍(显然)仍在使用节点6,该节点不支持异步/等待。如果您不使用async / await,则需要使用Promises(Node 6确实支持)。
所以你的台词
const q1snapshot = admin.database().ref('quizanswers/q1').once('value');
if(q1snapshot.val() == agent.parameters.pikachu){
最后仍然是不正确的,因为q1snapshot
被分配了一个Promise,并且根本不是结果的快照。因此,尝试将Promise的val()
与参数进行比较将无法正常工作。
您最好的选择是升级到现代Node引擎。您将编辑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": "8"
},"scripts": {
...
},"dependencies": {
...
}
}
此显示将其设置为Node8。您可能希望考虑使用Node 10,尽管Firebase的Cloud Functions中仍支持beta 10。
如果在Dialogflow中使用内联编辑器,则要进行此更改,您需要选择编辑器中的(package.json)选项卡:
,
@囚犯
我想到了你说的话,因此改变了我的意图
My intent
然后,我在实现中使用了这些代码,并将其映射到此意图,以针对实时数据库检查用户参数
const q1snapshot = admin.database().ref('quizanswers/q1').once('value');
if(q1snapshot.val() === agent.parameters.pikachu){
agent.add(
是正确的!);
score = score + 1;
return admin.database().ref('quizquestions').once('value').then((snapshot) =>{
const value = snapshot.child('q2').val();
agent.add(
$ {value} );
});
But it does not check still,this is what i get in my telegram bot
这是原始的api响应,
{“ responseId”:“ 6371e43d-4d2a-428d-9b40-6c224ec7a21e-b4ef8d5f”,
“ queryResult”:{
“ queryText”:“皮卡丘”,
“参数”:{
“皮卡丘”:“皮卡丘”
}
"allRequiredParamsPresent": true,"outputContexts": [
{
"name": "projects/physicstutor-ydlgsm/agent/sessions/75bb149e-9803-1c15-4cfb-6689ad5e3a79/contexts/awaitans2","lifespanCount": 1,"parameters": {
"pikachu": "pikachu","pikachu.original": "pikachu"
}
}
],"intent": {
"name": "projects/physicstutor-ydlgsm/agent/intents/f0313e22-6794-475b-ac11-279866ee5317","displayName": "qStartcorrect"
},"intentDetectionConfidence": 0.3,"diagnosticInfo": {
"webhook_latency_ms": 128
},"languageCode": "en"
"webhookStatus": {
"code": 14,"message": "Webhook call failed. Error: UNAVAILABLE."
},"alternativeQueryResults": [
{
"queryText": "pikachu","outputContexts": [
{
"name": "projects/physicstutor-ydlgsm/agent/sessions/75bb149e-9803-1c15-4cfb-6689ad5e3a79/contexts/awaitans1","parameters": {
"quiz.original": [
"quiz"
],"quiz": [
"quiz"
]
}
}
],"languageCode": "en"
}
]
}
有人可以启发我吗?