C# 继续当前对话框的Microsoft Bot Framework主动消息
Microsoft bot框架中有主动消息的概念-> 在我的解决方案中,我使用多个不同的对话框,在数据库中存储一些数据,每个回合都会加载这些数据。根据数据库中的数据,状态对象将被修改,根据修改情况,对话框将继续 在我的例子中,用户A启动对话框,系统以“我将您放入队列”响应,然后一段时间后B启动对话框,并询问他是否应与A配对。在用户B确认后,用户A的对话框应继续 我可以像下面这样给他写一条简单的消息,但我不知道如何简单地为匹配的用户强制一个新的“转向”,这样对话框就可以继续了C# 继续当前对话框的Microsoft Bot Framework主动消息,c#,botframework,C#,Botframework,Microsoft bot框架中有主动消息的概念-> 在我的解决方案中,我使用多个不同的对话框,在数据库中存储一些数据,每个回合都会加载这些数据。根据数据库中的数据,状态对象将被修改,根据修改情况,对话框将继续 在我的例子中,用户A启动对话框,系统以“我将您放入队列”响应,然后一段时间后B启动对话框,并询问他是否应与A配对。在用户B确认后,用户A的对话框应继续 我可以像下面这样给他写一条简单的消息,但我不知道如何简单地为匹配的用户强制一个新的“转向”,这样对话框就可以继续了 公共类基本bot:I
公共类基本bot:IBot
{
//一些性质
public BasicBot(CustomBotState botState、BotServices服务、UserState UserState、ConversationState ConversationState、ILoggerFactory loggerFactory、EndpointService EndpointService)
{
//设置一些属性
_conversationReferenceAccessor=_botState.CreateProperty(nameof(MatchConversationReference));
_dialogStateAccessor=_conversationState.CreateProperty(nameof(DialogState));
_matchStateAccessor=_userState.CreateProperty(nameof(MatchState));
var appId=string.IsNullOrWhiteSpace(endpointService.appId)?“1”:endpointService.appId;
Dialogs=新的DialogSet(_dialogStateAccessor);
添加(新的MatchDialog(_matchStateAccessor,loggerFactory,services,appId,_conversationReferenceAccessor));
}
私有对话框集对话框{get;set;}
公共异步任务OnTurnAsync(ITurnContext turnContext,CancellationToken CancellationToken)
{
var dialogContext=await Dialogs.CreateContextAsync(turnContext);
if(turnContext.Activity.Type==ActivityTypes.Message)
{
var dialogResult=await dialogContext.ContinueDialogAsync();
如果(!dialogContext.Context.responsed)
{
var match=LoadMatchFromDatabase();
wait dialogContext.BeginDialogAsync(nameof(MatchDialog),match);
}
}
//保存对话、用户、机器人的状态
}
}
公共类匹配对话框:ComponentDialog
{
//一些性质
公共匹配对话框(IStatePropertyAccessor状态访问器、ILoggerFactory loggerFactory、BotServices服务、字符串appId、IStatePropertyAccessor(iMatchConversationPropertyAccessor)
:base(名称(匹配对话框))
{
//设置一些属性
var waterwallsteps=新的waterwallstep[]
{
初始化TestePasync,
WaitForAnswer,
};
AddDialog(新建WaterWallDialog(名称(匹配对话框),WaterWallSteps));
}
私有异步任务WaitForAnswer(WaterWallStepContext步骤,CancellationToken CancellationToken)
{
var otherUser=wait GetOtherUser(步骤);
var conversations=wait GetMatchConversion(steps.Context);
if(conversations.ContainsKey(otherUser.Identifier))
{
等待步骤.Context.Adapter.ContinueConversationAsync(AppId,conversations[otherUser.Identifier],
异步(turnContext,令牌)=>
{
Wait turnContext.SendActivityAsync($“为您找到某人”);
},
取消令牌);
}
}
专用异步任务初始化EstaTestePasync(WaterWallStepContext stepContext,CancellationToken CancellationToken)
{
var state=await StateAccessor.GetAsync(stepContext.Context,()=>null);
var match=stepContext。选项作为匹配项;
if(state==null)
{
wait StateAccessor.SetAsync(stepContext.Context,new MatchState(){Match=Match});
}
else if(state.Match==null | | Match.Id!=state.Match.Id)
{
state.Match=Match;
}
返回wait-stepContext.NextAsync();
}
}
}有几种方法可以做到这一点,具体取决于您的代码。基本上,在发送发现用户B的主动消息的同一位置,您需要调用
dc.ContinueDialogAsync()
或dc.repromtDialogAsync()
,如适用
话虽如此,我认为最好的选择是分割对话。一个对话框获取队列中的用户A。一旦进入,它们就不再处于对话框中。一旦找到用户B,它将向用户A发送新对话框
我通过以下方式或多或少地做到了这一点:
CreateCallback()
下(此示例在此处主动发送消息),我在该方法的末尾添加了以下代码(出于某些原因,它不希望格式化为代码)://sample how I write something into the other conversation
var conversations = await GetMatchConversion(steps.Context);
if (conversations.ContainsKey(otherUser.Identifier))
{
await steps.Context.Adapter.ContinueConversationAsync(AppId, conversations[otherUser.Identifier],
async (turnContext, token) =>
{
// Send the user a proactive confirmation message.
await turnContext.SendActivityAsync($"{currentUser.Display()} I found a matching user...");
var dc = await Dialogs.CreateContextAsync(turnContext);
await dc.BeginDialogAsync(nameof(UserFoundDialog));
},
cancellationToken);
}
为了澄清这一点,UserA启动了一个对话框,在这个对话框中,用户被输入到一个队列中。当找到UserB并可以与UserA配对时,UserA会收到通知,表示已找到UserB。然后,您希望与UserA的对话继续。对吗?对,对。在我的例子中,用户A启动对话框,系统以“我将您放入队列”响应,然后一段时间后B启动对话框,并询问他是否应与A配对。在用户B确认后,用户A的对话框应继续。->我用这个简短的描述更新了描述。我已经有两个独立的对话框,一个QueueDialog和一个MatchDialog。我一直认为我需要用户状态o