【问题标题】:How can I get my bot to post a message to a Microsoft Teams channel?如何让我的机器人向 Microsoft Teams 频道发布消息?
【发布时间】:2018-05-07 14:11:13
【问题描述】:

我有一个与docs quickstart 中演示的机器人相同的机器人。它会重复用户所说的任何内容(目前)。

它当前在本地运行并使用 ngrok 公开。我已经使用 Microsoft Bot Framework 注册了该机器人。

我已在 Microsoft Bot Framework 中配置 Microsoft Teams 频道,并将我的机器人旁加载到 Teams 中。我的机器人可以接收来自 Teams 用户的消息。

目前,机器人只是将收到的任何内容重复给用户,但我希望它做的是发布到 Microsoft Teams 频道。我希望它发布到 Teams 频道 - 不是用户 - 无需用户先提示。因此,例如给定特定条件(例如,由某些事件触发,例如一天中的某个时间、拉取请求等),它会在频道中发布一条消息。

我已阅读有关 sending proactive messages 的文档,并且我了解到为了向团队频道发送消息,机器人需要知道用户的“地址”。此信息存储在session.message.address 对象中,并从当前对话中获取。但是,就我而言,我没有“当前保护”,因为我不想只回复用户,我想主动在频道中发帖。

那么,如何为 Teams 频道永久设置必要的凭据/地址/会话数据?

我调查过的事情:

  • 网络挂钩。我已经在我的 Teams 频道中配置了一个 webhook,我可以使用 curl 轻松地向它发送一条消息(使用 webhook url)。因此,我可以向 Teams 频道发送仅包含 url 的简单消息(无需身份验证),但我不确定如何将此 url 输入到我的机器人中。

  • How do we maintain different session for different users in Microsoft Bot Framework? 我不确定这里的答案是否能回答我的 问题。我的问题是机器人正在启动“对话”,而不是团队用户,所以我需要能够自己设置会话数据,以便机器人知道去哪里。

App.js:

require('dotenv').config();
var restify = require('restify');
var builder = require('botbuilder');

// Setup Restify Server
var server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function () {
   console.log('%s listening to %s', server.name, server.url); 
});

// Create chat connector for communicating with the Bot Framework Service
var connector = new builder.ChatConnector({
    appId: process.env.MICROSOFT_APP_ID,
    appPassword: process.env.MICROSOFT_APP_PASSWORD    
});

// Listen for messages from users 
server.post('/api/messages', connector.listen());

// Receive messages from the user and respond by echoing each message back (prefixed with 'You said:')
var bot = new builder.UniversalBot(connector, function (session) {
    session.send("You said: %s", session.message.text);
});

【问题讨论】:

    标签: node.js botframework microsoft-teams


    【解决方案1】:

    对于任何想知道 c# 相同的人,这里是对我有用的解决方案:

        var channelData = context.Activity.GetChannelData<TeamsChannelData>();
        var message = Activity.CreateMessageActivity();
        message.Text = "Hello World";
    
        var conversationParameters = new ConversationParameters
        {
             IsGroup = true,
             ChannelData = new TeamsChannelData
              {
                 Channel = new ChannelInfo(channelData.Channel.Id),
             },
             Activity = (Activity) message
        };
    
        var connectorClient = new ConnectorClient(new Uri(activity.ServiceUrl));
        var response = await 
        connectorClient.Conversations.CreateConversationAsync(conversationParameters);
    

    注意:如果您在 Bot 的控制器代码之外调用它,那么您需要在 serviceUrl 上调用 TrustServiceUrl,如下所示:

        MicrosoftAppCredentials.TrustServiceUrl(serviceUrl, DateTime.MaxValue);
        var connectorClient = new ConnectorClient(new Uri(serviceUrl));
    

    答案来源:https://github.com/OfficeDev/BotBuilder-MicrosoftTeams/issues/162

    【讨论】:

    • IsGroup 是干什么用的?我已尝试删除它,它按预期工作。
    • 我正在关注 github 链接,但无法找到如何获取 ID 等频道信息?我知道如何获取与此处无关的传入 Web 挂钩 URL。
    • 这是一个示例(其中活动是 Microsoft.Bot.Connector.Activity 类): var channelData = activity.GetChannelData(); var id = channelData.Channel.Id;
    【解决方案2】:

    这绝对是可能的。我们将这些称为主动消息,可以主动向用户和渠道发送消息。

    对于后者,请参阅https://github.com/OfficeDev/microsoft-teams-sample-complete-node 的示例,特别是此文件ProactiveMsgToChannelDialog.ts

    要将主动消息发送到频道,您需要使用 Microsoft Teams SDK(就像这些示例一样)。

    最后但同样重要的是,您需要将机器人添加到团队中,以便向团队中的某个频道发送消息,这需要清单。

    【讨论】:

    • 谢谢比尔。所以我收集到我在src/utils/DialogIds.ts(ProactiveMsgToChannelDialogId)中设置了频道的“地址/id”?在 MS Teams 中哪里可以找到此 ID?
    • src/utils/DialogIds.ts无关。在ProactiveMsgToChannelDialogId 中,逻辑是用户输入频道名称,然后调用teamsChatConnector.fetchChannelList 来遍历团队的频道列表并找到名称与用户输入的内容匹配的频道(如果有的话)和然后使用其 ID 发布到该频道。查看ProactiveMsgToChannelDialogId 中回调函数的逻辑,特别是第 38-74 行。其中一个参数是 result,它是 Channel 对象的数组,包括 .id.name - .id 是你想要的。
    • @andydavies 你能让这个工作吗?我正在尝试做类似的事情。
    • @Haymak3r 不,我没有管理它,然后我被转移到其他事情上(这是一项工作任务)。但是,如果答案对您有用,请告诉我,我会接受它作为“已回答”。或者,如果您以其他方式管理它,请将其放在此处,我会标记为已接受。
    • @BillBliss-MSFT 这个答案看起来像是对用户发送的消息的反应,而不是真正的主动。例如,在第 1 步中,您需要一个会话并为此发送消息 (!isMessageFromChannel(session.message)) 第 2 步也需要一个会话。 Andy 的问题是您如何从一些非消息事件触发:“(例如,由某些事件触发,例如一天中的时间、拉取请求等)它在频道中发布消息”。这可能吗?
    【解决方案3】:

    希望这对您有用.. 下面的代码会在开始聊天之前主动将消息发送到会话。

     bot.on('conversationUpdate', function (message) {  
           if (message.membersAdded[0].id === message.address.bot.id) {             
                 var reply = new builder.Message()    
                       .address(message.address)               
                       .text("Hello"");        
                 bot.send(reply);    
           }
        }); 
    

    【讨论】:

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