使用云函数模拟器在本地测试 Dialogflow 实现
Using the cloud functions emulator to test Dialogflow fulfillment locally
是否可以使用云函数模拟器在本地测试您的 Dialogflow fulfillment webhook?如果可以,我应该如何格式化请求?
我通读了我能找到的所有文档,包括 https://firebase.google.com/docs/functions/local-emulator 上的指南,特别感兴趣的是之前的这个问题,它似乎触及了类似的观点:
我可以使用函数 shell 调用我的实现函数,但是无论我如何尝试格式化正文,我似乎只能触发我的回退意图或错误捕获意图。
我可以在 Actions on Google 模拟器上验证,当给定输入 "hello" 时,我的 webhook 成功响应了默认的欢迎意图,但是当使用相同的请求 JSON 数据时作为本地函数的输入,我被引导到后备意图。
是不是功能模拟器无法在本地执行正确的意图匹配,因此总是触发后备意图,或者我只是没有正确格式化我的请求?任何帮助将不胜感激!
这是我正在使用的调用格式,以及来自 shell 的响应:
firebase > fulfillment({method: 'POST',json: true,body:
require("project/collabrec/testData.json")});
Sent request to function.
firebase > info: User function triggered, starting execution
info: Fallback intent triggered.
info: Execution took 15 ms, user function completed successfully
RESPONSE RECEIVED FROM FUNCTION: 200, {
"payload": {
"google": {
"expectUserResponse": true,
"richResponse": {
"items": [
{
"simpleResponse": {
"textToSpeech": "I didn't quite catch that. Could you say that again?"
}
}
]
}
}
}
}
这里是testData.json内容:
{
"user": {
"userId": "ABwppHFR0lfRsG_UM3NkvAptIkD2iUpIUNxFt-ia05PFuPajV6kRQKXu_H_ECMMe0lP_WcCsK64sH2MEIg8eqA",
"locale": "en-US",
"lastSeen": "2018-10-19T15:20:12Z"
},
"conversation": {
"conversationId": "ABwppHHerN4CIsBZiWg7M3Tq6NwlTWkfN-_zLIIOBcKbeaz4ruymv-nZ4TKr6ExzDv1tOzszsfcgXikgqRJ9gg",
"type": "ACTIVE",
"conversationToken": "[]"
},
"inputs": [
{
"intent": "actions.intent.TEXT",
"rawInputs": [
{
"inputType": "KEYBOARD",
"query": "hello"
}
],
"arguments": [
{
"name": "text",
"rawText": "hello",
"textValue": "hello"
}
]
}
],
"surface": {
"capabilities": [
{
"name": "actions.capability.MEDIA_RESPONSE_AUDIO"
},
{
"name": "actions.capability.SCREEN_OUTPUT"
},
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.WEB_BROWSER"
}
]
},
"isInSandbox": true,
"availableSurfaces": [
{
"capabilities": [
{
"name": "actions.capability.SCREEN_OUTPUT"
},
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.WEB_BROWSER"
}
]
}
],
"requestType": "SIMULATOR"
}
这是我的云函数 webhook:
const {dialogflow, Image} = require('actions-on-google');
const admin = require('firebase-admin');
const functions = require('firebase-functions');
const app = dialogflow();
app.catch((conv, error) => {
console.log("Error intent triggered.")
console.error(error);
conv.ask('Sorry, I ran into an error. Please try that again.');
});
app.fallback((conv) => {
console.log("Fallback intent triggered.")
conv.ask("I didn't quite catch that. Could you say that again?");
})
app.intent('Default Welcome Intent', (conv) => {
console.log("Welcome intent triggered.")
conv.ask("Welcome!!");
});
exports.fulfillment = functions.region('europe-west1').https.onRequest(app);
使用 Node v8.1.4 和软件包版本:
"@google-cloud/common-grpc": "^0.9.0",
"@google-cloud/firestore": "^0.17.0",
"@google-cloud/functions-emulator": "^1.0.0-beta.5",
"actions-on-google": "^2.4.1",
"firebase-admin": "^6.0.0",
"firebase-functions": "^2.0.5"
问题是您使用的是来自 AoG 模拟器的 JSON,但这显示了 AoG 发送到 Dialogflow 的 JSON。 Dialogflow 对此进行处理并向您的 webhook 发送一个不同的 JSON,其中包括处理 AoG JSON 和确定意图、参数和其他信息的结果。
如果您有 Dialogflow JSON,您正在做的应该有效。您有几种方法可以做到这一点:
最直接的是 运行 你的 webhook 放在一个可以从 Dialogflow 接收 POST 的地方并查看 conv.request
对象,这应该是能够给你JSON你需要的。
如果您 运行 在本地开发机器上使用 webhook(正如您所暗示的那样),我倾向于启动一个 ngrok 隧道。隧道提供了一个 public HTTPS 服务器,这非常有用,并且具有给我一个控制台的副作用,我可以使用它来准确查看请求和响应的内容 JSON.
最后,您应该能够进入 Dialogflow 中的项目设置并打开 Cloud Logging。该日志包括发送到您的 webhook 的请求以及您从中获得的响应。
是否可以使用云函数模拟器在本地测试您的 Dialogflow fulfillment webhook?如果可以,我应该如何格式化请求?
我通读了我能找到的所有文档,包括 https://firebase.google.com/docs/functions/local-emulator 上的指南,特别感兴趣的是之前的这个问题,它似乎触及了类似的观点:
我可以使用函数 shell 调用我的实现函数,但是无论我如何尝试格式化正文,我似乎只能触发我的回退意图或错误捕获意图。
我可以在 Actions on Google 模拟器上验证,当给定输入 "hello" 时,我的 webhook 成功响应了默认的欢迎意图,但是当使用相同的请求 JSON 数据时作为本地函数的输入,我被引导到后备意图。
是不是功能模拟器无法在本地执行正确的意图匹配,因此总是触发后备意图,或者我只是没有正确格式化我的请求?任何帮助将不胜感激!
这是我正在使用的调用格式,以及来自 shell 的响应:
firebase > fulfillment({method: 'POST',json: true,body:
require("project/collabrec/testData.json")});
Sent request to function.
firebase > info: User function triggered, starting execution
info: Fallback intent triggered.
info: Execution took 15 ms, user function completed successfully
RESPONSE RECEIVED FROM FUNCTION: 200, {
"payload": {
"google": {
"expectUserResponse": true,
"richResponse": {
"items": [
{
"simpleResponse": {
"textToSpeech": "I didn't quite catch that. Could you say that again?"
}
}
]
}
}
}
}
这里是testData.json内容:
{
"user": {
"userId": "ABwppHFR0lfRsG_UM3NkvAptIkD2iUpIUNxFt-ia05PFuPajV6kRQKXu_H_ECMMe0lP_WcCsK64sH2MEIg8eqA",
"locale": "en-US",
"lastSeen": "2018-10-19T15:20:12Z"
},
"conversation": {
"conversationId": "ABwppHHerN4CIsBZiWg7M3Tq6NwlTWkfN-_zLIIOBcKbeaz4ruymv-nZ4TKr6ExzDv1tOzszsfcgXikgqRJ9gg",
"type": "ACTIVE",
"conversationToken": "[]"
},
"inputs": [
{
"intent": "actions.intent.TEXT",
"rawInputs": [
{
"inputType": "KEYBOARD",
"query": "hello"
}
],
"arguments": [
{
"name": "text",
"rawText": "hello",
"textValue": "hello"
}
]
}
],
"surface": {
"capabilities": [
{
"name": "actions.capability.MEDIA_RESPONSE_AUDIO"
},
{
"name": "actions.capability.SCREEN_OUTPUT"
},
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.WEB_BROWSER"
}
]
},
"isInSandbox": true,
"availableSurfaces": [
{
"capabilities": [
{
"name": "actions.capability.SCREEN_OUTPUT"
},
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.WEB_BROWSER"
}
]
}
],
"requestType": "SIMULATOR"
}
这是我的云函数 webhook:
const {dialogflow, Image} = require('actions-on-google');
const admin = require('firebase-admin');
const functions = require('firebase-functions');
const app = dialogflow();
app.catch((conv, error) => {
console.log("Error intent triggered.")
console.error(error);
conv.ask('Sorry, I ran into an error. Please try that again.');
});
app.fallback((conv) => {
console.log("Fallback intent triggered.")
conv.ask("I didn't quite catch that. Could you say that again?");
})
app.intent('Default Welcome Intent', (conv) => {
console.log("Welcome intent triggered.")
conv.ask("Welcome!!");
});
exports.fulfillment = functions.region('europe-west1').https.onRequest(app);
使用 Node v8.1.4 和软件包版本:
"@google-cloud/common-grpc": "^0.9.0",
"@google-cloud/firestore": "^0.17.0",
"@google-cloud/functions-emulator": "^1.0.0-beta.5",
"actions-on-google": "^2.4.1",
"firebase-admin": "^6.0.0",
"firebase-functions": "^2.0.5"
问题是您使用的是来自 AoG 模拟器的 JSON,但这显示了 AoG 发送到 Dialogflow 的 JSON。 Dialogflow 对此进行处理并向您的 webhook 发送一个不同的 JSON,其中包括处理 AoG JSON 和确定意图、参数和其他信息的结果。
如果您有 Dialogflow JSON,您正在做的应该有效。您有几种方法可以做到这一点:
最直接的是 运行 你的 webhook 放在一个可以从 Dialogflow 接收 POST 的地方并查看
conv.request
对象,这应该是能够给你JSON你需要的。如果您 运行 在本地开发机器上使用 webhook(正如您所暗示的那样),我倾向于启动一个 ngrok 隧道。隧道提供了一个 public HTTPS 服务器,这非常有用,并且具有给我一个控制台的副作用,我可以使用它来准确查看请求和响应的内容 JSON.
最后,您应该能够进入 Dialogflow 中的项目设置并打开 Cloud Logging。该日志包括发送到您的 webhook 的请求以及您从中获得的响应。