Skip to content

Commit

Permalink
Merge pull request #325 from Microsoft/daveta-qnamaker-core
Browse files Browse the repository at this point in the history
QnA ASP Net Core sample's #12 and #22 (with AppInsights)
Added @cleemullins feedback in person.
  • Loading branch information
daveta authored Sep 6, 2018
2 parents b4f43f2 + 73067cf commit 7701c1f
Show file tree
Hide file tree
Showing 27 changed files with 710 additions and 216 deletions.
24 changes: 0 additions & 24 deletions csharp_dotnetcore/11.QnAMaker/AspNetCore-QnA-Bot.bot

This file was deleted.

25 changes: 20 additions & 5 deletions csharp_dotnetcore/11.QnAMaker/Program.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,36 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

namespace QnA_Bot
{
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;

namespace Microsoft.BotBuilderSamples
{
/// <summary>
/// This is an ASP.NET Core app that creates a webserver.
/// </summary>
public class Program
{
/// <summary>
/// This is the entry point for your application.
/// It is run first once your application is started.
/// This method creates a web server.
/// </summary>
/// <param name="args">Arguments for this method.</param>
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}

/// <summary>
/// Initializes a new instance of the <see cref="T:Microsoft.AspNetCore.Hosting.WebHostBuilder" />
/// class with pre-configured defaults.
/// The UseStartup method on WebHost specifies the Startup class for your app.
/// </summary>
/// <param name="args">Arguments for this method.</param>
/// <returns>A web server.</returns>
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseApplicationInsights()
.UseStartup<Startup>()
.Build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"AspNetCore-QnA-Bot": {
"QnABot": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
Expand Down
15 changes: 15 additions & 0 deletions csharp_dotnetcore/11.QnAMaker/QnABot.bot
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "QnABot",
"description": "",
"secretKey": "",
"services": [
{
"id": "http://localhost:3978/api/messages",
"name": "QnABot",
"type": "endpoint",
"appId": "",
"appPassword": "",
"endpoint": "http://localhost:3978/api/messages"
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,7 @@

<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<CodeAnalysisRuleSet>QnA-Bot.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<CodeAnalysisRuleSet>QnA-Bot.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRuleSet>QnABot.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>


Expand All @@ -28,7 +21,6 @@
<PackageReference Include="Microsoft.Bot.Builder.Integration.AspNet.Core" Version="4.0.0.38762" />
<PackageReference Include="Microsoft.Bot.Configuration" Version="4.0.0.38762" />
<PackageReference Include="AsyncUsageAnalyzers" Version="1.0.0-alpha003" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Features" Version="2.9.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.0-beta008" PrivateAssets="all" />
</ItemGroup>

Expand Down
38 changes: 12 additions & 26 deletions csharp_dotnetcore/11.QnAMaker/QnAMaker/BotServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,37 @@

using System;
using System.Collections.Generic;
using Microsoft.ApplicationInsights;
using Microsoft.Bot.Builder.AI.QnA;

namespace QnA_Bot
namespace Microsoft.BotBuilderSamples
{
/// <summary>
/// Represents the bot's references to external services.
/// Represents references to external services.
///
/// For example, Application Insights and QnaMaker services
/// are kept here (singletons). These external services are configured
/// using the BotConfigure class (based on the contents of your ".bot" file).
/// For example, the QnA Maker service is kept here as a singleton. This external service is configured
/// using the <see cref="Microsoft.Bot.Configuration.BotConfiguration"/> class
/// (based on the contents of your ".bot" file).
/// </summary>
[Serializable]
public class BotServices
{
/// <summary>
/// Initializes a new instance of the <see cref="BotServices"/> class.
/// </summary>
/// <param name="client">An Application Insights <see cref="TelemetryClient"/> instance.</param>
/// <param name="qnaServices">A dictionary of named <see cref="QnAMaker"/> instances for usage within the bot.</param>
public BotServices(TelemetryClient client, Dictionary<string, QnAMaker> qnaServices)
public BotServices(Dictionary<string, QnAMaker> qnaServices)
{
TelemetryClient = client ?? throw new ArgumentNullException(nameof(client));
QnAServices = qnaServices ?? throw new ArgumentNullException(nameof(qnaServices));
}

/// <summary>
/// Gets the Application Insights Telemetry client.
/// Use this to log new custom events/metrics/traces/etc into your
/// Application Insights service for later analysis.
/// Gets the set of QnA Maker services used.
/// Given there can be multiple <see cref="QnAMaker"/> services used in a single bot,
/// QnA Maker instances are represented as a Dictionary. This is also modeled in the
/// ".bot" file using named elements.
/// </summary>
/// <remarks>The QnA Maker services collection should not be modified while the bot is running.</remarks>
/// <value>
/// The Application Insights <see cref="TelemetryClient"/> instance created based on configuration in the .bot file.
/// </value>
public TelemetryClient TelemetryClient { get; }

/// <summary>
/// Gets the (potential) set of QnA Services used.
/// Given there can be multiple QnA services used in a single bot,
/// QnA is represented as a Dictionary. This is also modeled in the
/// ".bot" file since the elements are named (string).
/// This sample only uses a single QnA instance.
/// </summary>
/// <value>
/// A QnAMaker client instance created based on configuration in the .bot file.
/// A <see cref="QnAMaker"/> client instance created based on configuration in the .bot file.
/// </value>
public Dictionary<string, QnAMaker> QnAServices { get; } = new Dictionary<string, QnAMaker>();
}
Expand Down
32 changes: 17 additions & 15 deletions csharp_dotnetcore/11.QnAMaker/QnAMaker/QnABot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
using Microsoft.Bot.Builder;
using Microsoft.Bot.Schema;

namespace QnA_Bot
namespace Microsoft.BotBuilderSamples
{
/// <summary>
/// Represents a bot that can process incoming activities.
/// For each interaction from the user, an instance of this class is called.
/// For each interaction from the user, an instance of this class is created and
/// the OnTurnAsync method is called.
/// This is a Transient lifetime service. Transient lifetime services are created
/// each time they're requested. For each Activity received, a new instance of this
/// class is created. Objects that are expensive to construct, or have a lifetime
Expand All @@ -19,10 +19,10 @@ namespace QnA_Bot
public class QnABot : IBot
{
/// <summary>
/// Key in the Bot config (.bot file) for the QnaMaker instance.
/// In the .bot file, multiple instances of QnaMaker can be configured.
/// Key in the bot config (.bot file) for the QnA Maker instance.
/// In the ".bot" file, multiple instances of QnA Maker can be configured.
/// </summary>
public static readonly string QnAMakerKey = "QnaBot";
public static readonly string QnAMakerKey = "QnABot";

/// <summary>
/// Services configured from the ".bot" file.
Expand All @@ -32,20 +32,20 @@ public class QnABot : IBot
/// <summary>
/// Initializes a new instance of the <see cref="QnABot"/> class.
/// </summary>
/// <param name="services">Services configured from the ".bot" file.</param>
/// <param name="services">A <see cref="BotServices"/> configured from the ".bot" file.</param>
public QnABot(BotServices services)
{
_services = services ?? throw new System.ArgumentNullException(nameof(services));
if (!_services.QnAServices.ContainsKey(QnAMakerKey))
{
throw new System.ArgumentException($"Invalid configuration. Please check your '.bot' file for a QnA service named '{QnAMakerKey}'.");
throw new System.ArgumentException($"Invalid configuration. Please check your '.bot' file for a QnA service named '{QnAMakerKey}'.");
}
}

/// <summary>
/// Every Conversation turn for our QnA Bot will call this method.
/// There are no dialogs used, since it's "single turn" processing, meaning a single
/// request and response, with no stateful conversation.
/// Every conversation turn for our QnA bot will call this method.
/// There are no dialogs used, the sample only uses "single turn" processing,
/// meaning a single request and response, with no stateful conversation.
/// </summary>
/// <param name="context">A <see cref="ITurnContext"/> containing all the data needed
/// for processing this conversation turn. </param>
Expand All @@ -54,18 +54,20 @@ public QnABot(BotServices services)
/// <returns>A task that represents the work queued to execute.</returns>
public async Task OnTurnAsync(ITurnContext context, CancellationToken cancellationToken = default(CancellationToken))
{
if (context.Activity.Type == ActivityTypes.Message && !context.Responded)
if (context.Activity.Type == ActivityTypes.Message)
{
// Check QnAMaker model
// Check QnA Maker model
var response = await _services.QnAServices[QnAMakerKey].GetAnswersAsync(context);

if (response != null && response.Length > 0)
{
await context.SendActivityAsync(response[0].Answer);
}
else
{
await context.SendActivityAsync("No QnA Maker answers were found. This example uses a QnA Maker Knowledge Base that focuses on smart light bulbs. To see QnA Maker in action, ask the bot questions like \"Why won't it turn on?\" or say something like \"I need help.\"");
var msg = @"No QnA Maker answers were found. This example uses a QnA Maker Knowledge Base that focuses on smart light bulbs.
To see QnA Maker in action, ask the bot questions like 'Why won't it turn on?' or 'I need help'.";

await context.SendActivityAsync(msg);
}
}
}
Expand Down
38 changes: 0 additions & 38 deletions csharp_dotnetcore/11.QnAMaker/QnaBot.bot

This file was deleted.

46 changes: 22 additions & 24 deletions csharp_dotnetcore/11.QnAMaker/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
This sample shows how to integrate QnA Maker in a simple bot with ASP.Net Core 2 and Application Insights.
This sample shows how to integrate QnA Maker in a simple bot with ASP.Net Core 2.

# Concepts introduced in this sample
The [QnA Maker Service](https://www.qnamaker.ai) enables you to build, train and publish a simple question and answer bot based on FAQ URLs, structured documents or editorial content in minutes.

The [Application Insights](https://azure.microsoft.com/en-us/services/application-insights/) enables you to discover actionable insights through application performance management and instant analytics.
The [QnA Maker Service](https://www.qnamaker.ai) enables you to build, train and publish a simple question
and answer bot based on FAQ URLs, structured documents or editorial content in minutes.

In this sample, we demonstrate how to use the QnA Maker service to answer questions based on a FAQ text file as input.

Expand All @@ -15,36 +14,35 @@ git clone https://github.com/Microsoft/botbuilder-samples.git
```

## Prerequisites
- Follow instructions [here](https://docs.microsoft.com/en-us/azure/cognitive-services/qnamaker/how-to/set-up-qnamaker-service-azure) to create a QnA Maker service.
- Follow instructions [here](https://docs.microsoft.com/en-us/azure/cognitive-services/qnamaker/how-to/migrate-knowledge-base) to import the [sample.qna](sample.qna) to your newly created QnA Maker service.
- Update [QnABot.bot](QnABot.bot) with your kbid (KnowledgeBase Id) and endpointKey in the "qna" services section. You can find this information under "Settings" tab for your QnA Maker Knowledge Base at [QnAMaker.ai](https://www.qnamaker.ai)
- Follow instructions [here](https://docs.microsoft.com/en-us/azure/application-insights/app-insights-asp-net-core) to set up your Application Insights service.
- Note: The Application Insights will automatically update the [appsettings.json](appsettings.json) file.
- (Optional) Follow instructions [here](https://github.com/Microsoft/botbuilder-tools/tree/master/packages/QnAMaker) to set up the Qna Maker CLI to deploy the model.


## Visual studio
- Navigate to the samples folder (`BotBuilder-Samples\csharp_dotnetcore\11.QnAMaker`) and open AspNetCore-QnA-Bot.csproj in Visual studio
- Follow instructions [here](https://docs.microsoft.com/en-us/azure/cognitive-services/qnamaker/how-to/set-up-qnamaker-service-azure)
to create a QnA Maker service.
- Follow instructions [here](https://docs.microsoft.com/en-us/azure/cognitive-services/qnamaker/how-to/migrate-knowledge-base) to
import the [sample.qna](sample.qna) to your newly created QnA Maker service.
- Update [QnABot.bot](QnABot.bot) with your kbid (KnowledgeBase Id) and endpointKey in the "qna" services section. You can find this
information under "Settings" tab for your QnA Maker Knowledge Base at [QnAMaker.ai](https://www.qnamaker.ai)
- (Optional) Follow instructions [here](https://github.com/Microsoft/botbuilder-tools/tree/master/packages/QnAMaker) to set up the
QnA Maker CLI to deploy the model.

## Visual Studio
- Navigate to the samples folder (`BotBuilder-Samples\csharp_dotnetcore\11.QnAMaker`) and open QnABot.csproj in Visual Studio .
- Hit F5

## Visual studio code
## Visual Studio Code
- Open `BotBuilder-Samples\csharp_dotnetcore\11.QnAMaker` sample folder.
- Bring up a terminal, navigate to BotBuilder-Samples\11.QnAMaker folder
- type 'dotnet run'
- Bring up a terminal, navigate to `BotBuilder-Samples\csharp_dotnetcore\11.QnAMaker` folder.
- Type 'dotnet run'.

## Testing the bot using Bot Framework Emulator
[Microsoft Bot Framework Emulator](https://github.com/microsoft/botframework-emulator) is a desktop application that allows bot developers to test and debug their bots on localhost or running remotely through a tunnel.

- Install the Bot Framework emulator from [here](https://aka.ms/botframeworkemulator).
- Install the Bot Framework Emulator from [here](https://aka.ms/botframeworkemulator).

### Connect to bot using Bot Framework Emulator **V4**
- Launch Bot Framework Emulator
- File -> Open bot and navigate to `BotBuilder-Samples\csharp_dotnetcore\11.QnAMaker` folder
- Select QnA-Bot.bot file
- Launch the Bot Framework Emulator
- File -> Open bot and navigate to `BotBuilder-Samples\csharp_dotnetcore\11.QnAMaker` folder.
- Select the QnABot.bot file.

# Further reading

- [Azure Bot Service Introduction](https://docs.microsoft.com/en-us/azure/bot-service/bot-service-overview-introduction?view=azure-bot-service-4.0)
- [Azure Bot Service](https://docs.microsoft.com/en-us/azure/bot-service/bot-service-overview-introduction?view=azure-bot-service-4.0)
- [QnA Maker documentation](https://docs.microsoft.com/en-us/azure/cognitive-services/qnamaker/overview/overview)
- [QnA Maker command line tool](https://github.com/Microsoft/botbuilder-tools/tree/master/packages/QnAMaker)
- [Application Insights](https://azure.microsoft.com/en-us/services/application-insights/)
Loading

0 comments on commit 7701c1f

Please sign in to comment.