Reputation: 7782
I am trying to write a simple bot that will start my waterfall dialog when the user enter something. The usecase is very simple but it just doesn't seem to work, what is wrong?
The main bot is setup as such, I try to call my dialog in the OnMessageActivityAsync function:
namespace EmptyBot1.Dialogs
{
public class MainChatbot : ActivityHandler
{
private readonly IOptions<Models.Configurations> _mySettings;
protected readonly IRecognizer _recognizer;
protected readonly BotState _conversationState;
public MainChatbot(ConversationState conversationState, IOptions<Models.Configurations> mySettings, ChatbotRecognizer recognizer)
{
_mySettings = mySettings ?? throw new ArgumentNullException(nameof(mySettings));
_recognizer = recognizer;
_conversationState = conversationState;
}
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
string LuisAppId = _mySettings.Value.LuisAppId;
string LuisAPIKey = _mySettings.Value.LuisAPIKey;
string LuisAPIHostName = _mySettings.Value.LuisAPIHostName;
await turnContext.SendActivityAsync(MessageFactory.Text($"You Said: {turnContext.Activity.Text}"), cancellationToken);
var luisResult = await _recognizer.RecognizeAsync<Models.ChatbotIntent>(turnContext, cancellationToken);
Models.ChatbotIntent.Intent TopIntent = luisResult.TopIntent().intent;
await turnContext.SendActivityAsync(MessageFactory.Text($"Your Intention Is: {TopIntent.ToString()}"), cancellationToken);
switch (TopIntent)
{
case Models.ChatbotIntent.Intent.RunBot:
var RunBotOptions = new Models.RunBotOptions();
Dialog d = new MyCustomDialog();
// Trying to start my dialog here.
await d.RunAsync(turnContext, _conversationState.CreateProperty<DialogState>(nameof(DialogState)), cancellationToken);
break;
default:
break;
}
return;
}
}
}
Then I setup my dialog like this, also simple enough:
namespace EmptyBot1.Dialogs
{
public class MyCustomDialog : InteruptsDialog
{
public MyCustomDialog()
: base(nameof(MyCustomDialog))
{
AddDialog(new TextPrompt(nameof(TextPrompt)));
AddDialog(new ConfirmPrompt(nameof(ConfirmPrompt)));
AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
{
AskName,
AskUseDefault,
FinalStep
}));
// The initial child Dialog to run.
InitialDialogId = nameof(WaterfallDialog);
}
// ...
}
}
Everything is injected in startup.cs
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
// Add functionality to inject IOptions<T>
services.AddOptions();
// Add our Config object so it can be injected
services.Configure<Models.Configurations>(Configuration);
// Create the Bot Framework Adapter with error handling enabled.
services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithErrorHandler>();
// Create the bot as a transient. In this case the ASP Controller is expecting an IBot.
services.AddTransient<IBot, Dialogs.MainChatbot>();
// Create the Conversation state. (Used by the Dialog system itself.)
var storage = new MemoryStorage();
var conversationState = new ConversationState(storage);
services.AddSingleton(conversationState);
// Register LUIS recognizer
services.AddSingleton<ChatbotRecognizer>();
services.AddSingleton<Dialogs.MyCustomDialog>();
}
But when I run it I get 500 error, what am I doing wrong?
EDIT: To clarify, my goal is to be able to start a hardcoded waterfall dialog directly from ActivityHandler.OnMessageActivityAsync
.
The general solution from online and from the example projects from Microsoft all say to pass the dialog as a type T to my bot.
However, I already know exactly which dialog to start so there is need to pass it as a type, I can just hardcode it directly inside the bot, how do I start it?
Upvotes: 1
Views: 1093
Reputation: 7782
Turn out my code seem to work fine, not sure why it wasn't working yesterday. I'll leave it for future people checking up on answers. You can just use it exactly as it is in the question.
Upvotes: 1
Reputation: 2227
From what I can see, you're not adding the bot itself when you add the bot in startup. you have
// Create the bot as a transient. In this case the ASP Controller is expecting an IBot.
services.AddTransient<IBot, Dialogs.MainChatbot>();
try:
// Create the bot as a transient. In this case the ASP Controller is expecting an IBot.
services.AddTransient<IBot, MainChatbot<MyCustomDialog>>();
In order to do this, you're going to have to change your MainChatBot. In your class delcaration, you have:
public class MainChatbot : ActivityHandler
change it to:
public class MainChatbot<T> : ActivityHandler
where T : Dialog
You have your main 'bot' there, but you're not calling a dialog until it gets a LUIS intent. But you can't call a LUIS intent until a dialog is started. Initialize your bot with a dialog instead, so your bot knows where to 'start' essentially.
Upvotes: 0