BotBuilder Node.js SDK:如何将URL参数绑定到机器人会话
如何将URL参数绑定到Bot Session中
当然可以实现!你只需要在Bot的消息处理端点捕获URL查询参数,然后将其存储到Bot的用户状态(或会话状态)中,这样就能在后续对话里通过状态对象获取到这个参数值了。下面分不同SDK语言给你具体的实现步骤:
C# (Bot Framework SDK v4)
1. 定义状态类
首先创建一个用于存储用户偏好的类,用来保存发音设置:
public class UserPreferences { public string Pronunciation { get; set; } }
2. 注册状态服务
在Startup.cs中注册用户状态和对应的属性访问器,让Bot能持久化存储这个参数:
using Microsoft.Bot.Builder; using Microsoft.Bot.Builder.Integration.AspNet.Core; public void ConfigureServices(IServiceCollection services) { // 注册Bot适配器 services.AddHttpClient<BotFrameworkHttpAdapter>(); // 注册用户状态(示例用内存存储,生产环境建议替换为Azure Cosmos DB/Blob Storage等持久化存储) services.AddSingleton<UserState>(); services.AddSingleton(sp => { var userState = sp.GetRequiredService<UserState>(); // 创建访问UserPreferences的属性访问器 return userState.CreateProperty<UserPreferences>("UserPreferences"); }); // 注册你的Bot业务类 services.AddTransient<IBot, YourBotClass>(); }
3. 在消息控制器中捕获并存储URL参数
在处理/api/messages请求的控制器里,从HttpRequest中拿到查询参数,并存入用户状态:
using Microsoft.AspNetCore.Mvc; using Microsoft.Bot.Builder; using Microsoft.Bot.Builder.Integration.AspNet.Core; using System.Threading.Tasks; [Route("api/messages")] [ApiController] public class MessagesController : ControllerBase { private readonly IBotFrameworkHttpAdapter _adapter; private readonly IBot _bot; private readonly IServiceProvider _services; public MessagesController(IBotFrameworkHttpAdapter adapter, IBot bot, IServiceProvider services) { _adapter = adapter; _bot = bot; _services = services; } [HttpPost] public async Task PostAsync() { // 先处理Bot的常规消息流程 await _adapter.ProcessAsync(Request, Response, _bot); // 获取URL中的pronuntiation参数 var pronunciation = Request.Query["pronuntiation"].ToString(); if (!string.IsNullOrEmpty(pronunciation)) { // 获取用户状态访问器 var userPreferencesAccessor = _services.GetRequiredService<IStatePropertyAccessor<UserPreferences>>(); // 解析当前对话上下文 var activity = await Activity.ReadFromStreamAsync(Request.Body, HttpContext.RequestAborted); var turnContext = new TurnContext(_adapter, activity); // 读取或初始化用户偏好 var userPreferences = await userPreferencesAccessor.GetAsync(turnContext, () => new UserPreferences()); // 更新发音设置 userPreferences.Pronunciation = pronunciation; // 保存状态 await userPreferencesAccessor.SetAsync(turnContext, userPreferences); await _services.GetRequiredService<UserState>().SaveChangesAsync(turnContext); } } }
4. 在Bot对话中获取参数
在你的Bot业务逻辑类中,随时可以从用户状态里取出这个参数:
using Microsoft.Bot.Builder; using Microsoft.Bot.Schema; using System.Threading; using System.Threading.Tasks; public class YourBotClass : ActivityHandler { private readonly IStatePropertyAccessor<UserPreferences> _userPreferencesAccessor; public YourBotClass(IStatePropertyAccessor<UserPreferences> userPreferencesAccessor) { _userPreferencesAccessor = userPreferencesAccessor; } protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken) { // 获取用户的发音设置,默认值设为"default" var userPreferences = await _userPreferencesAccessor.GetAsync(turnContext, () => new UserPreferences()); var selectedPronunciation = userPreferences.Pronunciation ?? "default"; // 用这个参数做业务逻辑,比如回复用户当前设置 await turnContext.SendActivityAsync(MessageFactory.Text($"当前发音设置为:{selectedPronunciation}"), cancellationToken); } }
Node.js (Bot Framework SDK v4)
1. 配置状态存储
先初始化用户状态和属性访问器:
const restify = require('restify'); const { BotFrameworkAdapter, UserState, MemoryStorage } = require('botbuilder'); // 创建服务器 const server = restify.createServer(); server.listen(process.env.port || process.env.PORT || 3978, () => { console.log(`${server.name} listening to ${server.url}`); }); // 初始化适配器 const adapter = new BotFrameworkAdapter({ appId: process.env.MicrosoftAppId, appPassword: process.env.MicrosoftAppPassword }); // 初始化内存存储(生产环境替换为持久化存储) const memoryStorage = new MemoryStorage(); const userState = new UserState(memoryStorage); // 创建用户偏好的属性访问器 const userPreferencesAccessor = userState.createProperty('UserPreferences');
2. 捕获URL参数并存入状态
在处理/api/messages的路由中,获取查询参数并保存到用户状态:
server.post('/api/messages', async (req, res) => { // 获取URL中的pronuntiation参数 const pronunciation = req.query.pronuntiation; await adapter.processActivity(req, res, async (turnContext) => { if (pronunciation) { // 获取或初始化用户偏好 const userPreferences = await userPreferencesAccessor.get(turnContext, {}); // 更新发音设置 userPreferences.pronunciation = pronunciation; // 保存状态 await userPreferencesAccessor.set(turnContext, userPreferences); await userState.saveChanges(turnContext); } // 处理用户消息 if (turnContext.activity.type === 'message') { const userPreferences = await userPreferencesAccessor.get(turnContext, {}); const selectedPronunciation = userPreferences.pronunciation || 'default'; await turnContext.sendActivity(`当前发音设置为:${selectedPronunciation}`); } }); });
关键注意事项
- 持久化存储:示例用了内存存储(
MemoryStorage),但生产环境一定要换成Azure Cosmos DB、Azure Blob Storage等持久化存储,避免Bot重启后丢失状态。 - 参数更新逻辑:如果用户通过不同参数的URL进入对话,记得根据业务需求判断是否需要覆盖已有的设置,或者只在首次会话时保存。
- Web Chat集成:如果是通过Web Chat嵌入网页,确保初始化Web Chat时的请求URL包含该参数,这样Bot端点才能接收到。
内容的提问来源于stack exchange,提问作者Luis Pablo Linietsky
相关产品推荐
相关产品推荐

