主动消息传递:'Authorization has been denied for this request' 服务器重启时

Proactive Messaging: 'Authorization has been denied for this request' on server restart

我们正在使用 botframework 来增强 Microsoft Teams 中的聊天机器人体验。我们的许多用例都涉及主动向用户发送消息,我们通过 storing/retrieving 对话引用密切关注文档并信任检索到的引用中的 serviceUrl,从而使我们能够成功发送主动消息。

我们注意到,每当我们重新启动 bot 时,我们都会在尝试发送主动消息时收到以下错误: 此请求的授权已被拒绝。

我们第一次遇到此错误消息是在至少一天没有与机器人进行交互之后,通过在 serviceUrl 上更改以下语句并增加到期时间来解决该错误消息: MicrosoftAppCredentials.trustServiceUrl(conversationReference.serviceUrl, new Date(8640000000000000));

但是,我们现在每次重启机器人服务器时都会收到此消息,由于我们的 CI/CD 管道,这种情况经常发生。

我们可以通过事先手动向 bot 发送消息来快速解决此问题,这将起作用,但是这非常麻烦,因为我们每天可能有很多部署。

重现步骤

手动解决

其他上下文

环境:Node.js Docker 部署到 AWS 的容器

通过使用 botframework-connector 创建对话并发送主动消息设法解决了这个问题。

假设您已经存储并检索了 conversationReference,请先连接到机器人

const msAppCredentials = new MicrosoftAppCredentials(MS_APP_ID, MS_APP_PASSWORD);
const client = new ConnectorClient(MSAppCredentials, { baseUri: conversationReference.serviceUrl });

连接后,您可以建立对话参数并创建对话:

const parameters = {
  bot: { id: MS_APP_ID, name: conversationReference.bot.name }, 
  members: [{ id: conversationReference.user.id, name: conversationReference.user.name }],
  activity: MessageFactory.text("oi oi oi"),
  tenantId: conversationReference.conversation.tenantId,
  isGroup: false,
  channelData: { ...conversationReference.conversation.channelData }
}

const resource = await client.conversations.createConversation(parameters);

最后,将消息发送到会话

await client.conversations.sendToConversation(resource.id, parameters.activity);

您必须在机器人重新启动后信任一次 ServiceURL。通常,机器人框架默默地负责为每个入站对话启用信任。我们保留了一组我们从入站对话中遇到的唯一服务 URL,并且在我们的机器人重新启动时,我们循环遍历此列表并在启动任何对话之前信任它们。

这里描述了一个类似的问题:https://github.com/microsoft/BotBuilder-Samples/issues/2462