我的机器人基于机器人框架并集成了许多渠道,主要是在电报中,我面临这个错误POST to botName timed out after 15s .. 代码中有什么方法可以限制代码吗?
1 回答
我遇到了类似的问题。我的机器人实际上并没有停止运行(老实说,我不确定是否会抛出 console.log 错误)但我确实Couldn't send. Retry在网络聊天 UI 中得到了。
此解决方案不能解决问题,但确实提供了一种解决方法。我希望如果其他人对这个问题有直接的解决方案,他们会分享它!不过,您可以做的是使 API 调用异步并通过主动消息发送响应。您可以明确地让用户知道(就像我在下面的示例中所做的那样),或者如果延迟不是那么长,您不必说什么。
需要 conversationReference 对象才能完成这项工作。我将我的机器人设置为在每个消息活动上生成它(因此,context.activity.type === ActivityTypes.Message如果您使用旧语法,则使用 onMessage 处理程序或 onTurn)。我将它保存为对话状态,以便我可以在整个机器人中访问它。您需要从 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 上的主动通知示例中那样为主动消息传递设置单独的端点。我想你可以从你的机器人中调用这个端点,但对我来说,创建一个新的适配器来继续对话似乎更有效。