将主动消息发送到 Teams 中的频道
Sending proactive messages to a channel in Teams
所以,
我进行了广泛的搜索,阅读了我能找到的关于该主题的所有内容,但我仍然没有成功。我已经设法向用户发送主动消息,回复团队中的主题等,但我无法在团队频道中发送主动消息(创建新的post)。
是否有可用的示例(我找不到)? NodeJS 的 MS Docs 似乎显示了一个向团队中的每个用户发送消息的示例,而不是频道本身。
我研究了源代码,channelData
在 botFrameworkAdapter.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
,并且您需要存储它们以供将来参考(不要像示例中那样对它们进行硬编码)。
所以,没有单独的createConversation
和sendActivity
,都是一次调用。
感谢希尔顿抽出宝贵时间,并将 我手的模糊图像 发送给 MS 文档 :)
希望这对其他人有帮助
所以,
我进行了广泛的搜索,阅读了我能找到的关于该主题的所有内容,但我仍然没有成功。我已经设法向用户发送主动消息,回复团队中的主题等,但我无法在团队频道中发送主动消息(创建新的post)。
是否有可用的示例(我找不到)? NodeJS 的 MS Docs 似乎显示了一个向团队中的每个用户发送消息的示例,而不是频道本身。
我研究了源代码,channelData
在 botFrameworkAdapter.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
,并且您需要存储它们以供将来参考(不要像示例中那样对它们进行硬编码)。
所以,没有单独的createConversation
和sendActivity
,都是一次调用。
感谢希尔顿抽出宝贵时间,并将 我手的模糊图像 发送给 MS 文档 :)
希望这对其他人有帮助