【问题标题】:Bot Framework v4 - Bot Initiate ConversationBot Framework v4 - Bot 发起对话
【发布时间】:2019-07-27 05:17:57
【问题描述】:

我正在使用适用于 NodeJS 的 Bot Framework SDK v4 为 Microsoft Teams 开发一个机器人。有没有办法让机器人自动在频道中发起对话,而不是用户发起对话?当用户发起对话时,我的机器人工作正常。关于如何继续进行此操作的任何建议?

【问题讨论】:

    标签: botframework microsoft-teams


    【解决方案1】:

    MS Teams 将其称为“主动消息”(注意:Bot Framework 通常将“主动消息”定义为向用户发送与当前对话无关的消息,您可以参考该消息。Teams 将一些内容混为一谈类别)。您可以从 Teams 官方文档中了解更多关于 how to use proactive messaging 的信息。或者,更具体地说,creating a channel conversation

    它的要点是你需要capture a conversationUpdate and check for a new member added to the conversationfetch the team roster,然后你send the proactive message

    注意:对于 MS Teams,用户或团队必须先添加机器人:

    只要您的机器人具有通过先前添加到个人或团队范围中获得的用户信息,机器人就可以与单个 Microsoft Teams 用户创建新对话。此信息使您的机器人能够主动通知他们。例如,如果您的机器人被添加到团队中,它可以查询团队名册并在个人聊天中向用户发送个人消息,或者用户可以@提及另一个用户以触发机器人向该用户发送直接消息。

    一些开发人员在使用主动消息传递时遇到401: Unauthorized 错误,尤其是当机器人由于某种原因重新启动并且机器人正尝试重新发起主动消息时。您可以阅读有关防止 by using trustServiceUrl from this Sample 的更多信息(这是我的分支,用于提交 Pull Request 以使用 trustServiceUrl 信息更新 Proactive Sample)。

    【讨论】:

    • “机器人可以自动在频道中发起对话”的需求并不是真正的“主动消息传递”,因为它需要使用以前的信息,而不是仅仅从其他东西获取身份
    • @NicolasR 你是对的,至少对于 Bot Framework 是如何定义它的。然而,the Teams docs 将它与欢迎信息和对话开始混为一谈。我会编辑答案。
    • 是的,看起来可以根据频道执行某些操作
    • 感谢您的回复。在我的场景中,我将数据从外部 REST API 发送到在 Microsoft Teams 上运行的机器人。机器人接收此数据并将其发送到适当的通道。我能够成功实现此功能,但是,当此消息到达 Teams 时,机器人不会触发通知。有人遇到过这样的问题吗?或者关于如何更改功能的任何建议?
    • 您希望它创建什么样的通知?聊天或活动,在桌面或移动设备上?
    【解决方案2】:

    您可以使用 Botframework V4 和 Teams Extensions V4 中的连接器客户端发起全新的对话。在 nodejs 中,您将在 this Github Issue 的其中一个 cmets 中找到解决方案。对于在 C# 中寻找解决方案的任何人,请here is a detailed blog post 了解如何在 C# 版本的 botframework 中完成此任务。

    在 nodejs 中:

    var conversationReference = TurnContext.getConversationReference(context.activity)
    connectorClient = await createConnectorClient(context)
    
    var conversationParameters = {
    isGroup: true,
    bot: conversationReference.bot,
    channelData: (await teamsCtx.getTeamsChannelData()),
    tenantId: teamsCtx.tenant.id,
    activity: MessageFactory.text("Queue Summary Placeholder") as Activity
    } as ConversationParameters
    
    await connectorClient.conversations.createConversation(conversationParameters)
    
    

    在 C# 中

    ConnectorClient _client = new ConnectorClient(new Uri(turnContext.Activity.ServiceUrl), await GetMicrosoftAppCredentialsAsync(turnContext), new HttpClient());
                var channelData = turnContext.Activity.GetChannelData<TeamsChannelData>();
    
                var conversationParameter = new ConversationParameters
                {
                    Bot = turnContext.Activity.Recipient,
                    IsGroup = true,
                    ChannelData = channelData,
                    TenantId = channelData.Tenant.Id,
                    Activity = MessageFactory.Text(message)
                };
                var response = await _client.Conversations.CreateConversationAsync(conversationParameter);
    
    

    【讨论】:

    • 阅读博文;有一件事我不太清楚 - 最后你展示了机器人工作的截图,你将它添加到一个频道,然后你用@mention写信给机器人,它回复你,然后它开始它自己的谈话。是否有必要写入它才能完成设置并访问频道?是否可以存储它抓取的任何内容(Guid?)作为频道参考,以便机器人可以关闭、重新启动并且仍然能够在频道中创建新对话?
    • @CaiusJard 是的,首先需要给机器人写信。你可以使用数据库来保存你的数据,使用实体框架或任何你喜欢的东西。
    【解决方案3】:

    我们真的需要知道您希望机器人何时发送消息,机器人框架TeamsActivityHandler 类提供了多个methods,您可以使用例如:

    1. onMembersAdded(BotHandler):为添加成员的事件注册一个活动事件处理程序,为包括添加到对话的成员在内的任何传入对话更新活动发出。

    详细了解您可以利用的事件/方法here

    【讨论】:

      【解决方案4】:

      我最终弄清楚了,我编写了一个机器人控制器,我可以使用以下代码按需调用它。

      var conversationParameters = new ConversationParameters
                  {
                      IsGroup = true,
                      ChannelData = new TeamsChannelData
                      {
                          // this needs to come from the teams context.
                          Channel = new ChannelInfo(channelId),
                      },
                      Activity = (Activity)MessageFactory.Attachment(attachment)
                  };
                  // your service url may differ.
                  MicrosoftAppCredentials.TrustServiceUrl(String.IsNullOrEmpty(serviceUrl) ? constantServiceUrl : serviceUrl, DateTime.MaxValue);
                  var response = connectorClient.Conversations.CreateConversationAsync(conversationParameters).GetAwaiter().GetResult();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-01-27
        • 1970-01-01
        • 1970-01-01
        • 2019-06-04
        • 1970-01-01
        • 2021-09-07
        • 2019-05-26
        相关资源
        最近更新 更多