Microsoft Bot - Node SDK:如何 post 到 public 频道 *而不回复上一个。 activity*
Microsoft Bot - Node SDK: How to post to a public channel *without replying to a prev. activity*
背景与理论
根据 the docs and examples,您必须保存对对话的引用以便按需恢复它(例如当服务器收到 HTTP 请求时)并向 public频道。
所以我在做:
- 任何用户在频道中提及机器人(例如
#CorpChannel
)
- Bot 存储(特别是我正在使用 Azure Cosmos db)对话的引用(
storage.write(storeItems)
)
- [later] Bot 收到一个 HTTP 请求,意思是:"send 'hi there' to #CorpChannel"
- Bot 恢复对话引用并将其用于创建
TurnContext
以便调用 sendActivity()
问题
activity 'hi there' 正在回复我的机器人最初提到的内容,而不是通过该频道启动新的 thread/conversation。我想在#CorpChannel开始一个新的对话
视觉上:
Jane Doe: --------------
| @MyBot 09:00AM |
------------------------
Jhon Doe: --------------
| what ever 10:00AM |
------------------------
HTTP 请求:"send 'hi there' to #CorpChannel"
Jhon Doe: --------------
| whatever 10:00AM |
------------------------
Jane Doe: --------------
| @MyBot 09:00AM |
------------------------
|> MyBot: -----------
| Hi there 11:00AM |
--------------------
我试过的
这是我按需发送 activity 的代码
server.post("/api/notify", async (req, res) => {
const channel = req.body.channel;
const message = req.body.message;
const conversation = await bot.loadChannelConversation(channel);
if (!conversation) { /* ... */ }
await adapter.continueConversation(conversation, async (context) => {
await context.sendActivity(message);
});
return res.send({ notified: { channel, message } });
});
这是我要去数据库的代码
// (storage) is in the scope
const loadChannelConversation = async (key) => {
try {
const storeItems = await storage.read(['channels']);
const channels = storeItems['channels'] || {};
return channels[key] || null;
} catch (err) {
console.error(err);
return undefined;
}
};
如何 post 一条新消息而不是回复原始线程?
==== 编辑 ====
我也尝试过使用 SDK 中的 createConversation()
方法,但正如文档中所述:
The Bot Connector service supports the creating of group conversations; however, this method and most channels only support initiating a direct message (non-group) conversation.
它与 post 私下 私下发送第一条消息的原始用户开始新对话
Teams 频道线程中的对话 ID 如下所示:19:1234abcd@thread.tacv2;messageid=12345
要开始一个新线程,您需要做的就是向该对话 ID 发送一条消息,并删除 "messageid" 部分。
您可以像这样删除 messageid 部分:
function getRootConversationId(turnContext) {
const threadId = turnContext.activity.conversation.id;
const messageIdIndex = threadId.indexOf(";messageid=");
return messageIdIndex > 0 ? threadId.slice(0, messageIdIndex) : threadId;
}
如果要通过turn context发送消息保留其中间件管道,可以直接修改传入activity的会话ID。由于这会影响回合剩余时间的回合上下文,因此最好在之后将对话 ID 改回原来的状态。
const conversationId = getRootConversationId(turnContext);
// Send through the turn context
const conversation = turnContext.activity.conversation;
const threadId = conversation.id;
conversation.id = conversationId;
await turnContext.sendActivity("New thread (through the turn context)");
conversation.id = threadId; // restore conversation ID
如果您不想担心转向上下文,您也可以直接通过连接器客户端发送消息。
const conversationId = getRootConversationId(turnContext);
// Send through a connector client
const client = turnContext.turnState.get(turnContext.adapter.ConnectorClientKey);
await client.conversations.sendToConversation(
conversationId,
MessageFactory.text("New thread (through a connector client)"));
背景与理论
根据 the docs and examples,您必须保存对对话的引用以便按需恢复它(例如当服务器收到 HTTP 请求时)并向 public频道。
所以我在做:
- 任何用户在频道中提及机器人(例如
#CorpChannel
) - Bot 存储(特别是我正在使用 Azure Cosmos db)对话的引用(
storage.write(storeItems)
) - [later] Bot 收到一个 HTTP 请求,意思是:"send 'hi there' to #CorpChannel"
- Bot 恢复对话引用并将其用于创建
TurnContext
以便调用sendActivity()
问题
activity 'hi there' 正在回复我的机器人最初提到的内容,而不是通过该频道启动新的 thread/conversation。我想在#CorpChannel开始一个新的对话
视觉上:
Jane Doe: --------------
| @MyBot 09:00AM |
------------------------
Jhon Doe: --------------
| what ever 10:00AM |
------------------------
HTTP 请求:"send 'hi there' to #CorpChannel"
Jhon Doe: --------------
| whatever 10:00AM |
------------------------
Jane Doe: --------------
| @MyBot 09:00AM |
------------------------
|> MyBot: -----------
| Hi there 11:00AM |
--------------------
我试过的
这是我按需发送 activity 的代码
server.post("/api/notify", async (req, res) => {
const channel = req.body.channel;
const message = req.body.message;
const conversation = await bot.loadChannelConversation(channel);
if (!conversation) { /* ... */ }
await adapter.continueConversation(conversation, async (context) => {
await context.sendActivity(message);
});
return res.send({ notified: { channel, message } });
});
这是我要去数据库的代码
// (storage) is in the scope
const loadChannelConversation = async (key) => {
try {
const storeItems = await storage.read(['channels']);
const channels = storeItems['channels'] || {};
return channels[key] || null;
} catch (err) {
console.error(err);
return undefined;
}
};
如何 post 一条新消息而不是回复原始线程?
==== 编辑 ====
我也尝试过使用 SDK 中的 createConversation()
方法,但正如文档中所述:
The Bot Connector service supports the creating of group conversations; however, this method and most channels only support initiating a direct message (non-group) conversation.
它与 post 私下 私下发送第一条消息的原始用户开始新对话
Teams 频道线程中的对话 ID 如下所示:19:1234abcd@thread.tacv2;messageid=12345
要开始一个新线程,您需要做的就是向该对话 ID 发送一条消息,并删除 "messageid" 部分。
您可以像这样删除 messageid 部分:
function getRootConversationId(turnContext) {
const threadId = turnContext.activity.conversation.id;
const messageIdIndex = threadId.indexOf(";messageid=");
return messageIdIndex > 0 ? threadId.slice(0, messageIdIndex) : threadId;
}
如果要通过turn context发送消息保留其中间件管道,可以直接修改传入activity的会话ID。由于这会影响回合剩余时间的回合上下文,因此最好在之后将对话 ID 改回原来的状态。
const conversationId = getRootConversationId(turnContext);
// Send through the turn context
const conversation = turnContext.activity.conversation;
const threadId = conversation.id;
conversation.id = conversationId;
await turnContext.sendActivity("New thread (through the turn context)");
conversation.id = threadId; // restore conversation ID
如果您不想担心转向上下文,您也可以直接通过连接器客户端发送消息。
const conversationId = getRootConversationId(turnContext);
// Send through a connector client
const client = turnContext.turnState.get(turnContext.adapter.ConnectorClientKey);
await client.conversations.sendToConversation(
conversationId,
MessageFactory.text("New thread (through a connector client)"));