我正在Dialogflow上创建一个聊天机器人,该机器人可以执行各种操作(我基本上已经遵循了Dialogflow推出的一些教程,对代码进行了小幅重新格式化,并为自己进行了一些调整)。
代码很长,因此我将链接放在下面的Github上。另外,我在dialogflow上使用内联编辑器
问题/我不确定自己要做什么,因为我有一个用户登录部分(第33至51行),用户可以在其中通过语音登录自己的Google帐户。
在教程中,他们具有履行能力(我几乎可以肯定这是它不起作用的原因):
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app)
但是问题是,要实现我的其他功能,我需要具备以下条件:
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
..... Functions under }
我曾尝试写一些变体,认为这可能有效:
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((app, request, response)
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app(request, response)
// Syntax error
如何让代码的两半一起工作?是否可以执行此操作,还是必须重新设置格式,还是只需要对履行线做些不同的事情?
感谢您的帮助!
代码here
注意::在Github上的代码中,我没有更改履行行,而是以其他功能可以使用的形式将其保留。 该代码已经过登录和工作的测试,无法与我编写的其他功能一起使用。
答案 0 :(得分:2)
您似乎在混合两种不同版本的Google图书馆中的操作。建议您坚持使用V2,这意味着将Intent-map改为Intent处理程序。
// Intent that starts the account linking flow.
app.intent('Start Signin', conv => {
conv.ask(new SignIn('To get your account details'));
});
// Create a Dialogflow intent with the `actions_intent_SIGN_IN` event.
app.intent('Get Signin', (conv, params, signin) => {
if (signin.status === 'OK') {
const payload = conv.user.profile.payload;
conv.ask(`Welcome back ${payload.name}. What do you want to do next?`);
} else {
conv.ask(`I won't be able to save your data, but what do you want to do next?`);
}
});
app.intent('Make Appointment', (conv) => {
/* some code here */
});
app.intent('ReadFromFirestore', (conv) => {
// Get the database collection 'dialogflow' and document 'agent'
const dialogflowAgentDoc = db.collection('dialogflow').doc('agent');
// Get the value of 'entry' in the document and send it to the user
return dialogflowAgentDoc.get().then(doc => {
if (!doc.exists) {
conv.tell('No data found in the database!');
} else {
conv.ask(doc.data().entry);
}
}).catch(() => {
conv.ask('Error reading entry from the Firestore database. Please add a entry to the database first by saying, "Write <your phrase> to the database"');
});
});
app.intent('WriteToFirestore', (conv) => {
/* some code here */
});
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);
(省略了方法)
“ app”(对话框流)对象已经包装了请求和响应参数,因此您无需采取任何措施来干扰这些参数。
如果您想在dialogflow之外使用单独的端点来完成工作:您可以添加其他功能,例如:
exports.someOtherFunction = functions.https.onRequest((request, response) => {
/* do something with the request and response here */
});
这些与Dialogflow没有直接关系。
答案 1 :(得分:2)
问题在于这两个库具有不同的方式来设置用于处理请求/响应对象的侦听器以及设置意图处理程序注册。您不能将两者混合使用(如您所知)。您需要选择一个并以另一种方式转换注册的功能。
为节省大量输入时间,我将Google-Actions库称为a-o-g,将dialogflow-fulfillment库称为d-f。
使用Google动作库
您可以使用以下方式初始化监听器:
const app = dialogflow({
// REPLACE THE PLACEHOLDER WITH THE CLIENT_ID OF YOUR ACTIONS PROJECT
clientId: '<CLIENT ID>',
});
// Intent handler declarations go here
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);
转换dialogflow-fulfillment-style处理程序相对简单。 a-o-g conv
对象与d-f agent
对象非常相似。例如,两者都具有add()
方法,在处理动作时其行为方式相同。
conv
对象还具有parameters
属性,尽管最好在函数调用中使用第二个参数,但它包含相同的内容。同样,它具有arguments
属性,该属性包含与传递给处理程序的第三个参数相同的内容。
还值得注意的是,app.intent()
不必具有箭头功能,甚至不必像这样直接内联。您可以单独编写该函数,只需将其作为参数传递即可。
因此,您的makeAppointment()
函数可能会被重写并注册为类似的内容
function makeAppointment (conv) {
// Calculate appointment start and end datetimes (end = +1hr from start)
const dateTimeStart = new Date(Date.parse(conv.parameters.date.split('T')[0] + 'T' + agent.parameters.time.split('T')[1].split('-')[0] + timeZoneOffset));
const dateTimeEnd = new Date(new Date(dateTimeStart).setHours(dateTimeStart.getHours() + 1));
const appointmentTimeString = dateTimeStart.toLocaleString(
'en-US',
{ month: 'long', day: 'numeric', hour: 'numeric', timeZone: timeZone }
);
// Check the availibility of the time, and make an appointment if there is time on the calendar
return createCalendarEvent(dateTimeStart, dateTimeEnd).then(() => {
conv.add(`Okay, I have you booked for ${appointmentTimeString}!`);
}).catch(() => {
conv.add(`I'm sorry, there are no slots available for ${appointmentTimeString}.`);
});
}
app.intent( 'Make Appointment', makeAppointment );
使用对话流程实现库
您已经通过这种方式设置了侦听器和处理程序
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
// Declare your functions here
let intentMap = new Map();
// Map intent name to functions here
agent.handleRequest(intentMap);
});
所以问题是如何将似乎在函数参数中具有a-o-g特定信息的处理程序转换为d-f兼容处理程序。
d-f agent
对象可以获取(几乎)等效的conv
对象。毫不奇怪,它是agent.getConv()
。真。然后,您可以使用如上所述的parameters
和arguments
属性来获取第二个和第三个函数参数的等效项。您将使用agent.add()
添加一条消息(也可以使用conv
,但要复杂一些)。
“获取登录”处理程序可能看起来像这样:
function getSignin (agent){
let conv = agent.getConv();
let params = conv.parameters;
let signin = conv.arguments;
if (signin.status === 'OK') {
const payload = conv.user.profile.payload;
agent.ask(`Welcome back ${payload.name}. What do you want to do next?`);
} else {
agent.ask(`I won't be able to save your data, but what do you want to do next?`);
}
}
然后确保您在适当的位置注册了处理程序
intentMap.set('Get Signin', getSignin);