从意图异步触发实现 webhook?
Triggering the fulfillment webhook asynchronously from an intent?
我有一些意图需要触发 fulfillment webhook 并且不关心响应。 webhook 响应的时间比超时时间长,因此我希望只用 "Thanks for chatting" 响应,然后在实际触发 webhook 时关闭对话。
感觉很简单,但我错过了一些东西。我也是 dialogflow 的新手。
我可以用任何语言做到这一点,但这里有一个例子 Javascript:
fdk.handle(function (input) {
// Some code here that takes 20 seconds.
return {'fulfillmentText': 'i can respond but I will never make it here.'}
});
编辑 1 - 尝试异步
当我使用异步函数时,POST 请求永远不会发生。所以在下面的代码中:
fdk.handle(function (input) {
callFlow(input);
return { 'fulfillmentText': 'here is the response from the webhook!!' }
});
async function callFlow(input) {
console.log("input is --> " + input)
var url = "some_url"
console.log("Requesting " + url)
request(url, { json: true, headers: {'Access-Control-Allow-Origin' : '*'} }, (err, res, body) => {
if (err) { return console.log(err); }
console.log("body is...")
console.log(body)
});
}
我在日志中看到两个 console.log 输出,但请求中没有任何内容。而且请求似乎也没有发生,因为我没有在我的端点看到它。
解决方案
感谢 Prisoner 的提示。似乎我需要通过 callFlow() 和 handle() 函数 return 实现 JSON 返回。现在 Google 主页不会超时,并且会生成 HTTP 调用和响应。
const fdk = require('@fnproject/fdk');
const request = require('request');
fdk.handle(function (input) {
return callFlow(input);
});
async function callFlow(input) {
var searchPhrase = input || "cats"
var url = "some url"
return new Promise((resolve, reject) => {
request.post(url, {
headers: { 'content-type': 'application/x-www-form-urlencoded' },
body: searchPhrase
},
function (err, resp, body) {
if (err) { return console.log(err) }
r = { 'fulfillmentText': `OK I've triggered the flow function with search term ${searchPhrase}` }
resolve(r)
}
);
});
}
您不能异步触发履行。在会话模型中,预计履行将执行一些确定响应的逻辑。
您 可以 ,但是,在您 return 结果之前未完成的实现中执行异步操作。
如果您使用的是足够现代的节点版本(版本 8 及更高版本),您可以通过将函数声明为 async
函数来实现,但 不是 使用 await
关键字调用它。 (如果您使用 await
调用它,它将等待异步操作完成后再继续。)
因此,根据您的示例,这样的事情应该可行:
async function doSomethingLong(){
// This takes 20 seconds
}
fdk.handle(function (input) {
doSomethingLong();
return {'fulfillmentText': 'This might respond before doSomethingLong finishes.'}
});
根据您的代码示例更新 1。
您报告对 request
的调用似乎根本没有完成,这似乎很奇怪,但可能有一些奇怪的事情导致了它。
首先,request
本身不是异步函数。它使用回调模型,async
函数不会自动等待调用这些回调。所以你的 callFlow()
函数调用 console.log()
几次,在回调被回调之前调用 request()
和 returns。
您可能应该将 request
替换为 request-promise-native 包之类的东西,并等待您从调用中获得的 Promise。这使得 callFlow()
真正异步(并且您可以在它完成调用时记录)。
其次,我要指出您显示的代码没有执行 POST 操作。它默认执行 GET。如果您或您正在呼叫的 API,预计会出现 POST,这可能是错误的来源。但是,我希望填充 err
参数,并且您的代码看起来确实检查并记录了 this.
整个设置中的一个未知数,对我来说,是我不知道 fdk
是如何处理异步函数的,而且我对文档的粗略阅读并没有教我。我已经使用其他框架完成了此操作,这不是问题,但我不知道 fdk
处理程序是否超时或执行其他操作以在发送回复后终止调用。
我有一些意图需要触发 fulfillment webhook 并且不关心响应。 webhook 响应的时间比超时时间长,因此我希望只用 "Thanks for chatting" 响应,然后在实际触发 webhook 时关闭对话。
感觉很简单,但我错过了一些东西。我也是 dialogflow 的新手。
我可以用任何语言做到这一点,但这里有一个例子 Javascript:
fdk.handle(function (input) {
// Some code here that takes 20 seconds.
return {'fulfillmentText': 'i can respond but I will never make it here.'}
});
编辑 1 - 尝试异步
当我使用异步函数时,POST 请求永远不会发生。所以在下面的代码中:
fdk.handle(function (input) {
callFlow(input);
return { 'fulfillmentText': 'here is the response from the webhook!!' }
});
async function callFlow(input) {
console.log("input is --> " + input)
var url = "some_url"
console.log("Requesting " + url)
request(url, { json: true, headers: {'Access-Control-Allow-Origin' : '*'} }, (err, res, body) => {
if (err) { return console.log(err); }
console.log("body is...")
console.log(body)
});
}
我在日志中看到两个 console.log 输出,但请求中没有任何内容。而且请求似乎也没有发生,因为我没有在我的端点看到它。
解决方案
感谢 Prisoner 的提示。似乎我需要通过 callFlow() 和 handle() 函数 return 实现 JSON 返回。现在 Google 主页不会超时,并且会生成 HTTP 调用和响应。
const fdk = require('@fnproject/fdk');
const request = require('request');
fdk.handle(function (input) {
return callFlow(input);
});
async function callFlow(input) {
var searchPhrase = input || "cats"
var url = "some url"
return new Promise((resolve, reject) => {
request.post(url, {
headers: { 'content-type': 'application/x-www-form-urlencoded' },
body: searchPhrase
},
function (err, resp, body) {
if (err) { return console.log(err) }
r = { 'fulfillmentText': `OK I've triggered the flow function with search term ${searchPhrase}` }
resolve(r)
}
);
});
}
您不能异步触发履行。在会话模型中,预计履行将执行一些确定响应的逻辑。
您 可以 ,但是,在您 return 结果之前未完成的实现中执行异步操作。
如果您使用的是足够现代的节点版本(版本 8 及更高版本),您可以通过将函数声明为 async
函数来实现,但 不是 使用 await
关键字调用它。 (如果您使用 await
调用它,它将等待异步操作完成后再继续。)
因此,根据您的示例,这样的事情应该可行:
async function doSomethingLong(){
// This takes 20 seconds
}
fdk.handle(function (input) {
doSomethingLong();
return {'fulfillmentText': 'This might respond before doSomethingLong finishes.'}
});
根据您的代码示例更新 1。
您报告对 request
的调用似乎根本没有完成,这似乎很奇怪,但可能有一些奇怪的事情导致了它。
首先,request
本身不是异步函数。它使用回调模型,async
函数不会自动等待调用这些回调。所以你的 callFlow()
函数调用 console.log()
几次,在回调被回调之前调用 request()
和 returns。
您可能应该将 request
替换为 request-promise-native 包之类的东西,并等待您从调用中获得的 Promise。这使得 callFlow()
真正异步(并且您可以在它完成调用时记录)。
其次,我要指出您显示的代码没有执行 POST 操作。它默认执行 GET。如果您或您正在呼叫的 API,预计会出现 POST,这可能是错误的来源。但是,我希望填充 err
参数,并且您的代码看起来确实检查并记录了 this.
整个设置中的一个未知数,对我来说,是我不知道 fdk
是如何处理异步函数的,而且我对文档的粗略阅读并没有教我。我已经使用其他框架完成了此操作,这不是问题,但我不知道 fdk
处理程序是否超时或执行其他操作以在发送回复后终止调用。