将主动消息发送到 Teams 中的频道

Sending proactive messages to a channel in Teams

所以,

我进行了广泛的搜索,阅读了我能找到的关于该主题的所有内容,但我仍然没有成功。我已经设法向用户发送主动消息,回复团队中的主题等,但我无法在团队频道中发送主动消息(创建新的post)。

是否有可用的示例(我找不到)? NodeJS 的 MS Docs 似乎显示了一个向团队中的每个用户发送消息的示例,而不是频道本身。

我研究了源代码,channelDatabotFrameworkAdapter.js 中被硬编码为 null,这只会增加混乱。

所以,基本代码是:

const builder = require('botbuilder');
const adapter = new builder.BotFrameworkAdapter({
    appId: 'XXX',
    appPassword: 'YYY'
});

const conversation = {
  channelData: {
    //I have all this (saved from event when bot joined the Team)
  },
  ...
  // WHAT THIS OBJECT NEEDS TO BE TO SEND A SIMPLE "HELLO" TO A CHANNEL?
  // I have all the d
};

adapter.createConversation(conversation, async (turnContext) => {
  turnContext.sendActivity('HELLO'); //This may or may not be needed?
});

有人用 Node 做过吗?如果是这样,谁能告诉我一个工作示例(具有正确构造的 conversation 对象)?

* 编辑 *

正如希尔顿在下面的回答中所建议的,我尝试直接使用 ConnectorClient,但是 returns 资源不可用 (/v3/conversations)

这是我正在使用的代码(实际上只是这样,只是想发送演示消息):

const path = require('path');
const { ConnectorClient, MicrosoftAppCredentials } = require('botframework-connector');

const ENV_FILE = path.join(__dirname, '.env');
require('dotenv').config({ path: ENV_FILE });

const serviceUrl = 'https://smba.trafficmanager.net/emea/';

async function sendToChannel() {
    MicrosoftAppCredentials.trustServiceUrl(serviceUrl);

    var credentials = new MicrosoftAppCredentials(process.env.MicrosoftAppId, process.env.MicrosoftAppPassword);
    var client = new ConnectorClient(credentials, { baseUri: serviceUrl });

    var conversationResponse = await client.conversations.createConversation({
        bot: {
            id: process.env.MicrosoftAppId,
            name: process.env.BotName
        },
        isGroup: true,
        conversationType: "channel",
        id: "19:XXX@thread.tacv2"
    });

    var acivityResponse = await client.conversations.sendToConversation(conversationResponse.id, {
        type: 'message',
        from: { id: process.env.MicrosoftAppId },
        text: 'This a message from Bot Connector Client (NodeJS)'
    });

}

sendToChannel();

我做错了什么?

(我正在替换我之前的答案,因为我认为这更适合这种情况)。

我对此进行了更多研究并进行了 Fiddler 跟踪,以便为您提供更完整的答案。我不是 Node 专家,所以我不确定这是否会翻译 100%,但让我们看看。

基本上,您想要发送到以下端点: https://smba.trafficmanager.net/emea/v3/conversations/19:[RestOfYourChannelId]/activities

您将post发送如下消息:

{
  "type": "message",
  "from": {
    "id": "28:[rest of bot user id]",
    "name": "[bot name]"
  },
  "conversation": {
    "isGroup": true,
    "conversationType": "channel",
    "id": "19:[RestOfYourChannelId]"
  },
  "text": "Test Message"
}

但是,要 post 该端点,您需要对其进行正确的身份验证。可以这样做并直接与端点通信,但实际上使用内置机制更容易。这意味着在首次将机器人安装到频道时获取并存储对话参考。 This file shows how to do that (see how it gets and stores the conversationReference in the this.onConversationUpdate function). In that same sample, in a different file, it shows how to use that conversation reference to actually send the pro-active message - see here,其中使用 adapter.continueConversation.

Microsoft 机器人团队的一名成员也在 here 中详细展示了这一点。他还添加了 MicrosoftAppCredentials.trustServiceUrl(ref.serviceUrl);,这在某些情况下可能是必要的(如果您遇到安全问题,请尝试一下)。

那 - 应该 - 满足你的需要,所以试一试吧,如果你仍然遇到困难,请告诉我。

好的,所以,这就是我让它工作的方式。我把它张贴在这里以供将来参考。

免责声明:我仍然不知道如何将它与 botbuilder 一起使用,正如我最初的问题中所问的那样,这个答案将使用 ConnectorClient,这是可以接受的(至少对我而言)。根据 Hilton 的指示和我之前看到的 GitHub 问题 ( https://github.com/OfficeDev/BotBuilder-MicrosoftTeams/issues/162#issuecomment-434978847 ),我终于成功了。 MS 文档没有那么有用,因为它们总是使用 context 变量,当您的 Bot 响应消息或 activity 时可用,并且当 Bot [=] 时,它们会在内部记录这些上下文46=]。但是,如果您的 Bot 由于某种原因重新启动,或者您想将数据存储在数据库中以备后用,这就是解决方法。

所以,代码(NodeJS):

const path = require('path');
const { ConnectorClient, MicrosoftAppCredentials } = require('botframework-connector');

const ENV_FILE = path.join(__dirname, '.env');
require('dotenv').config({ path: ENV_FILE });

const serviceUrl = 'https://smba.trafficmanager.net/emea/';

async function sendToChannel() {
    MicrosoftAppCredentials.trustServiceUrl(serviceUrl);

    var credentials = new MicrosoftAppCredentials(process.env.MicrosoftAppId, process.env.MicrosoftAppPassword);
    var client = new ConnectorClient(credentials, { baseUri: serviceUrl });

    var conversationResponse = await client.conversations.createConversation({
        bot: {
            id: process.env.MicrosoftAppId,
            name: process.env.BotName
        },
        isGroup: true,
        conversationType: "channel",
        channelData: {
            channel: { id: "19:XXX@thread.tacv2" }
        },
        activity: {
            type: 'message',
            text: 'This a message from Bot Connector Client (NodeJS)'
        }
    });

}

sendToChannel();

注意:正如 Hilton 指出的那样,serviceUrl 也需要从您的数据库中加载,以及频道ID。它在 activity 中可用,当您的 Bot 添加到团队/频道/组时,您最初会收到 channelId 以及您也需要的 channelId ,并且您需要存储它们以供将来参考(不要像示例中那样对它们进行硬编码)。

所以,没有单独的createConversationsendActivity,都是一次调用。

感谢希尔顿抽出宝贵时间,并将 我手的模糊图像 发送给 MS 文档 :)

希望这对其他人有帮助