Я не могу понять, как сделать очень простую вещь в MS Bot Framework: позволить пользователю вырваться из любой беседы, оставить текущие диалоги и вернуться в главное меню, набрав "quit" , "exit" или "начать все".
Здесь, как мой основной разговор настроен:
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
try
{
if (activity.Type == ActivityTypes.Message)
{
UserActivityLogger.LogUserBehaviour(activity);
if (activity.Text.ToLower() == "start over")
{
//Do something here, but I don't have the IDialogContext here!
}
BotUtils.SendTyping(activity); //send "typing" indicator upon each message received
await Conversation.SendAsync(activity, () => new RootDialog());
}
else
{
HandleSystemMessage(activity);
}
}
Я знаю, как завершить диалог с context.Done<DialogType>(this);, но в этом методе у меня нет доступа к объекту IDialogContext, поэтому я не могу позвонить .Done().
Есть ли другой способ завершить весь стек диалогового окна, когда пользователь вводит определенное сообщение, кроме добавления проверки для этого на каждом шаге всех диалогов?
Добавлено баунти:
Мне нужен способ прервать все IDialog без использования возмутительного взлома, который я разместил здесь (который удаляет все пользовательские данные, которые мне нужны, например, пользовательские настройки и предпочтения).
В принципе, когда пользователь набирает "quit" или "exit", мне нужно выйти из того, что в настоящий момент выполняется IDialog, и вернуться в новое состояние, как будто пользователь только что начал разговор.
Мне нужно иметь возможность сделать это из MessageController.cs,, где я до сих пор не имею доступа к IDialogContext. Единственными полезными данными, которые у меня есть, является объект Activity. Я буду счастлив, если кто-то укажет на другие способы сделать это.
Еще один способ приблизиться к этому - найти другой способ проверить ключевые слова "exit" и "quit" в каком-либо другом месте бота, а не в методе Post.
Но это не должно быть проверкой, которая выполняется на каждом шаге IDialog, потому что слишком много кода и даже не всегда возможно (при использовании PromptDialog у меня нет доступа к тексту, который пользователь набрал).
Два возможных способа, которых я не исследовал:
- Вместо завершения всех текущих
IDialogs, запустите новый диалог с пользователем (новыйConversationId) - Получите объект
IDialogStackи сделайте что-нибудь с ним для управления стеке диалога.
Документы Microsoft молчат об этом объекте, поэтому я понятия не имею, как его получить. Я не использую объект Chain, который позволяет .Switch() находиться в любом месте бота, но если вы считаете, что его можно переписать для его использования, это может быть одним из способов его решения. Однако я не нашел, как делать разветвление между различными типами диалогов (FormFlow и обычный IDialog), которые, в свою очередь, вызывают их собственные дочерние диалоги и т.д.