I have a bot that is working fine in Bot emulator with all its LUIS,QnAMaker and Dispatch. I have many intents including Help which all works perfectly in Bot Emulator but when published on azure and messenger, Anything i type it only returns two intents, Cancel and sometimes None Intent.
In Messenger after publishing in Azure
MainDialog: (Dialog A and Dialog B is same as maindialog but inherits ComponentDialog instead of InterruptDialog)
public class MainDialog : InterruptDialog
{
private const string InitialId = nameof(MainDialog);
public MainDialog()
: base(nameof(MainDialog))
{
InitialDialogId = InitialId;
WaterfallStep[] waterfallSteps = new WaterfallStep[]
{
FirstStepAsync,
SecondStepAsync,
};
AddDialog(new WaterfallDialog(InitialId, waterfallSteps));
AddDialog(new ChoicePrompt(nameof(ChoicePrompt)));
AddDialog(new TextPrompt(nameof(TextPrompt)));
AddDialog(new DialogA());
AddDialog(new DialogB());
}
private async Task<DialogTurnResult> FirstStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
await stepContext.Context.SendActivityAsync("<Start of MainDialog>");
return await stepContext.PromptAsync(
nameof(ChoicePrompt),
new PromptOptions
{
Prompt = MessageFactory.Text($"What do you want to do next?"),
Choices = new List<Choice>
{
new Choice
{
Value = "Nothing",
Synonyms = new List<string>
{
"nothing",
},
},
},
RetryPrompt = MessageFactory.Text($"Please choose one of the options."),
});
}
private static async Task<DialogTurnResult> SecondStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken = default(CancellationToken))
{
await stepContext.Context.SendActivityAsync("End of Main");
return await stepContext.EndDialogAsync();
}
Interrupt Dialog:
public class InterruptDialog : ComponentDialog
{
public InterruptDialog(string id)
: base(id)
{
}
protected override async Task<DialogTurnResult> OnBeginDialogAsync(DialogContext innerDc, object options, CancellationToken cancellationToken = default(CancellationToken))
{
var result = await IsTurnInterruptedAsyncHelpAndCancel(innerDc, cancellationToken);
if (result != null)
{
return result;
}
return await base.OnBeginDialogAsync(innerDc, options, cancellationToken);
}
protected override async Task<DialogTurnResult> OnContinueDialogAsync(DialogContext innerDc, CancellationToken cancellationToken = default)
{
var result = await IsTurnInterruptedAsyncHelpAndCancel(innerDc, cancellationToken);
if (result != null)
{
return result;
}
return await base.OnContinueDialogAsync(innerDc, cancellationToken);
}
private async Task<DialogTurnResult> IsTurnInterruptedAsyncHelpAndCancel(DialogContext innerDc, CancellationToken cancellationToken)
{
var recognizerResult = innerDc.Context.TurnState.Get<RecognizerResult>("recognizerResult");
string topIntent = string.Empty;
var luisResult = recognizerResult.Properties["luisResult"] as LuisResult;
var result = luisResult.ConnectedServiceResult;
if(result != null)
{
topIntent = result.TopScoringIntent.Intent;
}
if (topIntent.Equals("MainDialog"))
{
if (innerDc.ActiveDialog != null)
{
await innerDc.CancelAllDialogsAsync();
await innerDc.BeginDialogAsync(nameof(MainDialog));
}
else
{
await innerDc.BeginDialogAsync(nameof(MainDialog));
}
return new DialogTurnResult(DialogTurnStatus.Waiting);
}
if (topIntent.Equals("DialogB"))
{
if (innerDc.ActiveDialog != null)
{
await innerDc.CancelAllDialogsAsync();
await innerDc.BeginDialogAsync(nameof(DialogB));
}
else
{
await innerDc.BeginDialogAsync(nameof(DialogB));
}
return new DialogTurnResult(DialogTurnStatus.Waiting);
}
if (topIntent.Equals("DialogA"))
{
if (innerDc.ActiveDialog != null)
{
await innerDc.CancelAllDialogsAsync();
await innerDc.BeginDialogAsync(nameof(DialogA));
}
else
{
await innerDc.BeginDialogAsync(nameof(DialogA));
}
return new DialogTurnResult(DialogTurnStatus.Waiting);
}
if (topIntent.Equals("Cancel"))
{
if (innerDc.ActiveDialog != null)
{
await innerDc.CancelAllDialogsAsync();
await innerDc.Context.SendActivityAsync("???? Ok. I've cancelled our last activity.");
}
else
{
await innerDc.Context.SendActivityAsync("I don't have anything to cancel.");
}
return new DialogTurnResult(DialogTurnStatus.Waiting);
}
if (topIntent.Equals("Help"))
{
await innerDc.Context.SendActivityAsync("Let me help you. ????");
if (innerDc.ActiveDialog != null)
{
await innerDc.RepromptDialogAsync();
}
return new DialogTurnResult(DialogTurnStatus.Waiting);
}
return null;
}
}
}
Botservice
public class BotServices : IBotServices
{
public BotServices(IConfiguration configuration)
{
DispatchService = new LuisRecognizer(new LuisApplication(
configuration["DispatchLuisAppId"],
configuration["DispatchLuisAPIKey"],
$"https://{configuration["DispatchLuisAPIHostName"]}"),
new LuisPredictionOptions { IncludeAllIntents = true, IncludeInstanceData = true },
true);
LuisService = new LuisRecognizer(new LuisApplication(
configuration["LuisAppId"],
configuration["LuisAPIKey"],
$"https://{configuration["LuisAPIHostName"]}"),
new LuisPredictionOptions { IncludeAllIntents = true, IncludeInstanceData = true },
true);
QnaService = new QnAMaker(new QnAMakerEndpoint
{
KnowledgeBaseId = configuration["QnAKnowledgebaseId"],
EndpointKey = configuration["QnAEndpointKey"],
Host = configuration["QnAEndpointHostName"]
});
}
public LuisRecognizer DispatchService { get; private set; }
public LuisRecognizer LuisService { get; private set; }
public QnAMaker QnaService { get; private set; }
}
DialogBot
public class DialogBot<T> : ActivityHandler
where T : Dialog
{
public readonly IStatePropertyAccessor<DialogState> _dialogAccessor;
protected readonly Dialog Dialog;
protected readonly BotState ConversationState;
protected readonly BotState UserState;
protected readonly ILogger Logger;
private readonly IBotServices BotServices;
private DialogSet Dialogs { get; set; }
public DialogBot(IBotServices botServices, ConversationState conversationState, UserState userState, T dialog, ILogger<DialogBot<T>> logger)
{
ConversationState = conversationState;
UserState = userState;
Dialog = dialog;
Logger = logger;
BotServices = botServices;
Dialogs = new DialogSet(conversationState.CreateProperty<DialogState>(nameof(DialogBot<T>)));
RegisterDialogs(Dialogs);
}
public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
{
await base.OnTurnAsync(turnContext, cancellationToken);
var recognizerResult = turnContext.TurnState.Get<RecognizerResult>("recognizerResult");
var topIntent = turnContext.TurnState.Get<string>("topIntent");
var dc = await Dialogs.CreateContextAsync(turnContext, cancellationToken);
var dialogResult = await dc.ContinueDialogAsync();
if (!dc.Context.Responded)
{
switch (dialogResult.Status)
{
case DialogTurnStatus.Empty:
await DispatchToTopIntentAsync(turnContext, topIntent, recognizerResult, cancellationToken);
break;
case DialogTurnStatus.Waiting:
break;
case DialogTurnStatus.Complete:
await dc.EndDialogAsync();
break;
default:
await dc.CancelAllDialogsAsync();
break;
}
}
}
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
Logger.LogInformation("Running dialog with Message Activity.");
string text = string.IsNullOrEmpty(turnContext.Activity.Text) ? string.Empty : turnContext.Activity.Text.ToLower();
if (!string.IsNullOrEmpty(text))
{
var recognizerResult = await BotServices.DispatchService.RecognizeAsync(turnContext, cancellationToken);
var topIntent = recognizerResult.GetTopScoringIntent();
var luisResult = recognizerResult.Properties["luisResult"] as LuisResult;
var result = luisResult.ConnectedServiceResult;
var topLuisIntent = result.TopScoringIntent.Intent;
turnContext.TurnState.Add("topIntent", topIntent.intent);
turnContext.TurnState.Add("recognizerResult", recognizerResult);
}
await Dialog.RunAsync(turnContext, ConversationState.CreateProperty<DialogState>("DialogState"), cancellationToken);
}
private void RegisterDialogs(DialogSet dialogs)
{
dialogs.Add(new MainDialog());
dialogs.Add(new DialogA());
dialogs.Add(new DialogB());
}
private async Task DispatchToTopIntentAsync(ITurnContext turnContext, string intent, RecognizerResult recognizerResult, CancellationToken cancellationToken)
{
switch (dispatch)
{
case "q_thisAzureBotQna":
await DispatchToQnAMakerAsync(turnContext, cancellationToken);
break;
case "l_thisAzureBot-953e":
await DispatchToLuisModelAsync(turnContext, recognizerResult.Properties["luisResult"] as LuisResult, cancellationToken);
break;
}
}
private async Task DispatchToQnAMakerAsync(ITurnContext turnContext, CancellationToken cancellationToken)
{
if (!string.IsNullOrEmpty(turnContext.Activity.Text))
{
var results = await BotServices.QnaService.GetAnswersAsync(turnContext);
if (results.Any())
{
await turnContext.SendActivityAsync(MessageFactory.Text(results.First().Answer), cancellationToken);
}
else
{
await turnContext.SendActivityAsync(MessageFactory.Text("Sorry, could not find an answer in the Q and A system."), cancellationToken);
}
}
}
private async Task DispatchToLuisModelAsync(ITurnContext turnContext, LuisResult luisResult, CancellationToken cancellationToken)
{
var result = luisResult.ConnectedServiceResult;
var topIntent = result.TopScoringIntent.Intent;
switch (topIntent)
{
case "Greeting":
Random r = new Random();
var x = r.Next(1, 3);
switch (x)
{
case 1:
await turnContext.SendActivityAsync(MessageFactory.Text($"Hi!"));
break;
case 2:
await turnContext.SendActivityAsync(MessageFactory.Text($"Hello!"));
break;
case 3:
await turnContext.SendActivityAsync(MessageFactory.Text($"Hey!"));
break;
default:
break;
}
break;
default:
break;
}
}
}
}
Startup:
public class Startup
{
public Startup()
{
}
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<ICredentialProvider, ConfigurationCredentialProvider>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithErrorHandler>();
services.AddSingleton<IStorage, MemoryStorage>();
services.AddSingleton<UserState>();
services.AddSingleton<ConversationState>();
services.AddSingleton<IBotServices, BotServices>();
services.AddTransient<MainDialog>();
services.AddTransient<IBot, DialogBot<MainDialog>>();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseMvc();
}
}
}