【发布时间】:2019-07-20 05:49:00
【问题描述】:
微软bot框架中有主动消息的概念->https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-howto-proactive-message?view=azure-bot-service-4.0&tabs=csharp
我在我的解决方案中使用多个不同的对话框,我将一些数据存储在数据库中,这些数据每次都会加载。根据来自数据库的数据,状态对象被修改,并且根据该数据,对话框继续。
在我的情况下,用户 A 启动对话,系统响应“我将你放入队列”然后一段时间后 B 启动他的对话并询问他是否应该与 A 配对。用户 B 确认后,对话来自用户 A 应该继续。
我可以给他写一条如下所示的简单消息,但我不知道如何简单地为匹配的用户强制进行新的“转向”,以便对话继续。
public class BasicBot : IBot
{
// some properties
public BasicBot(CustomBotState botState, BotServices services, UserState userState, ConversationState conversationState, ILoggerFactory loggerFactory, EndpointService endpointService)
{
// set some properties
_conversationReferenceAccessor = _botState.CreateProperty<Dictionary<string, ConversationReference>>(nameof(MatchConversationReference));
_dialogStateAccessor = _conversationState.CreateProperty<DialogState>(nameof(DialogState));
_matchStateAccessor = _userState.CreateProperty<MatchState>(nameof(MatchState));
var appId = string.IsNullOrWhiteSpace(endpointService.AppId) ? "1" : endpointService.AppId;
Dialogs = new DialogSet(_dialogStateAccessor);
Dialogs.Add(new MatchDialog(_matchStateAccessor, loggerFactory, services, appId, _conversationReferenceAccessor));
}
private DialogSet Dialogs { get; set; }
public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken)
{
var dialogContext = await Dialogs.CreateContextAsync(turnContext);
if (turnContext.Activity.Type == ActivityTypes.Message)
{
var dialogResult = await dialogContext.ContinueDialogAsync();
if (!dialogContext.Context.Responded)
{
var match = LoadMatchFromDatabase();
await dialogContext.BeginDialogAsync(nameof(MatchDialog), match);
}
}
// save the state of conversation, user, bot
}
}
public class MatchDialog : ComponentDialog
{
// some properties
public MatchDialog(IStatePropertyAccessor<MatchState> stateAccessor, ILoggerFactory loggerFactory, BotServices services, string appId, IStatePropertyAccessor<Dictionary<string, ConversationReference>> _matchConversationPropertyAccessor)
: base(nameof(MatchDialog))
{
// set some properties
var waterfallSteps = new WaterfallStep[]
{
InitializeStateStepAsync,
WaitForAnswer,
};
AddDialog(new WaterfallDialog(nameof(MatchDialog), waterfallSteps));
}
private async Task<DialogTurnResult> WaitForAnswer(WaterfallStepContext steps, CancellationToken cancellationToken)
{
var otherUser = await GetOtherUser(steps);
var conversations = await GetMatchConversion(steps.Context);
if (conversations.ContainsKey(otherUser.Identifier))
{
await steps.Context.Adapter.ContinueConversationAsync(AppId, conversations[otherUser.Identifier],
async (turnContext, token) =>
{
await turnContext.SendActivityAsync($"Found someone for you");
},
cancellationToken);
}
}
private async Task<DialogTurnResult> InitializeStateStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
var state = await StateAccessor.GetAsync(stepContext.Context, () => null);
var match = stepContext.Options as Match;
if (state == null)
{
await StateAccessor.SetAsync(stepContext.Context, new MatchState() { Match = match });
}
else if (state.Match == null || match.Id != state.Match.Id)
{
state.Match = match;
}
return await stepContext.NextAsync();
}
}
}
【问题讨论】:
-
为了澄清,UserA 启动一个对话,并在此对话期间进入队列。当找到 UserB 并且可以与 UserA 配对时,会通知 UserA 找到 UserB。然后,您希望与 UserA 的对话继续。对吗?
-
是的,正确。在我的情况下,用户 A 开始对话,系统以“我将你放入队列”作为响应,然后一段时间后 B 开始他的对话并询问他是否应该与 A 配对。用户 B 确认后,来自用户的对话A 应该继续。 -> 我用这个简短的描述更新了描述
标签: c# botframework