Bot Framework(Node.js)从Cosmos DB获取用户地址实现主动消息发送咨询
解决Bot从Cosmos DB获取用户注册地址并主动发送消息的问题
嘿,我来帮你搞定这个问题!既然你已经完成了Bot和Cosmos DB的基础配置,那接下来核心就是从Cosmos里查询用户注册时存入的地址,再用这个地址主动发消息。咱一步步来:
1. 先确认Cosmos里的用户数据结构
首先,你在//REGISTER流程里存入用户地址时,要确保数据存在Cosmos的文档里,结构大概是这样(以常见的Bot Framework存储格式为例):
{ "id": "some-unique-id", "userId": "user-123", // 用户的唯一标识,比如Bot里的From.Id "registeredAddress": "用户注册时填的地址信息", // 自定义的存储字段,名字你可以按需改 "partitionKey": "user-123" // 对应Cosmos的分区键,Bot默认用userId }
👉 注册流程里一定要把地址写入这个字段,比如在收集用户地址的Dialog里,通过UserState或者直接操作Cosmos容器来存储。
2. 从Cosmos查询用户注册地址的代码示例
C#版本(基于Bot Framework SDK v4)
你已经有CosmosClient实例(配置Bot和Cosmos连接时应该已经注入了),直接用它查询指定用户的地址:
// 替换成你的数据库和容器名称 var container = cosmosClient.GetContainer("YourBotDatabase", "YourBotContainer"); // 目标用户的ID,比如注册时记录的userId var targetUserId = "user-123"; // 构建查询语句,精准获取注册地址 var query = new QueryDefinition("SELECT c.registeredAddress FROM c WHERE c.userId = @userId") .WithParameter("@userId", targetUserId); using var iterator = container.GetItemQueryIterator<string>(query); while (iterator.HasMoreResults) { var response = await iterator.ReadNextAsync(); if (response.Any()) { var userRegisteredAddress = response.First(); // 拿到地址后,用Adapter主动发送消息 await adapter.ContinueConversationAsync(botAppId, userRegisteredAddress, async (turnContext, cancellationToken) => { await turnContext.SendActivityAsync($"嘿,这是用你注册时的地址发来的消息哦!"); }, cancellationToken); } }
JavaScript/TypeScript版本
复用已配置的CosmosClient,写个简单的查询函数:
const { CosmosClient } = require("@azure/cosmos"); // 初始化客户端(你应该已经在Bot配置里设置过环境变量) const cosmosClient = new CosmosClient({ endpoint: process.env.COSMOS_ENDPOINT, key: process.env.COSMOS_KEY }); const container = cosmosClient.database("YourBotDatabase").container("YourBotContainer"); // 查询用户注册地址的工具函数 async function getRegisteredAddress(userId) { const querySpec = { query: "SELECT c.registeredAddress FROM c WHERE c.userId = @userId", parameters: [{ name: "@userId", value: userId }] }; const { resources } = await container.items.query(querySpec).fetchAll(); return resources.length > 0 ? resources[0].registeredAddress : null; } // 主动发送消息的函数 async function sendMessageToRegisteredUser(adapter, botAppId, userId) { const userAddress = await getRegisteredAddress(userId); if (userAddress) { await adapter.continueConversationAsync(botAppId, userAddress, async (turnContext) => { await turnContext.sendActivity("这是用你注册时的地址发送的主动消息!"); }); } else { console.log("没找到该用户的注册地址哦"); } }
3. 关键注意事项
- 分区键匹配:Bot Framework默认用
userId作为Cosmos的分区键,查询时要确保WHERE条件和分区键一致,不然查询效率会大打折扣。 - 注册时的存储逻辑:在//REGISTER流程里,一定要把用户地址正确存入Cosmos文档的对应字段(比如上面的
registeredAddress),不然查不到数据。 - 主动消息的Adapter:主动发送消息必须用到Bot的
Adapter实例,以及Bot的App ID(Azure Bot Service里的Microsoft App ID),这些你在配置Bot和Cosmos连接时应该已经有了。
这样你就能获取到用户注册时存入的地址,实现跨会话的主动消息发送啦!
内容的提问来源于stack exchange,提问作者Richard Franek
相关产品推荐
相关产品推荐

