【发布时间】:2020-07-27 23:46:59
【问题描述】:
我的机器人基于bot框架并集成了许多渠道,主要在telegram中,我遇到了这个错误POST to botName timed out after 15s..有什么办法可以在代码中限制吗?
【问题讨论】:
标签: node.js botframework telegram-bot azure-bot-service
我的机器人基于bot框架并集成了许多渠道,主要在telegram中,我遇到了这个错误POST to botName timed out after 15s..有什么办法可以在代码中限制吗?
【问题讨论】:
标签: node.js botframework telegram-bot azure-bot-service
我遇到了类似的问题。我的机器人实际上并没有停止运行(老实说,我不确定是否会抛出 console.log 错误),但我确实在网络聊天 UI 中收到了 Couldn't send. Retry。
此解决方案不能解决问题,但确实提供了一种解决方法。 我希望如果其他人对此问题有直接的解决方案,他们会分享它!您可以做的是使 API 调用异步并通过主动消息发送响应。您可以明确地让用户知道(就像我在下面的示例中所做的那样),或者如果延迟不是那么长,您不必说什么。
conversationReference 对象是完成这项工作所必需的。我将我的机器人设置为在每个消息活动上生成它(因此,如果您使用旧语法,则使用 onMessage 处理程序或 onTurn where context.activity.type === ActivityTypes.Message)。我将它保存为对话状态,以便我可以在整个机器人中访问它。您需要从 botbuilder 库中导入 TurnContext。保存对话参考只需使用
// Save the conversationReference
const conversationData = await this.dialogState.get(context, {});
conversationData.conversationReference = TurnContext.getConversationReference(context.activity);
await this.conversationState.saveChanges(context);
我使用虚拟 API 整理了一个示例,如下所示。请注意,我不是在等待 API 调用。这就是阻止Couldn't send. Retry 消息出现的原因。如果您不需要或不想让用户知道会有延迟响应,您可以省略sendActivity。此外,您可以只从您正在调用的其他函数访问对话状态,但您必须以任何一种方式传递一些东西,看来我只是传递了值而不是状态访问器。
case PROACTIVE_MSG_INTENT:
await dc.context.sendActivity(`OK, I'll simulate a long-running API call and send a proactive message when it's done.`);
const conversationData = await this.dialogState.get(context, {});
apiSimulation.longRunningRequest(conversationData.conversationReference);
break;
所以我这里的函数显然是一个模拟的 API。你会在我有await new Promise(resolve => setTimeout(resolve, 30000)); 声明的地方调用你的API。你确实想等待这个电话,因为你显然需要回复才能发回!但是您的机器人的其余部分将继续运行。这是我的整个示例函数。
const { BotFrameworkAdapter } = require('botbuilder');
class apiSimulation {
static async longRunningRequest(conversationReference) {
console.log('Starting simulated API');
await new Promise(resolve => setTimeout(resolve, 30000));
console.log('Simulated API complete');
// Set up the adapter and send the message
try {
const adapter = new BotFrameworkAdapter({
appId: process.env.microsoftAppID,
appPassword: process.env.microsoftAppPassword,
channelService: process.env.ChannelService,
openIdMetadata: process.env.BotOpenIdMetadata
});
await adapter.continueConversation(conversationReference, async turnContext => {
await turnContext.sendActivity('This message was sent after a simulated long-running API');
});
} catch (error) {
console.log(error);
}
}
}
module.exports.apiSimulation = apiSimulation;
应该就是这样!您的机器人处理程序不会等待 API 响应,因此您不会收到消息,并且您的单独函数将等待响应并通过主动消息/continueConversation 发送。请注意,您不需要像在 GitHub 上的 Proactive Notification Sample 中那样为主动消息传递设置单独的端点。我想你可以从你的机器人中调用这个端点,但对我来说,创建一个新的适配器来继续对话似乎更有效。
【讨论】: