├── .gitignore ├── CSharp ├── Settings.StyleCop ├── exercise1-EchoBot.md ├── exercise1-EchoBot │ ├── App_Start │ │ └── WebApiConfig.cs │ ├── Controllers │ │ └── MessagesController.cs │ ├── Dialogs │ │ └── RootDialog.cs │ ├── Exercise1.csproj │ ├── Exercise1.sln │ ├── Global.asax │ ├── Global.asax.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Web.Debug.config │ ├── Web.Release.config │ ├── Web.config │ ├── default.htm │ └── packages.config ├── exercise2-TicketSubmissionDialog.md ├── exercise2-TicketSubmissionDialog │ ├── App_Start │ │ └── WebApiConfig.cs │ ├── Controllers │ │ ├── MessagesController.cs │ │ └── TicketsController.cs │ ├── Dialogs │ │ └── RootDialog.cs │ ├── Exercise2.csproj │ ├── Exercise2.sln │ ├── Global.asax │ ├── Global.asax.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Util │ │ └── TicketAPIClient.cs │ ├── Web.Debug.config │ ├── Web.Release.config │ ├── Web.config │ ├── default.htm │ └── packages.config ├── exercise3-LuisDialog.md ├── exercise3-LuisDialog │ ├── App_Start │ │ └── WebApiConfig.cs │ ├── Controllers │ │ ├── MessagesController.cs │ │ └── TicketsController.cs │ ├── Dialogs │ │ └── RootDialog.cs │ ├── Exercise3.csproj │ ├── Exercise3.sln │ ├── Global.asax │ ├── Global.asax.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Util │ │ └── TicketAPIClient.cs │ ├── Web.Debug.config │ ├── Web.Release.config │ ├── Web.config │ ├── default.htm │ └── packages.config ├── exercise4-KnowledgeBase.md ├── exercise4-KnowledgeBase │ ├── App_Start │ │ └── WebApiConfig.cs │ ├── Controllers │ │ ├── MessagesController.cs │ │ └── TicketsController.cs │ ├── Dialogs │ │ ├── CategoryExplorerDialog.cs │ │ ├── RootDialog.cs │ │ ├── SearchScorable.cs │ │ └── ShowArticleDetailsScorable.cs │ ├── Exercise4.csproj │ ├── Exercise4.sln │ ├── Global.asax │ ├── Global.asax.cs │ ├── Model │ │ ├── Category.cs │ │ ├── FacetResult.cs │ │ ├── SearchFacets.cs │ │ ├── SearchResult.cs │ │ └── SearchResultHit.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Services │ │ └── AzureSearchService.cs │ ├── Util │ │ ├── CardUtil.cs │ │ └── TicketAPIClient.cs │ ├── Web.Debug.config │ ├── Web.Release.config │ ├── Web.config │ ├── default.htm │ └── packages.config ├── exercise5-Deployment.md ├── exercise6-MoodDetection.md ├── exercise6-MoodDetetion │ ├── App_Start │ │ └── WebApiConfig.cs │ ├── Controllers │ │ ├── MessagesController.cs │ │ └── TicketsController.cs │ ├── Dialogs │ │ ├── CategoryExplorerDialog.cs │ │ ├── RootDialog.cs │ │ ├── SearchScorable.cs │ │ ├── ShowArticleDetailsScorable.cs │ │ └── UserFeedbackRequestDialog.cs │ ├── Exercise6.csproj │ ├── Exercise6.sln │ ├── Global.asax │ ├── Global.asax.cs │ ├── Model │ │ ├── Category.cs │ │ ├── FacetResult.cs │ │ ├── SearchFacets.cs │ │ ├── SearchResult.cs │ │ └── SearchResultHit.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Services │ │ ├── AzureSearchService.cs │ │ └── TextAnalyticsService.cs │ ├── Util │ │ ├── CardUtil.cs │ │ └── TicketAPIClient.cs │ ├── Web.Debug.config │ ├── Web.Release.config │ ├── Web.config │ ├── default.htm │ └── packages.config ├── exercise7-HandOffToHuman.md ├── exercise7-HandOffToHuman │ ├── App_Start │ │ └── WebApiConfig.cs │ ├── Controllers │ │ ├── MessagesController.cs │ │ └── TicketsController.cs │ ├── Dialogs │ │ ├── AgentLoginScorable.cs │ │ ├── CategoryExplorerDialog.cs │ │ ├── RootDialog.cs │ │ ├── SearchScorable.cs │ │ ├── ShowArticleDetailsScorable.cs │ │ └── UserFeedbackRequestDialog.cs │ ├── Exercise7.csproj │ ├── Exercise7.sln │ ├── Global.asax │ ├── Global.asax.cs │ ├── HandOff │ │ ├── AgentExtensions.cs │ │ ├── CommandScorable.cs │ │ ├── Provider.cs │ │ └── RouterScorable.cs │ ├── Model │ │ ├── Category.cs │ │ ├── FacetResult.cs │ │ ├── SearchFacets.cs │ │ ├── SearchResult.cs │ │ └── SearchResultHit.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Services │ │ ├── AzureSearchService.cs │ │ └── TextAnalyticsService.cs │ ├── Util │ │ ├── CardUtil.cs │ │ └── TicketAPIClient.cs │ ├── Web.Debug.config │ ├── Web.Release.config │ ├── Web.config │ ├── default.htm │ └── packages.config ├── exercise8-BackChannel.md ├── exercise8-BackChannel │ ├── App_Start │ │ └── WebApiConfig.cs │ ├── Controllers │ │ ├── MessagesController.cs │ │ └── TicketsController.cs │ ├── Dialogs │ │ ├── AgentLoginScorable.cs │ │ ├── CategoryExplorerDialog.cs │ │ ├── RootDialog.cs │ │ ├── SearchScorable.cs │ │ ├── ShowArticleDetailsScorable.cs │ │ └── UserFeedbackRequestDialog.cs │ ├── Exercise8.csproj │ ├── Exercise8.sln │ ├── Global.asax │ ├── Global.asax.cs │ ├── HandOff │ │ ├── AgentExtensions.cs │ │ ├── CommandScorable.cs │ │ ├── Provider.cs │ │ └── RouterScorable.cs │ ├── Model │ │ ├── Category.cs │ │ ├── FacetResult.cs │ │ ├── SearchFacets.cs │ │ ├── SearchResult.cs │ │ └── SearchResultHit.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Services │ │ ├── AzureSearchService.cs │ │ └── TextAnalyticsService.cs │ ├── Util │ │ ├── CardUtil.cs │ │ └── TicketAPIClient.cs │ ├── Web.Debug.config │ ├── Web.Release.config │ ├── Web.config │ ├── default.htm │ └── packages.config └── images │ ├── demo-formflow.png │ ├── exercise1-default-htm.png │ ├── exercise1-echo-bot.png │ ├── exercise1-new-project.png │ ├── exercise1-run-project.png │ ├── exercise2-dialog.png │ ├── exercise2-emulator-adaptivecards.png │ ├── exercise2-full-conversation-1.png │ ├── exercise2-full-conversation-2.png │ ├── exercise2-start-new.png │ ├── exercise3-addluisapp.png │ ├── exercise3-dialog.png │ ├── exercise3-hello.png │ ├── exercise3-hi.png │ ├── exercise3-luis-dashboard.png │ ├── exercise3-luis-entity.png │ ├── exercise3-luis-mykeys.png │ ├── exercise3-luis-recognizedutterances.png │ ├── exercise3-save-utterances.png │ ├── exercise3-severity.png │ ├── exercise3-suggested-utterances.png │ ├── exercise3-test.png │ ├── exercise3-unknown.png │ ├── exercise4-azuresearch-createdatasource.png │ ├── exercise4-azuresearch-createindexer.png │ ├── exercise4-azuresearch-managekeys.png │ ├── exercise4-createdocumentdb.png │ ├── exercise4-createsearchservice.png │ ├── exercise4-documentdb-addcollection.png │ ├── exercise4-documentdb-uploadfiles.png │ ├── exercise4-emulator-detailsofarticle.png │ ├── exercise4-emulator-explorecategory2.png │ ├── exercise4-emulator-explorekb2.png │ ├── exercise4-emulator-search.png │ ├── exercise4-emulator-showkbresults.png │ ├── exercise4-faq-index-facets-matrix.png │ ├── exercise4-import-data-button.png │ ├── exercise4-new-intent.png │ ├── exercise4-new.png │ ├── exercise4-testbit-explorehardware.png │ ├── exercise5-addappsettings.png │ ├── exercise5-addbottoskype.png │ ├── exercise5-botchannels.png │ ├── exercise5-botconfiguration.png │ ├── exercise5-botname.png │ ├── exercise5-generateappid.png │ ├── exercise5-generatepassword.png │ ├── exercise5-savebutton.png │ ├── exercise5-testskype.png │ ├── exercise5-testwebchannel.png │ ├── exercise5-vs-createappservice.png │ ├── exercise5-vs-publish.png │ ├── exercise6-negativefeedback.png │ ├── exercise6-positivefeedback.png │ ├── exercise6-test-providefeedback.png │ ├── exercise6-text-analytics-keys.png │ ├── exercise7-diagram.png │ ├── exercise7-test-agent-connect.png │ ├── exercise7-test-agent-login.png │ ├── exercise7-test-agent-resume.png │ ├── exercise7-test-agent-talk.png │ ├── exercise7-test-user-connect.png │ ├── exercise7-test-user-resume.png │ ├── exercise7-test-user-talk.png │ ├── exercise7-test-user-ticketfeedback.png │ ├── exercise7-test-user-waitagent.png │ ├── exercise8-addnewsite.png │ ├── exercise8-backchannel-webchat.png │ ├── exercise8-edit.png │ ├── exercise8-ngrok.png │ ├── exercise8-webchat-articles.png │ ├── exercise8-webchat-articlesdetail.png │ └── exercise8-webchatsecrets.png ├── Demos ├── CSharp.md └── Node.md ├── Node ├── exercise1-EchoBot.md ├── exercise1-EchoBot │ ├── .env │ ├── app.js │ └── package.json ├── exercise2-TicketSubmissionDialog.md ├── exercise2-TicketSubmissionDialog │ ├── .env │ ├── app.js │ ├── cards │ │ └── ticket.json │ ├── package.json │ └── ticketsApi.js ├── exercise3-LuisDialog.md ├── exercise3-LuisDialog │ ├── .env │ ├── app.js │ ├── cards │ │ └── ticket.json │ ├── package.json │ └── ticketsApi.js ├── exercise4-KnowledgeBase.md ├── exercise4-KnowledgeBase │ ├── .env │ ├── app.js │ ├── azureSearchApiClient.js │ ├── cards │ │ └── ticket.json │ ├── data │ │ └── luis_model.json │ ├── package.json │ └── ticketsApi.js ├── exercise5-Deployment.md ├── exercise6-MoodDetection.md ├── exercise6-MoodDetection │ ├── .env │ ├── app.js │ ├── azureSearchApiClient.js │ ├── cards │ │ └── ticket.json │ ├── package.json │ ├── textAnalyticsApiClient.js │ └── ticketsApi.js ├── exercise7-HandOffToHuman.md ├── exercise7-HandOffToHuman │ ├── .env │ ├── app.js │ ├── azureSearchApiClient.js │ ├── cards │ │ └── ticket.json │ ├── handoff │ │ ├── command.js │ │ ├── provider.js │ │ └── router.js │ ├── package.json │ ├── textAnalyticsApiClient.js │ └── ticketsApi.js ├── exercise8-BackChannel.md ├── exercise8-BackChannel │ ├── .env │ ├── app.js │ ├── azureSearchApiClient.js │ ├── cards │ │ └── ticket.json │ ├── handoff │ │ ├── command.js │ │ ├── provider.js │ │ └── router.js │ ├── package.json │ ├── textAnalyticsApiClient.js │ ├── ticketsApi.js │ └── web-ui │ │ └── default.htm └── images │ ├── exercise1-echo-bot.png │ ├── exercise2-console.png │ ├── exercise2-dialog.png │ ├── exercise2-emulator-adaptivecards.png │ ├── exercise2-full-conversation-1.png │ ├── exercise2-full-conversation-2.png │ ├── exercise2-start-new.png │ ├── exercise3-addluisapp.png │ ├── exercise3-dialog.png │ ├── exercise3-hello.png │ ├── exercise3-hi.png │ ├── exercise3-luis-dashboard.png │ ├── exercise3-luis-entity.png │ ├── exercise3-luis-recognizedutterances.png │ ├── exercise3-save-utterances.png │ ├── exercise3-severity.png │ ├── exercise3-suggested-utterances.png │ ├── exercise3-test.png │ ├── exercise3-unknown.png │ ├── exercise4-azuresearch-createdatasource.png │ ├── exercise4-azuresearch-createindexer.png │ ├── exercise4-azuresearch-managekeys.png │ ├── exercise4-createdocumentdb.png │ ├── exercise4-createsearchservice.png │ ├── exercise4-diagram.png │ ├── exercise4-documentdb-addcollection.png │ ├── exercise4-documentdb-uploadfiles.png │ ├── exercise4-emulator-detailsofarticle.png │ ├── exercise4-emulator-explorecategory2.png │ ├── exercise4-emulator-explorekb2.png │ ├── exercise4-emulator-search.png │ ├── exercise4-emulator-showarticle.png │ ├── exercise4-emulator-showkbresults.png │ ├── exercise4-faq-index-facets-matrix.png │ ├── exercise4-import-data-button.png │ ├── exercise4-new-intent.png │ ├── exercise4-new.png │ ├── exercise4-testbit-explorehardware.png │ ├── exercise5-addappsettings.png │ ├── exercise5-addbottoskype.png │ ├── exercise5-botchannels.png │ ├── exercise5-botconfiguration.png │ ├── exercise5-botname.png │ ├── exercise5-createwebapp.png │ ├── exercise5-deploymentcredentials.png │ ├── exercise5-deploymentoption-localgit.png │ ├── exercise5-deploymentsuccessful.png │ ├── exercise5-entergitcredentials.png │ ├── exercise5-essentials-gitclone.png │ ├── exercise5-generateappid.png │ ├── exercise5-generatepassword.png │ ├── exercise5-savebutton.png │ ├── exercise5-testskype.png │ ├── exercise5-testwebchannel.png │ ├── exercise6-negativefeedback.png │ ├── exercise6-possitivefeedback.png │ ├── exercise6-test-providefeedback.png │ ├── exercise6-text-analytics-keys.png │ ├── exercise7-diagram.png │ ├── exercise7-test-agent-connect.png │ ├── exercise7-test-agent-login.png │ ├── exercise7-test-agent-resume.png │ ├── exercise7-test-agent-talk.png │ ├── exercise7-test-user-connect.png │ ├── exercise7-test-user-resume.png │ ├── exercise7-test-user-talk.png │ ├── exercise7-test-user-ticketfeedback.png │ ├── exercise7-test-user-waitagent.png │ ├── exercise8-addnewsite.png │ ├── exercise8-diagram.png │ ├── exercise8-edit.png │ ├── exercise8-ngrok.png │ ├── exercise8-webchat-articles.png │ ├── exercise8-webchat-articlesdetail.png │ └── exercise8-webchatsecrets.png ├── Readme.md ├── Slides ├── 1 - Bots in the real world.pptx ├── 2 - Mastering the user experience.pptx ├── 3 - Natural Language Processing and LUIS.pptx ├── 4 - Knowledge base and Azure Search.pptx ├── 5 - Deploying your bot.pptx ├── 6 - Cognitive Services.pptx ├── 7 - Handoff to Human.pptx ├── 8 - Backchannel.pptx └── MissionMars │ ├── 1 - Bot Design.pptx │ ├── 2 - Mastering the interface.pptx │ ├── 3 - Natural language processing.pptx │ ├── 4 - Knowledge base bots.pptx │ ├── 5 - Deploying M.A.X.pptx │ ├── 6 - Cognitive Services.pptx │ ├── 7 - Middleware and human handoff.pptx │ └── 8 - WebChat and Backchannel.pptx ├── assets ├── botimages │ ├── head-sad-medium.png │ ├── head-sad-small.png │ ├── head-smiling-medium.png │ └── head-smiling-small.png ├── categories.json ├── exercise2-TicketSubmissionDialog │ ├── TicketAPIClient.cs │ ├── TicketsController.cs │ └── ticket.json ├── exercise3-LuisDialog │ └── luis_model.json ├── exercise4-KnowledgeBase │ ├── CardUtil.cs │ ├── Category.cs │ ├── FacetResult.cs │ ├── FurtherChallenge │ │ ├── CardUtil.cs │ │ ├── ImageSearchService.cs │ │ ├── articlesCard.js │ │ └── imageSearchApiClient.js │ ├── SearchFacets.cs │ ├── SearchResult.cs │ ├── SearchResultHit.cs │ ├── SearchScorable.cs │ └── ShowArticleDetailsScorable.cs ├── exercise6-MoodDetection │ └── TextAnalyticsService.cs ├── exercise7-HandOffToHuman │ ├── AgentExtensions.cs │ ├── AgentLoginScorable.cs │ ├── CommandScorable.cs │ ├── Provider.cs │ ├── RouterScorable.cs │ ├── command.js │ ├── luis_model.json │ └── provider.js ├── exercise8-BackChannel │ └── default.htm ├── kb │ ├── 1.json │ ├── 10.json │ ├── 11.json │ ├── 12.json │ ├── 13.json │ ├── 14.json │ ├── 15.json │ ├── 16.json │ ├── 17.json │ ├── 2.json │ ├── 3.json │ ├── 4.json │ ├── 5.json │ ├── 6.json │ ├── 7.json │ ├── 8.json │ └── 9.json ├── logo.png └── severities.json ├── exercise1-EchoBot.md ├── exercise2-TicketSubmissionDialog.md ├── exercise3-LuisDialog.md ├── exercise4-KnowledgeBase.md ├── exercise5-Deployment.md ├── exercise6-MoodDetection.md ├── exercise7-HandOffToHuman.md └── exercise8-BackChannel.md /CSharp/exercise1-EchoBot/App_Start/WebApiConfig.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot 2 | { 3 | using System.Web.Http; 4 | using Newtonsoft.Json; 5 | using Newtonsoft.Json.Serialization; 6 | 7 | public static class WebApiConfig 8 | { 9 | public static void Register(HttpConfiguration config) 10 | { 11 | // Json settings 12 | config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; 13 | config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 14 | config.Formatters.JsonFormatter.SerializerSettings.Formatting = Formatting.Indented; 15 | JsonConvert.DefaultSettings = () => new JsonSerializerSettings() 16 | { 17 | ContractResolver = new CamelCasePropertyNamesContractResolver(), 18 | Formatting = Newtonsoft.Json.Formatting.Indented, 19 | NullValueHandling = NullValueHandling.Ignore, 20 | }; 21 | 22 | // Web API configuration and services 23 | 24 | // Web API routes 25 | config.MapHttpAttributeRoutes(); 26 | 27 | config.Routes.MapHttpRoute( 28 | name: "DefaultApi", 29 | routeTemplate: "api/{controller}/{id}", 30 | defaults: new { id = RouteParameter.Optional }); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /CSharp/exercise1-EchoBot/Dialogs/RootDialog.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Dialogs 2 | { 3 | using System; 4 | using System.Threading.Tasks; 5 | using Microsoft.Bot.Builder.Dialogs; 6 | using Microsoft.Bot.Connector; 7 | 8 | [Serializable] 9 | public class RootDialog : IDialog 10 | { 11 | public Task StartAsync(IDialogContext context) 12 | { 13 | context.Wait(this.MessageReceivedAsync); 14 | 15 | return Task.CompletedTask; 16 | } 17 | 18 | private async Task MessageReceivedAsync(IDialogContext context, IAwaitable result) 19 | { 20 | var activity = await result as Activity; 21 | 22 | // calculate something for us to return 23 | int length = (activity.Text ?? string.Empty).Length; 24 | 25 | // return our reply to the user 26 | await context.PostAsync($"You sent {activity.Text} which was {length} characters"); 27 | 28 | context.Wait(this.MessageReceivedAsync); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /CSharp/exercise1-EchoBot/Exercise1.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Exercise1", "Exercise1.csproj", "{14A866F5-E2EF-4D2F-9596-4315C009469E}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {14A866F5-E2EF-4D2F-9596-4315C009469E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {14A866F5-E2EF-4D2F-9596-4315C009469E}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {14A866F5-E2EF-4D2F-9596-4315C009469E}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {14A866F5-E2EF-4D2F-9596-4315C009469E}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /CSharp/exercise1-EchoBot/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="HelpDeskBot.WebApiApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /CSharp/exercise1-EchoBot/Global.asax.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot 2 | { 3 | using System.Web.Http; 4 | 5 | public class WebApiApplication : System.Web.HttpApplication 6 | { 7 | protected void Application_Start() 8 | { 9 | GlobalConfiguration.Configure(WebApiConfig.Register); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /CSharp/exercise1-EchoBot/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Exercise1-EchoBot")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Exercise1-EchoBot")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("a8ba1066-5695-4d71-abb4-65e5a5e0c3d4")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /CSharp/exercise1-EchoBot/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /CSharp/exercise1-EchoBot/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /CSharp/exercise1-EchoBot/default.htm: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 |

Step1

9 |

Describe your bot here and your terms of use etc.

10 |

Visit Bot Framework to register your bot. When you register it, remember to set your bot's endpoint to

https://your_bots_hostname/api/messages

11 | 12 | 13 | -------------------------------------------------------------------------------- /CSharp/exercise1-EchoBot/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /CSharp/exercise2-TicketSubmissionDialog/App_Start/WebApiConfig.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot 2 | { 3 | using System.Web.Http; 4 | using Newtonsoft.Json; 5 | using Newtonsoft.Json.Serialization; 6 | 7 | public static class WebApiConfig 8 | { 9 | public static void Register(HttpConfiguration config) 10 | { 11 | // Json settings 12 | config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; 13 | config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 14 | config.Formatters.JsonFormatter.SerializerSettings.Formatting = Formatting.Indented; 15 | JsonConvert.DefaultSettings = () => new JsonSerializerSettings() 16 | { 17 | ContractResolver = new CamelCasePropertyNamesContractResolver(), 18 | Formatting = Newtonsoft.Json.Formatting.Indented, 19 | NullValueHandling = NullValueHandling.Ignore, 20 | }; 21 | 22 | // Web API configuration and services 23 | 24 | // Web API routes 25 | config.MapHttpAttributeRoutes(); 26 | 27 | config.Routes.MapHttpRoute( 28 | name: "DefaultApi", 29 | routeTemplate: "api/{controller}/{id}", 30 | defaults: new { id = RouteParameter.Optional }); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /CSharp/exercise2-TicketSubmissionDialog/Controllers/TicketsController.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Web.Http; 6 | using Util; 7 | 8 | public class TicketsController : ApiController 9 | { 10 | private static int nextTicketId = 1; 11 | private static Dictionary tickets = new Dictionary(); 12 | 13 | [HttpPost] 14 | public IHttpActionResult Post(Ticket ticket) 15 | { 16 | int ticketId; 17 | 18 | Console.WriteLine("Ticket accepted: category:" + ticket.Category + " severity:" + ticket.Severity + " description:" + ticket.Description); 19 | 20 | lock (tickets) 21 | { 22 | ticketId = nextTicketId++; 23 | TicketsController.tickets.Add(ticketId, ticket); 24 | } 25 | 26 | return this.Ok(ticketId.ToString()); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /CSharp/exercise2-TicketSubmissionDialog/Exercise2.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Exercise2", "Exercise2.csproj", "{DDE71465-6745-4142-BF0C-9BBCE8B7920C}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {DDE71465-6745-4142-BF0C-9BBCE8B7920C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {DDE71465-6745-4142-BF0C-9BBCE8B7920C}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {DDE71465-6745-4142-BF0C-9BBCE8B7920C}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {DDE71465-6745-4142-BF0C-9BBCE8B7920C}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /CSharp/exercise2-TicketSubmissionDialog/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="HelpDeskBot.WebApiApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /CSharp/exercise2-TicketSubmissionDialog/Global.asax.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot 2 | { 3 | using System.Web.Http; 4 | 5 | public class WebApiApplication : System.Web.HttpApplication 6 | { 7 | protected void Application_Start() 8 | { 9 | GlobalConfiguration.Configure(WebApiConfig.Register); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /CSharp/exercise2-TicketSubmissionDialog/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Exercise2-TicketSubmissionDialog")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Exercise2-TicketSubmissionDialog")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("a8ba1066-5695-4d71-abb4-65e5a5e0c3d4")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /CSharp/exercise2-TicketSubmissionDialog/Util/TicketAPIClient.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Util 2 | { 3 | using System; 4 | using System.Net.Http; 5 | using System.Net.Http.Headers; 6 | using System.Threading.Tasks; 7 | using System.Web.Configuration; 8 | 9 | public class Ticket 10 | { 11 | public string Category { get; set; } 12 | 13 | public string Severity { get; set; } 14 | 15 | public string Description { get; set; } 16 | } 17 | 18 | public class TicketAPIClient 19 | { 20 | public async Task PostTicketAsync(string category, string severity, string description) 21 | { 22 | try 23 | { 24 | using (var client = new HttpClient()) 25 | { 26 | client.BaseAddress = new Uri(WebConfigurationManager.AppSettings["TicketsAPIBaseUrl"]); 27 | client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 28 | 29 | var ticket = new Ticket 30 | { 31 | Category = category, 32 | Severity = severity, 33 | Description = description 34 | }; 35 | 36 | var response = await client.PostAsJsonAsync("api/tickets", ticket); 37 | return await response.Content.ReadAsAsync(); 38 | } 39 | } 40 | catch 41 | { 42 | return -1; 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /CSharp/exercise2-TicketSubmissionDialog/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /CSharp/exercise2-TicketSubmissionDialog/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /CSharp/exercise2-TicketSubmissionDialog/default.htm: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 |

Exercise2

9 |

Describe your bot here and your terms of use etc.

10 |

Visit Bot Framework to register your bot. When you register it, remember to set your bot's endpoint to

https://your_bots_hostname/api/messages

11 | 12 | 13 | -------------------------------------------------------------------------------- /CSharp/exercise2-TicketSubmissionDialog/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /CSharp/exercise3-LuisDialog/App_Start/WebApiConfig.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot 2 | { 3 | using System.Web.Http; 4 | using Newtonsoft.Json; 5 | using Newtonsoft.Json.Serialization; 6 | 7 | public static class WebApiConfig 8 | { 9 | public static void Register(HttpConfiguration config) 10 | { 11 | // Json settings 12 | config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; 13 | config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 14 | config.Formatters.JsonFormatter.SerializerSettings.Formatting = Formatting.Indented; 15 | JsonConvert.DefaultSettings = () => new JsonSerializerSettings() 16 | { 17 | ContractResolver = new CamelCasePropertyNamesContractResolver(), 18 | Formatting = Newtonsoft.Json.Formatting.Indented, 19 | NullValueHandling = NullValueHandling.Ignore, 20 | }; 21 | 22 | // Web API configuration and services 23 | 24 | // Web API routes 25 | config.MapHttpAttributeRoutes(); 26 | 27 | config.Routes.MapHttpRoute( 28 | name: "DefaultApi", 29 | routeTemplate: "api/{controller}/{id}", 30 | defaults: new { id = RouteParameter.Optional }); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /CSharp/exercise3-LuisDialog/Controllers/TicketsController.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Web.Http; 6 | using Util; 7 | 8 | public class TicketsController : ApiController 9 | { 10 | private static int nextTicketId = 1; 11 | private static Dictionary tickets = new Dictionary(); 12 | 13 | [HttpPost] 14 | public IHttpActionResult Post(Ticket ticket) 15 | { 16 | int ticketId; 17 | 18 | Console.WriteLine("Ticket accepted: category:" + ticket.Category + " severity:" + ticket.Severity + " description:" + ticket.Description); 19 | 20 | lock (tickets) 21 | { 22 | ticketId = nextTicketId++; 23 | TicketsController.tickets.Add(ticketId, ticket); 24 | } 25 | 26 | return this.Ok(ticketId.ToString()); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /CSharp/exercise3-LuisDialog/Exercise3.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Exercise3", "Exercise3.csproj", "{63BEF962-FF36-4722-93D0-83FF60398358}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {63BEF962-FF36-4722-93D0-83FF60398358}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {63BEF962-FF36-4722-93D0-83FF60398358}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {63BEF962-FF36-4722-93D0-83FF60398358}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {63BEF962-FF36-4722-93D0-83FF60398358}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /CSharp/exercise3-LuisDialog/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="HelpDeskBot.WebApiApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /CSharp/exercise3-LuisDialog/Global.asax.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot 2 | { 3 | using System.Web.Http; 4 | 5 | public class WebApiApplication : System.Web.HttpApplication 6 | { 7 | protected void Application_Start() 8 | { 9 | GlobalConfiguration.Configure(WebApiConfig.Register); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /CSharp/exercise3-LuisDialog/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Exercise3-LuisDialog")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Exercise3-LuisDialog")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("a8ba1066-5695-4d71-abb4-65e5a5e0c3d4")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /CSharp/exercise3-LuisDialog/Util/TicketAPIClient.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Util 2 | { 3 | using System; 4 | using System.Net.Http; 5 | using System.Net.Http.Headers; 6 | using System.Threading.Tasks; 7 | using System.Web.Configuration; 8 | 9 | public class Ticket 10 | { 11 | public string Category { get; set; } 12 | 13 | public string Severity { get; set; } 14 | 15 | public string Description { get; set; } 16 | } 17 | 18 | public class TicketAPIClient 19 | { 20 | public async Task PostTicketAsync(string category, string severity, string description) 21 | { 22 | try 23 | { 24 | using (var client = new HttpClient()) 25 | { 26 | client.BaseAddress = new Uri(WebConfigurationManager.AppSettings["TicketsAPIBaseUrl"]); 27 | client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 28 | 29 | var issue = new Ticket 30 | { 31 | Category = category, 32 | Severity = severity, 33 | Description = description 34 | }; 35 | 36 | var response = await client.PostAsJsonAsync("api/tickets", issue); 37 | return await response.Content.ReadAsAsync(); 38 | } 39 | } 40 | catch 41 | { 42 | return -1; 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /CSharp/exercise3-LuisDialog/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /CSharp/exercise3-LuisDialog/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /CSharp/exercise3-LuisDialog/default.htm: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 |

Exercise3

9 |

Describe your bot here and your terms of use etc.

10 |

Visit Bot Framework to register your bot. When you register it, remember to set your bot's endpoint to

https://your_bots_hostname/api/messages

11 | 12 | 13 | -------------------------------------------------------------------------------- /CSharp/exercise3-LuisDialog/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /CSharp/exercise4-KnowledgeBase/App_Start/WebApiConfig.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot 2 | { 3 | using System.Web.Http; 4 | using Newtonsoft.Json; 5 | using Newtonsoft.Json.Serialization; 6 | 7 | public static class WebApiConfig 8 | { 9 | public static void Register(HttpConfiguration config) 10 | { 11 | // Json settings 12 | config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; 13 | config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 14 | config.Formatters.JsonFormatter.SerializerSettings.Formatting = Formatting.Indented; 15 | JsonConvert.DefaultSettings = () => new JsonSerializerSettings() 16 | { 17 | ContractResolver = new CamelCasePropertyNamesContractResolver(), 18 | Formatting = Newtonsoft.Json.Formatting.Indented, 19 | NullValueHandling = NullValueHandling.Ignore, 20 | }; 21 | 22 | // Web API configuration and services 23 | 24 | // Web API routes 25 | config.MapHttpAttributeRoutes(); 26 | 27 | config.Routes.MapHttpRoute( 28 | name: "DefaultApi", 29 | routeTemplate: "api/{controller}/{id}", 30 | defaults: new { id = RouteParameter.Optional }); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /CSharp/exercise4-KnowledgeBase/Controllers/TicketsController.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Web.Http; 6 | using Util; 7 | 8 | public class TicketsController : ApiController 9 | { 10 | private static int nextTicketId = 1; 11 | private static Dictionary tickets = new Dictionary(); 12 | 13 | [HttpPost] 14 | public IHttpActionResult Post(Ticket ticket) 15 | { 16 | int ticketId; 17 | 18 | Console.WriteLine("Ticket accepted: category:" + ticket.Category + " severity:" + ticket.Severity + " description:" + ticket.Description); 19 | 20 | lock (tickets) 21 | { 22 | ticketId = nextTicketId++; 23 | TicketsController.tickets.Add(ticketId, ticket); 24 | } 25 | 26 | return this.Ok(ticketId.ToString()); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /CSharp/exercise4-KnowledgeBase/Dialogs/SearchScorable.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Dialogs 2 | { 3 | using System; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | using Microsoft.Bot.Builder.Scorables.Internals; 7 | using Microsoft.Bot.Connector; 8 | using Services; 9 | using Util; 10 | 11 | public class SearchScorable : ScorableBase 12 | { 13 | private const string TRIGGER = "search about "; 14 | private readonly AzureSearchService searchService = new AzureSearchService(); 15 | 16 | protected override Task DoneAsync(IActivity item, string state, CancellationToken token) 17 | { 18 | return Task.CompletedTask; 19 | } 20 | 21 | protected override double GetScore(IActivity item, string state) 22 | { 23 | return 1.0; 24 | } 25 | 26 | protected override bool HasScore(IActivity item, string state) 27 | { 28 | return !string.IsNullOrWhiteSpace(state); 29 | } 30 | 31 | protected async override Task PostAsync(IActivity item, string state, CancellationToken token) 32 | { 33 | var searchResult = await this.searchService.Search(state); 34 | 35 | var replyActivity = ((Activity)item).CreateReply(); 36 | await CardUtil.ShowSearchResults(replyActivity, searchResult, $"I'm sorry, I did not understand '{state}'.\nType 'help' to know more about me :)"); 37 | } 38 | 39 | protected async override Task PrepareAsync(IActivity item, CancellationToken token) 40 | { 41 | var message = item.AsMessageActivity(); 42 | if (message != null && !string.IsNullOrWhiteSpace(message.Text)) 43 | { 44 | if (message.Text.Trim().StartsWith(TRIGGER, StringComparison.InvariantCultureIgnoreCase)) 45 | { 46 | return message.Text.Substring(TRIGGER.Length); 47 | } 48 | } 49 | 50 | return null; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /CSharp/exercise4-KnowledgeBase/Exercise4.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Exercise4", "Exercise4.csproj", "{A8BA1066-5695-4D71-ABB4-65E5A5E0C3D4}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {A8BA1066-5695-4D71-ABB4-65E5A5E0C3D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {A8BA1066-5695-4D71-ABB4-65E5A5E0C3D4}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {A8BA1066-5695-4D71-ABB4-65E5A5E0C3D4}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {A8BA1066-5695-4D71-ABB4-65E5A5E0C3D4}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /CSharp/exercise4-KnowledgeBase/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="HelpDeskBot.WebApiApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /CSharp/exercise4-KnowledgeBase/Global.asax.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot 2 | { 3 | using System.Web.Http; 4 | using Autofac; 5 | using Dialogs; 6 | using Microsoft.Bot.Builder.Dialogs; 7 | using Microsoft.Bot.Builder.Scorables; 8 | using Microsoft.Bot.Connector; 9 | 10 | public class WebApiApplication : System.Web.HttpApplication 11 | { 12 | protected void Application_Start() 13 | { 14 | GlobalConfiguration.Configure(WebApiConfig.Register); 15 | 16 | var builder = new ContainerBuilder(); 17 | 18 | builder.RegisterType() 19 | .As>() 20 | .InstancePerLifetimeScope(); 21 | 22 | builder.RegisterType() 23 | .As>() 24 | .InstancePerLifetimeScope(); 25 | 26 | builder.Update(Conversation.Container); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /CSharp/exercise4-KnowledgeBase/Model/Category.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | public class Category 4 | { 5 | public int Count { get; set; } 6 | 7 | public string Value { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /CSharp/exercise4-KnowledgeBase/Model/FacetResult.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | using Newtonsoft.Json; 4 | 5 | public class FacetResult 6 | { 7 | [JsonProperty("@odata.context")] 8 | public string ODataContext { get; set; } 9 | 10 | [JsonProperty("@search.facets")] 11 | public SearchFacets Facets { get; set; } 12 | 13 | public SearchResultHit[] Value { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /CSharp/exercise4-KnowledgeBase/Model/SearchFacets.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | using Newtonsoft.Json; 4 | 5 | public class SearchFacets 6 | { 7 | [JsonProperty("category@odata.type")] 8 | public string CategoryOdataType { get; set; } 9 | 10 | public Category[] Category { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /CSharp/exercise4-KnowledgeBase/Model/SearchResult.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | using Newtonsoft.Json; 4 | 5 | public class SearchResult 6 | { 7 | [JsonProperty("@odata.context")] 8 | public string ODataContext { get; set; } 9 | 10 | public SearchResultHit[] Value { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /CSharp/exercise4-KnowledgeBase/Model/SearchResultHit.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | using Newtonsoft.Json; 4 | 5 | public class SearchResultHit 6 | { 7 | [JsonProperty("@search.score")] 8 | public float SearchScore { get; set; } 9 | 10 | public string Title { get; set; } 11 | 12 | public string Category { get; set; } 13 | 14 | public string Text { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /CSharp/exercise4-KnowledgeBase/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Exercise4-KnowledgeBase")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Exercise4-KnowledgeBase")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("a8ba1066-5695-4d71-abb4-65e5a5e0c3d4")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /CSharp/exercise4-KnowledgeBase/Util/TicketAPIClient.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Util 2 | { 3 | using System; 4 | using System.Net.Http; 5 | using System.Net.Http.Headers; 6 | using System.Threading.Tasks; 7 | using System.Web.Configuration; 8 | 9 | public class Ticket 10 | { 11 | public string Category { get; set; } 12 | 13 | public string Severity { get; set; } 14 | 15 | public string Description { get; set; } 16 | } 17 | 18 | public class TicketAPIClient 19 | { 20 | public async Task PostTicketAsync(string category, string severity, string description) 21 | { 22 | try 23 | { 24 | using (var client = new HttpClient()) 25 | { 26 | client.BaseAddress = new Uri(WebConfigurationManager.AppSettings["TicketsAPIBaseUrl"]); 27 | client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 28 | 29 | var issue = new Ticket 30 | { 31 | Category = category, 32 | Severity = severity, 33 | Description = description 34 | }; 35 | 36 | var response = await client.PostAsJsonAsync("api/tickets", issue); 37 | return await response.Content.ReadAsAsync(); 38 | } 39 | } 40 | catch 41 | { 42 | return -1; 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /CSharp/exercise4-KnowledgeBase/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /CSharp/exercise4-KnowledgeBase/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /CSharp/exercise4-KnowledgeBase/default.htm: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 |

Exercise4

9 |

Describe your bot here and your terms of use etc.

10 |

Visit Bot Framework to register your bot. When you register it, remember to set your bot's endpoint to

https://your_bots_hostname/api/messages

11 | 12 | 13 | -------------------------------------------------------------------------------- /CSharp/exercise4-KnowledgeBase/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /CSharp/exercise6-MoodDetetion/App_Start/WebApiConfig.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot 2 | { 3 | using System.Web.Http; 4 | using Newtonsoft.Json; 5 | using Newtonsoft.Json.Serialization; 6 | 7 | public static class WebApiConfig 8 | { 9 | public static void Register(HttpConfiguration config) 10 | { 11 | // Json settings 12 | config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; 13 | config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 14 | config.Formatters.JsonFormatter.SerializerSettings.Formatting = Formatting.Indented; 15 | JsonConvert.DefaultSettings = () => new JsonSerializerSettings() 16 | { 17 | ContractResolver = new CamelCasePropertyNamesContractResolver(), 18 | Formatting = Newtonsoft.Json.Formatting.Indented, 19 | NullValueHandling = NullValueHandling.Ignore, 20 | }; 21 | 22 | // Web API configuration and services 23 | 24 | // Web API routes 25 | config.MapHttpAttributeRoutes(); 26 | 27 | config.Routes.MapHttpRoute( 28 | name: "DefaultApi", 29 | routeTemplate: "api/{controller}/{id}", 30 | defaults: new { id = RouteParameter.Optional }); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /CSharp/exercise6-MoodDetetion/Controllers/TicketsController.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Web.Http; 6 | using Util; 7 | 8 | public class TicketsController : ApiController 9 | { 10 | private static int nextIssueId = 1; 11 | private static Dictionary issues = new Dictionary(); 12 | 13 | [HttpPost] 14 | public IHttpActionResult Post(Ticket issue) 15 | { 16 | int issueId; 17 | 18 | Console.WriteLine("Ticket accepted: category:" + issue.Category + " severity:" + issue.Severity + " description:" + issue.Description); 19 | 20 | lock (issues) 21 | { 22 | issueId = nextIssueId++; 23 | TicketsController.issues.Add(issueId, issue); 24 | } 25 | 26 | return this.Ok(issueId.ToString()); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /CSharp/exercise6-MoodDetetion/Dialogs/SearchScorable.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Dialogs 2 | { 3 | using System; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | using Microsoft.Bot.Builder.Scorables.Internals; 7 | using Microsoft.Bot.Connector; 8 | using Services; 9 | using Util; 10 | 11 | public class SearchScorable : ScorableBase 12 | { 13 | private const string TRIGGER = "search about "; 14 | private readonly AzureSearchService searchService = new AzureSearchService(); 15 | 16 | protected override Task DoneAsync(IActivity item, string state, CancellationToken token) 17 | { 18 | return Task.CompletedTask; 19 | } 20 | 21 | protected override double GetScore(IActivity item, string state) 22 | { 23 | return 1.0; 24 | } 25 | 26 | protected override bool HasScore(IActivity item, string state) 27 | { 28 | return !string.IsNullOrWhiteSpace(state); 29 | } 30 | 31 | protected async override Task PostAsync(IActivity item, string state, CancellationToken token) 32 | { 33 | var searchResult = await this.searchService.Search(state); 34 | 35 | var replyActivity = ((Activity)item).CreateReply(); 36 | await CardUtil.ShowSearchResults(replyActivity, searchResult, $"I'm sorry, I did not understand '{state}'.\nType 'help' to know more about me :)"); 37 | } 38 | 39 | protected async override Task PrepareAsync(IActivity item, CancellationToken token) 40 | { 41 | var message = item.AsMessageActivity(); 42 | if (message != null && !string.IsNullOrWhiteSpace(message.Text)) 43 | { 44 | if (message.Text.Trim().StartsWith(TRIGGER, StringComparison.InvariantCultureIgnoreCase)) 45 | { 46 | return message.Text.Substring(TRIGGER.Length); 47 | } 48 | } 49 | 50 | return null; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /CSharp/exercise6-MoodDetetion/Exercise6.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Exercise6", "Exercise6.csproj", "{3800949E-4BA5-4D99-9EC4-F940AE29FBE1}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {3800949E-4BA5-4D99-9EC4-F940AE29FBE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {3800949E-4BA5-4D99-9EC4-F940AE29FBE1}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {3800949E-4BA5-4D99-9EC4-F940AE29FBE1}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {3800949E-4BA5-4D99-9EC4-F940AE29FBE1}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /CSharp/exercise6-MoodDetetion/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="HelpDeskBot.WebApiApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /CSharp/exercise6-MoodDetetion/Global.asax.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot 2 | { 3 | using System.Web.Http; 4 | using Autofac; 5 | using Dialogs; 6 | using Microsoft.Bot.Builder.Dialogs; 7 | using Microsoft.Bot.Builder.Scorables; 8 | using Microsoft.Bot.Connector; 9 | 10 | public class WebApiApplication : System.Web.HttpApplication 11 | { 12 | protected void Application_Start() 13 | { 14 | GlobalConfiguration.Configure(WebApiConfig.Register); 15 | 16 | var builder = new ContainerBuilder(); 17 | 18 | builder.RegisterType() 19 | .As>() 20 | .InstancePerLifetimeScope(); 21 | 22 | builder.RegisterType() 23 | .As>() 24 | .InstancePerLifetimeScope(); 25 | 26 | builder.Update(Conversation.Container); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /CSharp/exercise6-MoodDetetion/Model/Category.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | public class Category 4 | { 5 | public int Count { get; set; } 6 | 7 | public string Value { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /CSharp/exercise6-MoodDetetion/Model/FacetResult.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | using Newtonsoft.Json; 4 | 5 | public class FacetResult 6 | { 7 | [JsonProperty("@odata.context")] 8 | public string ODataContext { get; set; } 9 | 10 | [JsonProperty("@search.facets")] 11 | public SearchFacets Facets { get; set; } 12 | 13 | public SearchResultHit[] Value { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /CSharp/exercise6-MoodDetetion/Model/SearchFacets.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | using Newtonsoft.Json; 4 | 5 | public class SearchFacets 6 | { 7 | [JsonProperty("category@odata.type")] 8 | public string CategoryOdataType { get; set; } 9 | 10 | public Category[] Category { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /CSharp/exercise6-MoodDetetion/Model/SearchResult.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | using Newtonsoft.Json; 4 | 5 | public class SearchResult 6 | { 7 | [JsonProperty("@odata.context")] 8 | public string ODataContext { get; set; } 9 | 10 | public SearchResultHit[] Value { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /CSharp/exercise6-MoodDetetion/Model/SearchResultHit.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | using Newtonsoft.Json; 4 | 5 | public class SearchResultHit 6 | { 7 | [JsonProperty("@search.score")] 8 | public float SearchScore { get; set; } 9 | 10 | public string Title { get; set; } 11 | 12 | public string Category { get; set; } 13 | 14 | public string Text { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /CSharp/exercise6-MoodDetetion/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Exercise6-MoodDetection")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Exercise6-MoodDetection")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("a8ba1066-5695-4d71-abb4-65e5a5e0c3d4")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /CSharp/exercise6-MoodDetetion/Util/TicketAPIClient.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Util 2 | { 3 | using System; 4 | using System.Net.Http; 5 | using System.Net.Http.Headers; 6 | using System.Threading.Tasks; 7 | using System.Web.Configuration; 8 | 9 | public class Ticket 10 | { 11 | public string Category { get; set; } 12 | 13 | public string Severity { get; set; } 14 | 15 | public string Description { get; set; } 16 | } 17 | 18 | public class TicketAPIClient 19 | { 20 | public async Task PostTicketAsync(string category, string severity, string description) 21 | { 22 | try 23 | { 24 | using (var client = new HttpClient()) 25 | { 26 | client.BaseAddress = new Uri(WebConfigurationManager.AppSettings["TicketsAPIBaseUrl"]); 27 | client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 28 | 29 | var issue = new Ticket 30 | { 31 | Category = category, 32 | Severity = severity, 33 | Description = description 34 | }; 35 | 36 | var response = await client.PostAsJsonAsync("api/tickets", issue); 37 | return await response.Content.ReadAsAsync(); 38 | } 39 | } 40 | catch 41 | { 42 | return -1; 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /CSharp/exercise6-MoodDetetion/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /CSharp/exercise6-MoodDetetion/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /CSharp/exercise6-MoodDetetion/default.htm: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 |

exercise 6

9 |

Describe your bot here and your terms of use etc.

10 |

Visit Bot Framework to register your bot. When you register it, remember to set your bot's endpoint to

https://your_bots_hostname/api/messages

11 | 12 | 13 | -------------------------------------------------------------------------------- /CSharp/exercise6-MoodDetetion/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /CSharp/exercise7-HandOffToHuman/App_Start/WebApiConfig.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot 2 | { 3 | using System.Web.Http; 4 | using Newtonsoft.Json; 5 | using Newtonsoft.Json.Serialization; 6 | 7 | public static class WebApiConfig 8 | { 9 | public static void Register(HttpConfiguration config) 10 | { 11 | // Json settings 12 | config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; 13 | config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 14 | config.Formatters.JsonFormatter.SerializerSettings.Formatting = Formatting.Indented; 15 | JsonConvert.DefaultSettings = () => new JsonSerializerSettings() 16 | { 17 | ContractResolver = new CamelCasePropertyNamesContractResolver(), 18 | Formatting = Newtonsoft.Json.Formatting.Indented, 19 | NullValueHandling = NullValueHandling.Ignore, 20 | }; 21 | 22 | // Web API configuration and services 23 | 24 | // Web API routes 25 | config.MapHttpAttributeRoutes(); 26 | 27 | config.Routes.MapHttpRoute( 28 | name: "DefaultApi", 29 | routeTemplate: "api/{controller}/{id}", 30 | defaults: new { id = RouteParameter.Optional }); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /CSharp/exercise7-HandOffToHuman/Controllers/TicketsController.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Web.Http; 6 | using Util; 7 | 8 | public class TicketsController : ApiController 9 | { 10 | private static int nextTicketId = 1; 11 | private static Dictionary tickets = new Dictionary(); 12 | 13 | [HttpPost] 14 | public IHttpActionResult Post(Ticket ticket) 15 | { 16 | int ticketId; 17 | 18 | Console.WriteLine("Ticket accepted: category:" + ticket.Category + " severity:" + ticket.Severity + " description:" + ticket.Description); 19 | 20 | lock (tickets) 21 | { 22 | ticketId = nextTicketId++; 23 | TicketsController.tickets.Add(ticketId, ticket); 24 | } 25 | 26 | return this.Ok(ticketId.ToString()); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /CSharp/exercise7-HandOffToHuman/Dialogs/SearchScorable.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Dialogs 2 | { 3 | using System; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | using Microsoft.Bot.Builder.Scorables.Internals; 7 | using Microsoft.Bot.Connector; 8 | using Services; 9 | using Util; 10 | 11 | public class SearchScorable : ScorableBase 12 | { 13 | private const string TRIGGER = "search about "; 14 | private readonly AzureSearchService searchService = new AzureSearchService(); 15 | 16 | protected override Task DoneAsync(IActivity item, string state, CancellationToken token) 17 | { 18 | return Task.CompletedTask; 19 | } 20 | 21 | protected override double GetScore(IActivity item, string state) 22 | { 23 | return 1.0; 24 | } 25 | 26 | protected override bool HasScore(IActivity item, string state) 27 | { 28 | return !string.IsNullOrWhiteSpace(state); 29 | } 30 | 31 | protected async override Task PostAsync(IActivity item, string state, CancellationToken token) 32 | { 33 | var searchResult = await this.searchService.Search(state); 34 | 35 | var replyActivity = ((Activity)item).CreateReply(); 36 | await CardUtil.ShowSearchResults(replyActivity, searchResult, $"I'm sorry, I did not understand '{state}'.\nType 'help' to know more about me :)"); 37 | } 38 | 39 | protected async override Task PrepareAsync(IActivity item, CancellationToken token) 40 | { 41 | var message = item.AsMessageActivity(); 42 | if (message != null && !string.IsNullOrWhiteSpace(message.Text)) 43 | { 44 | if (message.Text.Trim().StartsWith(TRIGGER, StringComparison.InvariantCultureIgnoreCase)) 45 | { 46 | return message.Text.Substring(TRIGGER.Length); 47 | } 48 | } 49 | 50 | return null; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /CSharp/exercise7-HandOffToHuman/Exercise7.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Exercise7", "Exercise7.csproj", "{C2970C02-3230-4240-B1C6-64CD35210E35}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {C2970C02-3230-4240-B1C6-64CD35210E35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {C2970C02-3230-4240-B1C6-64CD35210E35}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {C2970C02-3230-4240-B1C6-64CD35210E35}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {C2970C02-3230-4240-B1C6-64CD35210E35}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /CSharp/exercise7-HandOffToHuman/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="HelpDeskBot.WebApiApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /CSharp/exercise7-HandOffToHuman/Global.asax.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot 2 | { 3 | using System.Web.Http; 4 | using Autofac; 5 | using Dialogs; 6 | using HandOff; 7 | using Microsoft.Bot.Builder.Dialogs.Internals; 8 | using Microsoft.Bot.Builder.Scorables; 9 | using Microsoft.Bot.Connector; 10 | 11 | public class WebApiApplication : System.Web.HttpApplication 12 | { 13 | protected void Application_Start() 14 | { 15 | GlobalConfiguration.Configure(WebApiConfig.Register); 16 | 17 | var builder = new ContainerBuilder(); 18 | 19 | // Hand Off Scorables, Provider and UserRoleResolver 20 | builder.Register(c => new RouterScorable(c.Resolve(), c.Resolve(), c.Resolve())) 21 | .As>().InstancePerLifetimeScope(); 22 | builder.Register(c => new CommandScorable(c.Resolve(), c.Resolve(), c.Resolve())) 23 | .As>().InstancePerLifetimeScope(); 24 | builder.RegisterType() 25 | .SingleInstance(); 26 | 27 | // Bot Scorables 28 | builder.Register(c => new AgentLoginScorable(c.Resolve(), c.Resolve())) 29 | .As>() 30 | .InstancePerLifetimeScope(); 31 | builder.RegisterType() 32 | .As>() 33 | .InstancePerLifetimeScope(); 34 | builder.RegisterType() 35 | .As>() 36 | .InstancePerLifetimeScope(); 37 | builder.Update(Microsoft.Bot.Builder.Dialogs.Conversation.Container); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /CSharp/exercise7-HandOffToHuman/HandOff/AgentExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.HandOff 2 | { 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using Microsoft.Bot.Builder.Dialogs.Internals; 6 | 7 | public static class AgentExtensions 8 | { 9 | private const string ISAGENT = "isAgent"; 10 | 11 | public static bool IsAgent(this IBotData botData) 12 | { 13 | bool isAgent = false; 14 | botData.ConversationData.TryGetValue(ISAGENT, out isAgent); 15 | return isAgent; 16 | } 17 | 18 | public static Task SetAgent(this IBotData botData, bool value, CancellationToken token) 19 | { 20 | botData.ConversationData.SetValue(ISAGENT, value); 21 | return botData.FlushAsync(token); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /CSharp/exercise7-HandOffToHuman/Model/Category.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | public class Category 4 | { 5 | public int Count { get; set; } 6 | 7 | public string Value { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /CSharp/exercise7-HandOffToHuman/Model/FacetResult.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | using Newtonsoft.Json; 4 | 5 | public class FacetResult 6 | { 7 | [JsonProperty("@odata.context")] 8 | public string ODataContext { get; set; } 9 | 10 | [JsonProperty("@search.facets")] 11 | public SearchFacets Facets { get; set; } 12 | 13 | public SearchResultHit[] Value { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /CSharp/exercise7-HandOffToHuman/Model/SearchFacets.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | using Newtonsoft.Json; 4 | 5 | public class SearchFacets 6 | { 7 | [JsonProperty("category@odata.type")] 8 | public string CategoryOdataType { get; set; } 9 | 10 | public Category[] Category { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /CSharp/exercise7-HandOffToHuman/Model/SearchResult.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | using Newtonsoft.Json; 4 | 5 | public class SearchResult 6 | { 7 | [JsonProperty("@odata.context")] 8 | public string ODataContext { get; set; } 9 | 10 | public SearchResultHit[] Value { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /CSharp/exercise7-HandOffToHuman/Model/SearchResultHit.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | using Newtonsoft.Json; 4 | 5 | public class SearchResultHit 6 | { 7 | [JsonProperty("@search.score")] 8 | public float SearchScore { get; set; } 9 | 10 | public string Title { get; set; } 11 | 12 | public string Category { get; set; } 13 | 14 | public string Text { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /CSharp/exercise7-HandOffToHuman/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Exercise7-HandOffToHuman")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Exercise7-HandOffToHuman")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("a8ba1066-5695-4d71-abb4-65e5a5e0c3d4")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /CSharp/exercise7-HandOffToHuman/Util/TicketAPIClient.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Util 2 | { 3 | using System; 4 | using System.Net.Http; 5 | using System.Net.Http.Headers; 6 | using System.Threading.Tasks; 7 | using System.Web.Configuration; 8 | 9 | public class Ticket 10 | { 11 | public string Category { get; set; } 12 | 13 | public string Severity { get; set; } 14 | 15 | public string Description { get; set; } 16 | } 17 | 18 | public class TicketAPIClient 19 | { 20 | public async Task PostTicketAsync(string category, string severity, string description) 21 | { 22 | try 23 | { 24 | using (var client = new HttpClient()) 25 | { 26 | client.BaseAddress = new Uri(WebConfigurationManager.AppSettings["TicketsAPIBaseUrl"]); 27 | client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 28 | 29 | var issue = new Ticket 30 | { 31 | Category = category, 32 | Severity = severity, 33 | Description = description 34 | }; 35 | 36 | var response = await client.PostAsJsonAsync("api/tickets", issue); 37 | return await response.Content.ReadAsAsync(); 38 | } 39 | } 40 | catch 41 | { 42 | return -1; 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /CSharp/exercise7-HandOffToHuman/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /CSharp/exercise7-HandOffToHuman/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /CSharp/exercise7-HandOffToHuman/default.htm: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 |

exercise 7

9 |

Describe your bot here and your terms of use etc.

10 |

Visit Bot Framework to register your bot. When you register it, remember to set your bot's endpoint to

https://your_bots_hostname/api/messages

11 | 12 | 13 | -------------------------------------------------------------------------------- /CSharp/exercise7-HandOffToHuman/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /CSharp/exercise8-BackChannel/App_Start/WebApiConfig.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot 2 | { 3 | using System.Web.Http; 4 | using Newtonsoft.Json; 5 | using Newtonsoft.Json.Serialization; 6 | 7 | public static class WebApiConfig 8 | { 9 | public static void Register(HttpConfiguration config) 10 | { 11 | // Json settings 12 | config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; 13 | config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 14 | config.Formatters.JsonFormatter.SerializerSettings.Formatting = Formatting.Indented; 15 | JsonConvert.DefaultSettings = () => new JsonSerializerSettings() 16 | { 17 | ContractResolver = new CamelCasePropertyNamesContractResolver(), 18 | Formatting = Newtonsoft.Json.Formatting.Indented, 19 | NullValueHandling = NullValueHandling.Ignore, 20 | }; 21 | 22 | // Web API configuration and services 23 | 24 | // Web API routes 25 | config.MapHttpAttributeRoutes(); 26 | 27 | config.Routes.MapHttpRoute( 28 | name: "DefaultApi", 29 | routeTemplate: "api/{controller}/{id}", 30 | defaults: new { id = RouteParameter.Optional }); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /CSharp/exercise8-BackChannel/Controllers/TicketsController.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Web.Http; 6 | using Util; 7 | 8 | public class TicketsController : ApiController 9 | { 10 | private static int nextTicketId = 1; 11 | private static Dictionary tickets = new Dictionary(); 12 | 13 | [HttpPost] 14 | public IHttpActionResult Post(Ticket ticket) 15 | { 16 | int ticketId; 17 | 18 | Console.WriteLine("Ticket accepted: category:" + ticket.Category + " severity:" + ticket.Severity + " description:" + ticket.Description); 19 | 20 | lock (tickets) 21 | { 22 | ticketId = nextTicketId++; 23 | TicketsController.tickets.Add(ticketId, ticket); 24 | } 25 | 26 | return this.Ok(ticketId.ToString()); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /CSharp/exercise8-BackChannel/Dialogs/SearchScorable.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Dialogs 2 | { 3 | using System; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | using Microsoft.Bot.Builder.Scorables.Internals; 7 | using Microsoft.Bot.Connector; 8 | using Services; 9 | using Util; 10 | 11 | public class SearchScorable : ScorableBase 12 | { 13 | private const string TRIGGER = "search about "; 14 | private readonly AzureSearchService searchService = new AzureSearchService(); 15 | 16 | protected override Task DoneAsync(IActivity item, string state, CancellationToken token) 17 | { 18 | return Task.CompletedTask; 19 | } 20 | 21 | protected override double GetScore(IActivity item, string state) 22 | { 23 | return 1.0; 24 | } 25 | 26 | protected override bool HasScore(IActivity item, string state) 27 | { 28 | return !string.IsNullOrWhiteSpace(state); 29 | } 30 | 31 | protected async override Task PostAsync(IActivity item, string state, CancellationToken token) 32 | { 33 | var searchResult = await this.searchService.Search(state); 34 | 35 | var replyActivity = ((Activity)item).CreateReply(); 36 | await CardUtil.ShowSearchResults(replyActivity, searchResult, $"I'm sorry, I did not understand '{state}'.\nType 'help' to know more about me :)"); 37 | } 38 | 39 | protected async override Task PrepareAsync(IActivity item, CancellationToken token) 40 | { 41 | var message = item.AsMessageActivity(); 42 | if (message != null && !string.IsNullOrWhiteSpace(message.Text)) 43 | { 44 | if (message.Text.Trim().StartsWith(TRIGGER, StringComparison.InvariantCultureIgnoreCase)) 45 | { 46 | return message.Text.Substring(TRIGGER.Length); 47 | } 48 | } 49 | 50 | return null; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /CSharp/exercise8-BackChannel/Exercise8.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Exercise8", "Exercise8.csproj", "{DF00915E-23C3-4F27-8986-5F9BF88196CE}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {DF00915E-23C3-4F27-8986-5F9BF88196CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {DF00915E-23C3-4F27-8986-5F9BF88196CE}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {DF00915E-23C3-4F27-8986-5F9BF88196CE}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {DF00915E-23C3-4F27-8986-5F9BF88196CE}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /CSharp/exercise8-BackChannel/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="HelpDeskBot.WebApiApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /CSharp/exercise8-BackChannel/Global.asax.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot 2 | { 3 | using System.Web.Http; 4 | using Autofac; 5 | using Dialogs; 6 | using HandOff; 7 | using Microsoft.Bot.Builder.Dialogs.Internals; 8 | using Microsoft.Bot.Builder.Scorables; 9 | using Microsoft.Bot.Connector; 10 | 11 | public class WebApiApplication : System.Web.HttpApplication 12 | { 13 | protected void Application_Start() 14 | { 15 | GlobalConfiguration.Configure(WebApiConfig.Register); 16 | 17 | var builder = new ContainerBuilder(); 18 | 19 | // Hand Off Scorables, Provider and UserRoleResolver 20 | builder.Register(c => new RouterScorable(c.Resolve(), c.Resolve(), c.Resolve())) 21 | .As>().InstancePerLifetimeScope(); 22 | builder.Register(c => new CommandScorable(c.Resolve(), c.Resolve(), c.Resolve())) 23 | .As>().InstancePerLifetimeScope(); 24 | builder.RegisterType() 25 | .SingleInstance(); 26 | 27 | // Bot Scorables 28 | builder.Register(c => new AgentLoginScorable(c.Resolve(), c.Resolve())) 29 | .As>() 30 | .InstancePerLifetimeScope(); 31 | builder.RegisterType() 32 | .As>() 33 | .InstancePerLifetimeScope(); 34 | builder.RegisterType() 35 | .As>() 36 | .InstancePerLifetimeScope(); 37 | builder.Update(Microsoft.Bot.Builder.Dialogs.Conversation.Container); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /CSharp/exercise8-BackChannel/HandOff/AgentExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.HandOff 2 | { 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using Microsoft.Bot.Builder.Dialogs.Internals; 6 | 7 | public static class AgentExtensions 8 | { 9 | private const string ISAGENT = "isAgent"; 10 | 11 | public static bool IsAgent(this IBotData botData) 12 | { 13 | bool isAgent = false; 14 | botData.ConversationData.TryGetValue(ISAGENT, out isAgent); 15 | return isAgent; 16 | } 17 | 18 | public static Task SetAgent(this IBotData botData, bool value, CancellationToken token) 19 | { 20 | botData.ConversationData.SetValue(ISAGENT, value); 21 | return botData.FlushAsync(token); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /CSharp/exercise8-BackChannel/Model/Category.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | public class Category 4 | { 5 | public int Count { get; set; } 6 | 7 | public string Value { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /CSharp/exercise8-BackChannel/Model/FacetResult.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | using Newtonsoft.Json; 4 | 5 | public class FacetResult 6 | { 7 | [JsonProperty("@odata.context")] 8 | public string ODataContext { get; set; } 9 | 10 | [JsonProperty("@search.facets")] 11 | public SearchFacets Facets { get; set; } 12 | 13 | public SearchResultHit[] Value { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /CSharp/exercise8-BackChannel/Model/SearchFacets.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | using Newtonsoft.Json; 4 | 5 | public class SearchFacets 6 | { 7 | [JsonProperty("category@odata.type")] 8 | public string CategoryOdataType { get; set; } 9 | 10 | public Category[] Category { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /CSharp/exercise8-BackChannel/Model/SearchResult.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | using Newtonsoft.Json; 4 | 5 | public class SearchResult 6 | { 7 | [JsonProperty("@odata.context")] 8 | public string ODataContext { get; set; } 9 | 10 | public SearchResultHit[] Value { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /CSharp/exercise8-BackChannel/Model/SearchResultHit.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | using Newtonsoft.Json; 4 | 5 | public class SearchResultHit 6 | { 7 | [JsonProperty("@search.score")] 8 | public float SearchScore { get; set; } 9 | 10 | public string Title { get; set; } 11 | 12 | public string Category { get; set; } 13 | 14 | public string Text { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /CSharp/exercise8-BackChannel/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Exercise8-BackChannel")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Exercise8-BackChannel")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("a8ba1066-5695-4d71-abb4-65e5a5e0c3d4")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /CSharp/exercise8-BackChannel/Util/TicketAPIClient.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Util 2 | { 3 | using System; 4 | using System.Net.Http; 5 | using System.Net.Http.Headers; 6 | using System.Threading.Tasks; 7 | using System.Web.Configuration; 8 | 9 | public class Ticket 10 | { 11 | public string Category { get; set; } 12 | 13 | public string Severity { get; set; } 14 | 15 | public string Description { get; set; } 16 | } 17 | 18 | public class TicketAPIClient 19 | { 20 | public async Task PostTicketAsync(string category, string severity, string description) 21 | { 22 | try 23 | { 24 | using (var client = new HttpClient()) 25 | { 26 | client.BaseAddress = new Uri(WebConfigurationManager.AppSettings["TicketsAPIBaseUrl"]); 27 | client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 28 | 29 | var issue = new Ticket 30 | { 31 | Category = category, 32 | Severity = severity, 33 | Description = description 34 | }; 35 | 36 | var response = await client.PostAsJsonAsync("api/tickets", issue); 37 | return await response.Content.ReadAsAsync(); 38 | } 39 | } 40 | catch 41 | { 42 | return -1; 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /CSharp/exercise8-BackChannel/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /CSharp/exercise8-BackChannel/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /CSharp/exercise8-BackChannel/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /CSharp/images/demo-formflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/demo-formflow.png -------------------------------------------------------------------------------- /CSharp/images/exercise1-default-htm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise1-default-htm.png -------------------------------------------------------------------------------- /CSharp/images/exercise1-echo-bot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise1-echo-bot.png -------------------------------------------------------------------------------- /CSharp/images/exercise1-new-project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise1-new-project.png -------------------------------------------------------------------------------- /CSharp/images/exercise1-run-project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise1-run-project.png -------------------------------------------------------------------------------- /CSharp/images/exercise2-dialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise2-dialog.png -------------------------------------------------------------------------------- /CSharp/images/exercise2-emulator-adaptivecards.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise2-emulator-adaptivecards.png -------------------------------------------------------------------------------- /CSharp/images/exercise2-full-conversation-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise2-full-conversation-1.png -------------------------------------------------------------------------------- /CSharp/images/exercise2-full-conversation-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise2-full-conversation-2.png -------------------------------------------------------------------------------- /CSharp/images/exercise2-start-new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise2-start-new.png -------------------------------------------------------------------------------- /CSharp/images/exercise3-addluisapp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise3-addluisapp.png -------------------------------------------------------------------------------- /CSharp/images/exercise3-dialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise3-dialog.png -------------------------------------------------------------------------------- /CSharp/images/exercise3-hello.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise3-hello.png -------------------------------------------------------------------------------- /CSharp/images/exercise3-hi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise3-hi.png -------------------------------------------------------------------------------- /CSharp/images/exercise3-luis-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise3-luis-dashboard.png -------------------------------------------------------------------------------- /CSharp/images/exercise3-luis-entity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise3-luis-entity.png -------------------------------------------------------------------------------- /CSharp/images/exercise3-luis-mykeys.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise3-luis-mykeys.png -------------------------------------------------------------------------------- /CSharp/images/exercise3-luis-recognizedutterances.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise3-luis-recognizedutterances.png -------------------------------------------------------------------------------- /CSharp/images/exercise3-save-utterances.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise3-save-utterances.png -------------------------------------------------------------------------------- /CSharp/images/exercise3-severity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise3-severity.png -------------------------------------------------------------------------------- /CSharp/images/exercise3-suggested-utterances.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise3-suggested-utterances.png -------------------------------------------------------------------------------- /CSharp/images/exercise3-test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise3-test.png -------------------------------------------------------------------------------- /CSharp/images/exercise3-unknown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise3-unknown.png -------------------------------------------------------------------------------- /CSharp/images/exercise4-azuresearch-createdatasource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise4-azuresearch-createdatasource.png -------------------------------------------------------------------------------- /CSharp/images/exercise4-azuresearch-createindexer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise4-azuresearch-createindexer.png -------------------------------------------------------------------------------- /CSharp/images/exercise4-azuresearch-managekeys.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise4-azuresearch-managekeys.png -------------------------------------------------------------------------------- /CSharp/images/exercise4-createdocumentdb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise4-createdocumentdb.png -------------------------------------------------------------------------------- /CSharp/images/exercise4-createsearchservice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise4-createsearchservice.png -------------------------------------------------------------------------------- /CSharp/images/exercise4-documentdb-addcollection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise4-documentdb-addcollection.png -------------------------------------------------------------------------------- /CSharp/images/exercise4-documentdb-uploadfiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise4-documentdb-uploadfiles.png -------------------------------------------------------------------------------- /CSharp/images/exercise4-emulator-detailsofarticle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise4-emulator-detailsofarticle.png -------------------------------------------------------------------------------- /CSharp/images/exercise4-emulator-explorecategory2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise4-emulator-explorecategory2.png -------------------------------------------------------------------------------- /CSharp/images/exercise4-emulator-explorekb2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise4-emulator-explorekb2.png -------------------------------------------------------------------------------- /CSharp/images/exercise4-emulator-search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise4-emulator-search.png -------------------------------------------------------------------------------- /CSharp/images/exercise4-emulator-showkbresults.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise4-emulator-showkbresults.png -------------------------------------------------------------------------------- /CSharp/images/exercise4-faq-index-facets-matrix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise4-faq-index-facets-matrix.png -------------------------------------------------------------------------------- /CSharp/images/exercise4-import-data-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise4-import-data-button.png -------------------------------------------------------------------------------- /CSharp/images/exercise4-new-intent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise4-new-intent.png -------------------------------------------------------------------------------- /CSharp/images/exercise4-new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise4-new.png -------------------------------------------------------------------------------- /CSharp/images/exercise4-testbit-explorehardware.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise4-testbit-explorehardware.png -------------------------------------------------------------------------------- /CSharp/images/exercise5-addappsettings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise5-addappsettings.png -------------------------------------------------------------------------------- /CSharp/images/exercise5-addbottoskype.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise5-addbottoskype.png -------------------------------------------------------------------------------- /CSharp/images/exercise5-botchannels.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise5-botchannels.png -------------------------------------------------------------------------------- /CSharp/images/exercise5-botconfiguration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise5-botconfiguration.png -------------------------------------------------------------------------------- /CSharp/images/exercise5-botname.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise5-botname.png -------------------------------------------------------------------------------- /CSharp/images/exercise5-generateappid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise5-generateappid.png -------------------------------------------------------------------------------- /CSharp/images/exercise5-generatepassword.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise5-generatepassword.png -------------------------------------------------------------------------------- /CSharp/images/exercise5-savebutton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise5-savebutton.png -------------------------------------------------------------------------------- /CSharp/images/exercise5-testskype.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise5-testskype.png -------------------------------------------------------------------------------- /CSharp/images/exercise5-testwebchannel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise5-testwebchannel.png -------------------------------------------------------------------------------- /CSharp/images/exercise5-vs-createappservice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise5-vs-createappservice.png -------------------------------------------------------------------------------- /CSharp/images/exercise5-vs-publish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise5-vs-publish.png -------------------------------------------------------------------------------- /CSharp/images/exercise6-negativefeedback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise6-negativefeedback.png -------------------------------------------------------------------------------- /CSharp/images/exercise6-positivefeedback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise6-positivefeedback.png -------------------------------------------------------------------------------- /CSharp/images/exercise6-test-providefeedback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise6-test-providefeedback.png -------------------------------------------------------------------------------- /CSharp/images/exercise6-text-analytics-keys.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise6-text-analytics-keys.png -------------------------------------------------------------------------------- /CSharp/images/exercise7-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise7-diagram.png -------------------------------------------------------------------------------- /CSharp/images/exercise7-test-agent-connect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise7-test-agent-connect.png -------------------------------------------------------------------------------- /CSharp/images/exercise7-test-agent-login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise7-test-agent-login.png -------------------------------------------------------------------------------- /CSharp/images/exercise7-test-agent-resume.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise7-test-agent-resume.png -------------------------------------------------------------------------------- /CSharp/images/exercise7-test-agent-talk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise7-test-agent-talk.png -------------------------------------------------------------------------------- /CSharp/images/exercise7-test-user-connect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise7-test-user-connect.png -------------------------------------------------------------------------------- /CSharp/images/exercise7-test-user-resume.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise7-test-user-resume.png -------------------------------------------------------------------------------- /CSharp/images/exercise7-test-user-talk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise7-test-user-talk.png -------------------------------------------------------------------------------- /CSharp/images/exercise7-test-user-ticketfeedback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise7-test-user-ticketfeedback.png -------------------------------------------------------------------------------- /CSharp/images/exercise7-test-user-waitagent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise7-test-user-waitagent.png -------------------------------------------------------------------------------- /CSharp/images/exercise8-addnewsite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise8-addnewsite.png -------------------------------------------------------------------------------- /CSharp/images/exercise8-backchannel-webchat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise8-backchannel-webchat.png -------------------------------------------------------------------------------- /CSharp/images/exercise8-edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise8-edit.png -------------------------------------------------------------------------------- /CSharp/images/exercise8-ngrok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise8-ngrok.png -------------------------------------------------------------------------------- /CSharp/images/exercise8-webchat-articles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise8-webchat-articles.png -------------------------------------------------------------------------------- /CSharp/images/exercise8-webchat-articlesdetail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise8-webchat-articlesdetail.png -------------------------------------------------------------------------------- /CSharp/images/exercise8-webchatsecrets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/CSharp/images/exercise8-webchatsecrets.png -------------------------------------------------------------------------------- /Node/exercise1-EchoBot/.env: -------------------------------------------------------------------------------- 1 | # Do not use this in production, use App Settings instead. 2 | PORT=3978 3 | MICROSOFT_APP_ID= 4 | MICROSOFT_APP_PASSWORD= -------------------------------------------------------------------------------- /Node/exercise1-EchoBot/app.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | require('dotenv').config(); 3 | const restify = require('restify'); 4 | const builder = require('botbuilder'); 5 | 6 | // Setup Restify Server 7 | var server = restify.createServer(); 8 | server.listen(process.env.port || process.env.PORT || 3978, () => { 9 | console.log('%s listening to %s', server.name, server.url); 10 | }); 11 | 12 | // Create chat connector for communicating with the Bot Framework Service 13 | var connector = new builder.ChatConnector({ 14 | appId: process.env.MICROSOFT_APP_ID, 15 | appPassword: process.env.MICROSOFT_APP_PASSWORD 16 | }); 17 | 18 | // Listen for messages from users 19 | server.post('/api/messages', connector.listen()); 20 | 21 | // Receive messages from the user and respond by echoing each message back (prefixed with 'You said:') 22 | var bot = new builder.UniversalBot(connector, [ 23 | (session, args, next) => { 24 | session.send('You said: ' + session.message.text + ' which was ' + session.message.text.length + ' characters'); 25 | } 26 | ]); -------------------------------------------------------------------------------- /Node/exercise1-EchoBot/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "echo-bot", 3 | "version": "0.1.0", 4 | "license": "MIT", 5 | "description": "Echo bot example", 6 | "scripts": { 7 | "nodewatch": "nodemon app.js", 8 | "start": "nodemon app.js", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "dependencies": { 12 | "botbuilder": "^3.8.4", 13 | "dotenv": "^4.0.0", 14 | "restify": "^4.3.0" 15 | }, 16 | "devDependencies": { 17 | "nodemon": "^1.11.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Node/exercise2-TicketSubmissionDialog/.env: -------------------------------------------------------------------------------- 1 | # Do not use this in production, use App Settings instead. 2 | PORT=3978 3 | MICROSOFT_APP_ID= 4 | MICROSOFT_APP_PASSWORD= -------------------------------------------------------------------------------- /Node/exercise2-TicketSubmissionDialog/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ticket-submission-dialog", 3 | "version": "0.1.0", 4 | "license": "MIT", 5 | "description": "Ticket Submission bot example", 6 | "scripts": { 7 | "nodewatch": "nodemon app.js", 8 | "start": "nodemon app.js", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "dependencies": { 12 | "botbuilder": "^3.8.4", 13 | "dotenv": "^4.0.0", 14 | "restify": "^4.3.0" 15 | }, 16 | "devDependencies": { 17 | "nodemon": "^1.11.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Node/exercise2-TicketSubmissionDialog/ticketsApi.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | var tickets = []; 3 | var lastTicketId = 1; 4 | 5 | module.exports = (req, res) => { 6 | console.log('Ticket received: ', req.body); 7 | let ticketId = lastTicketId++; 8 | var ticket = req.body; 9 | ticket.id = ticketId; 10 | tickets.push(ticket); 11 | 12 | res.send(ticketId.toString()); 13 | }; 14 | -------------------------------------------------------------------------------- /Node/exercise3-LuisDialog/.env: -------------------------------------------------------------------------------- 1 | # Do not use this in production, use App Settings instead. 2 | PORT=3978 3 | MICROSOFT_APP_ID= 4 | MICROSOFT_APP_PASSWORD= 5 | LUIS_MODEL_URL= -------------------------------------------------------------------------------- /Node/exercise3-LuisDialog/cards/ticket.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", 3 | "type": "AdaptiveCard", 4 | "version": "1.0", 5 | "body": [ 6 | { 7 | "type": "TextBlock", 8 | "text": "Ticket #{ticketId}", 9 | "weight": "bolder", 10 | "size": "large", 11 | "speak": "You've created a new Ticket #{ticketId}We will contact you soon." 12 | }, 13 | { 14 | "type": "ColumnSet", 15 | "columns": [ 16 | { 17 | "type": "Column", 18 | "size": "1", 19 | "items": [ 20 | { 21 | "type": "FactSet", 22 | "facts": [ 23 | { 24 | "title": "Severity:", 25 | "value": "{severity}" 26 | }, 27 | { 28 | "title": "Category:", 29 | "value": "{category}" 30 | } 31 | ] 32 | } 33 | ] 34 | }, 35 | { 36 | "type": "Column", 37 | "size": "auto", 38 | "items": [ 39 | { 40 | "type": "Image", 41 | "url": "https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/master/assets/botimages/head-smiling-medium.png", 42 | "horizontalAlignment": "right" 43 | } 44 | ] 45 | } 46 | ], 47 | "separation": "strong" 48 | }, 49 | { 50 | "type": "TextBlock", 51 | "text": "{description}", 52 | "speak": "", 53 | "wrap": true 54 | } 55 | ] 56 | } -------------------------------------------------------------------------------- /Node/exercise3-LuisDialog/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "luis-dialog", 3 | "version": "0.1.0", 4 | "license": "MIT", 5 | "description": "Luis bot example", 6 | "scripts": { 7 | "nodewatch": "nodemon app.js", 8 | "start": "nodemon app.js", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "dependencies": { 12 | "botbuilder": "^3.8.4", 13 | "dotenv": "^4.0.0", 14 | "restify": "^4.3.0" 15 | }, 16 | "devDependencies": { 17 | "nodemon": "^1.11.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Node/exercise3-LuisDialog/ticketsApi.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | 3 | var tickets = []; 4 | var lastTicketId = 1; 5 | 6 | module.exports = (req, res) => { 7 | console.log('Ticket received: ', req.body); 8 | let ticketId = lastTicketId++; 9 | var ticket = req.body; 10 | ticket.id = ticketId; 11 | tickets.push(ticket); 12 | 13 | res.send(ticketId.toString()); 14 | }; 15 | -------------------------------------------------------------------------------- /Node/exercise4-KnowledgeBase/.env: -------------------------------------------------------------------------------- 1 | # Do not use this in production, use App Settings instead. 2 | PORT=3978 3 | MICROSOFT_APP_ID= 4 | MICROSOFT_APP_PASSWORD= 5 | LUIS_MODEL_URL= 6 | AZURE_SEARCH_ACCOUNT= 7 | AZURE_SEARCH_INDEX=knowledge-base-index 8 | AZURE_SEARCH_KEY= -------------------------------------------------------------------------------- /Node/exercise4-KnowledgeBase/azureSearchApiClient.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | const restify = require('restify'); 3 | 4 | module.exports = (config) => { 5 | return (query, callback) => { 6 | const client = restify.createJsonClient({ url: `https://${config.searchName}.search.windows.net/` }); 7 | var urlPath = `/indexes/${config.indexName}/docs?api-key=${config.searchKey}&api-version=2016-09-01&${query}`; 8 | 9 | client.get(urlPath, (err, request, response, result) => { 10 | if (!err && response && response.statusCode == 200) { 11 | callback(null, result); 12 | } else { 13 | callback(err, null); 14 | } 15 | }); 16 | }; 17 | }; 18 | -------------------------------------------------------------------------------- /Node/exercise4-KnowledgeBase/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "knowledgebase", 3 | "version": "0.1.0", 4 | "license": "MIT", 5 | "description": "Luis + Azure Search Bot example", 6 | "scripts": { 7 | "nodewatch": "nodemon app.js", 8 | "start": "nodemon app.js", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "dependencies": { 12 | "botbuilder": "^3.8.4", 13 | "dotenv": "^4.0.0", 14 | "restify": "^4.3.0" 15 | }, 16 | "devDependencies": { 17 | "nodemon": "^1.11.0" 18 | } 19 | } -------------------------------------------------------------------------------- /Node/exercise4-KnowledgeBase/ticketsApi.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | 3 | var tickets = []; 4 | var lastTicketId = 1; 5 | 6 | module.exports = (req, res) => { 7 | console.log('Ticket received: ', req.body); 8 | let ticketId = lastTicketId++; 9 | var ticket = req.body; 10 | ticket.id = ticketId; 11 | tickets.push(ticket); 12 | 13 | res.send(ticketId.toString()); 14 | }; 15 | -------------------------------------------------------------------------------- /Node/exercise6-MoodDetection/.env: -------------------------------------------------------------------------------- 1 | # Do not use this in production, use App Settings instead. 2 | PORT=3978 3 | MICROSOFT_APP_ID= 4 | MICROSOFT_APP_PASSWORD= 5 | LUIS_MODEL_URL= 6 | AZURE_SEARCH_ACCOUNT= 7 | AZURE_SEARCH_INDEX=knowledge-base-index 8 | AZURE_SEARCH_KEY= 9 | TEXT_ANALYTICS_KEY= -------------------------------------------------------------------------------- /Node/exercise6-MoodDetection/azureSearchApiClient.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | const restify = require('restify'); 3 | 4 | module.exports = (config) => { 5 | return (query, callback) => { 6 | const client = restify.createJsonClient({ url: `https://${config.searchName}.search.windows.net/` }); 7 | var urlPath = `/indexes/${config.indexName}/docs?api-key=${config.searchKey}&api-version=2016-09-01&${query}`; 8 | 9 | client.get(urlPath, (err, request, response, result) => { 10 | if (!err && response && response.statusCode == 200) { 11 | callback(null, result); 12 | } else { 13 | callback(err, null); 14 | } 15 | }); 16 | }; 17 | }; 18 | -------------------------------------------------------------------------------- /Node/exercise6-MoodDetection/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mood-detection", 3 | "version": "0.1.0", 4 | "license": "MIT", 5 | "description": "Mood Detection Bot example", 6 | "scripts": { 7 | "nodewatch": "nodemon app.js", 8 | "start": "nodemon app.js", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "dependencies": { 12 | "botbuilder": "^3.8.4", 13 | "dotenv": "^4.0.0", 14 | "restify": "^4.3.0" 15 | }, 16 | "devDependencies": { 17 | "nodemon": "^1.11.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Node/exercise6-MoodDetection/textAnalyticsApiClient.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | const restify = require('restify'); 3 | 4 | module.exports = (config) => { 5 | return (query, callback) => { 6 | const client = restify.createJsonClient({ 7 | url: `https://westus.api.cognitive.microsoft.com`, 8 | headers: { 9 | 'Ocp-Apim-Subscription-Key': config.apiKey 10 | } 11 | }); 12 | 13 | const payload = { 14 | documents: [{ 15 | language: 'en', 16 | id: 'singleId', 17 | text: query 18 | }] 19 | }; 20 | 21 | const urlPath = '/text/analytics/v2.0/sentiment'; 22 | 23 | client.post(urlPath, payload, (err, request, response, result) => { 24 | if (!err && 25 | response && 26 | response.statusCode == 200 && 27 | result.documents[0]) { 28 | callback(null, result.documents[0].score); 29 | } else { 30 | callback(err, null); 31 | } 32 | }); 33 | }; 34 | }; -------------------------------------------------------------------------------- /Node/exercise6-MoodDetection/ticketsApi.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | 3 | var tickets = []; 4 | var lastTicketId = 1; 5 | 6 | module.exports = (req, res) => { 7 | console.log('Ticket received: ', req.body); 8 | let ticketId = lastTicketId++; 9 | var ticket = req.body; 10 | ticket.id = ticketId; 11 | tickets.push(ticket); 12 | 13 | res.send(ticketId.toString()); 14 | }; 15 | -------------------------------------------------------------------------------- /Node/exercise7-HandOffToHuman/.env: -------------------------------------------------------------------------------- 1 | # Do not use this in production, use App Settings instead. 2 | PORT=3978 3 | MICROSOFT_APP_ID= 4 | MICROSOFT_APP_PASSWORD= 5 | LUIS_MODEL_URL= 6 | AZURE_SEARCH_ACCOUNT= 7 | AZURE_SEARCH_INDEX=knowledge-base-index 8 | AZURE_SEARCH_KEY= 9 | TEXT_ANALYTICS_KEY= -------------------------------------------------------------------------------- /Node/exercise7-HandOffToHuman/azureSearchApiClient.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | const restify = require('restify'); 3 | 4 | module.exports = (config) => { 5 | return (query, callback) => { 6 | const client = restify.createJsonClient({ url: `https://${config.searchName}.search.windows.net/` }); 7 | var urlPath = `/indexes/${config.indexName}/docs?api-key=${config.searchKey}&api-version=2016-09-01&${query}`; 8 | 9 | client.get(urlPath, (err, request, response, result) => { 10 | if (!err && response && response.statusCode == 200) { 11 | callback(null, result); 12 | } else { 13 | callback(err, null); 14 | } 15 | }); 16 | }; 17 | }; 18 | -------------------------------------------------------------------------------- /Node/exercise7-HandOffToHuman/handoff/provider.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | 3 | // Conversation state enumeration 4 | const ConversationState = { 5 | ConnectedToBot: 0, 6 | WaitingForAgent: 1, 7 | ConnectedToAgent: 2 8 | }; 9 | 10 | function Provider () { 11 | 'use strict'; 12 | 13 | const data = []; 14 | 15 | // return all conversations 16 | const currentConversations = () => { 17 | return data; 18 | }; 19 | 20 | // creates a new conversation 21 | const createConversation = (address) => { 22 | const conversation = { 23 | timestamp: new Date().getTime(), 24 | user: address, 25 | state: ConversationState.ConnectedToBot 26 | }; 27 | 28 | data.push(conversation); 29 | 30 | return conversation; 31 | }; 32 | 33 | // find a conversation by its user conversation id 34 | const findByConversationId = (id) => { 35 | return data.find((conversation) => conversation.user.conversation.id === id); 36 | }; 37 | 38 | // find a conversation by its agent conversation id 39 | const findByAgentId = (id) => { 40 | return data.find((conversation) => conversation.agent && conversation.agent.conversation.id === id); 41 | }; 42 | 43 | // find a conversation by its agent conversation id 44 | const peekConversation = (agent) => { 45 | var conversation = data.sort((a,b) => a.timestamp < b.timestamp).find((conversation) => conversation.state === ConversationState.WaitingForAgent); 46 | if (conversation) { 47 | conversation.state = ConversationState.ConnectedToAgent; 48 | conversation.agent = agent; 49 | } 50 | return conversation; 51 | }; 52 | 53 | return { 54 | createConversation, 55 | currentConversations, 56 | findByAgentId, 57 | findByConversationId, 58 | peekConversation 59 | }; 60 | } 61 | 62 | module.exports = { Provider, ConversationState }; -------------------------------------------------------------------------------- /Node/exercise7-HandOffToHuman/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "handofftohuman", 3 | "version": "0.1.0", 4 | "license": "MIT", 5 | "description": "Add Hand off to human feature", 6 | "scripts": { 7 | "nodewatch": "nodemon app.js", 8 | "start": "nodemon app.js", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "dependencies": { 12 | "botbuilder": "^3.8.4", 13 | "dotenv": "^4.0.0", 14 | "restify": "^4.3.0" 15 | }, 16 | "devDependencies": { 17 | "nodemon": "^1.11.0" 18 | } 19 | } -------------------------------------------------------------------------------- /Node/exercise7-HandOffToHuman/textAnalyticsApiClient.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | const restify = require('restify'); 3 | 4 | module.exports = (config) => { 5 | return (query, callback) => { 6 | const client = restify.createJsonClient({ 7 | url: `https://westus.api.cognitive.microsoft.com`, 8 | headers: { 9 | 'Ocp-Apim-Subscription-Key': config.apiKey 10 | } 11 | }); 12 | 13 | const payload = { 14 | documents: [{ 15 | language: 'en', 16 | id: 'singleId', 17 | text: query 18 | }] 19 | }; 20 | 21 | const urlPath = '/text/analytics/v2.0/sentiment'; 22 | 23 | client.post(urlPath, payload, (err, request, response, result) => { 24 | if (!err && 25 | response && 26 | response.statusCode == 200 && 27 | result.documents[0]) { 28 | callback(null, result.documents[0].score); 29 | } else { 30 | callback(err, null); 31 | } 32 | }); 33 | }; 34 | }; 35 | 36 | -------------------------------------------------------------------------------- /Node/exercise7-HandOffToHuman/ticketsApi.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | 3 | var tickets = []; 4 | var lastTicketId = 1; 5 | 6 | module.exports = (req, res) => { 7 | console.log('Ticket received: ', req.body); 8 | let ticketId = lastTicketId++; 9 | var ticket = req.body; 10 | ticket.id = ticketId; 11 | tickets.push(ticket); 12 | 13 | res.send(ticketId.toString()); 14 | }; 15 | -------------------------------------------------------------------------------- /Node/exercise8-BackChannel/.env: -------------------------------------------------------------------------------- 1 | # Do not use this in production, use App Settings instead. 2 | PORT=3978 3 | MICROSOFT_APP_ID= 4 | MICROSOFT_APP_PASSWORD= 5 | LUIS_MODEL_URL= 6 | AZURE_SEARCH_ACCOUNT= 7 | AZURE_SEARCH_INDEX=knowledge-base-index 8 | AZURE_SEARCH_KEY= 9 | TEXT_ANALYTICS_KEY= -------------------------------------------------------------------------------- /Node/exercise8-BackChannel/azureSearchApiClient.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | const restify = require('restify'); 3 | 4 | module.exports = (config) => { 5 | return (query, callback) => { 6 | const client = restify.createJsonClient({ url: `https://${config.searchName}.search.windows.net/` }); 7 | var urlPath = `/indexes/${config.indexName}/docs?api-key=${config.searchKey}&api-version=2016-09-01&${query}`; 8 | 9 | client.get(urlPath, (err, request, response, result) => { 10 | if (!err && response && response.statusCode == 200) { 11 | callback(null, result); 12 | } else { 13 | callback(err, null); 14 | } 15 | }); 16 | }; 17 | }; 18 | -------------------------------------------------------------------------------- /Node/exercise8-BackChannel/cards/ticket.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", 3 | "type": "AdaptiveCard", 4 | "version": "1.0", 5 | "body": [ 6 | { 7 | "type": "TextBlock", 8 | "text": "Ticket #{ticketId}", 9 | "weight": "bolder", 10 | "size": "large", 11 | "speak": "You've created a new Ticket #{ticketId}We will contact you soon." 12 | }, 13 | { 14 | "type": "ColumnSet", 15 | "columns": [ 16 | { 17 | "type": "Column", 18 | "size": "1", 19 | "items": [ 20 | { 21 | "type": "FactSet", 22 | "facts": [ 23 | { 24 | "title": "Severity:", 25 | "value": "{severity}" 26 | }, 27 | { 28 | "title": "Category:", 29 | "value": "{category}" 30 | } 31 | ] 32 | } 33 | ] 34 | }, 35 | { 36 | "type": "Column", 37 | "size": "auto", 38 | "items": [ 39 | { 40 | "type": "Image", 41 | "url": "https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/master/assets/botimages/head-smiling-medium.png", 42 | "horizontalAlignment": "right" 43 | } 44 | ] 45 | } 46 | ], 47 | "separation": "strong" 48 | }, 49 | { 50 | "type": "TextBlock", 51 | "text": "{description}", 52 | "speak": "", 53 | "wrap": true 54 | } 55 | ] 56 | } -------------------------------------------------------------------------------- /Node/exercise8-BackChannel/handoff/provider.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | 3 | // Conversation state enumeration 4 | const ConversationState = { 5 | ConnectedToBot: 0, 6 | WaitingForAgent: 1, 7 | ConnectedToAgent: 2 8 | }; 9 | 10 | function Provider () { 11 | 'use strict'; 12 | 13 | const data = []; 14 | 15 | // return all conversations 16 | const currentConversations = () => { 17 | return data; 18 | }; 19 | 20 | // creates a new conversation 21 | const createConversation = (address) => { 22 | const conversation = { 23 | timestamp: new Date().getTime(), 24 | user: address, 25 | state: ConversationState.ConnectedToBot 26 | }; 27 | 28 | data.push(conversation); 29 | 30 | return conversation; 31 | }; 32 | 33 | // find a conversation by its user conversation id 34 | const findByConversationId = (id) => { 35 | return data.find((conversation) => conversation.user.conversation.id === id); 36 | }; 37 | 38 | // find a conversation by its agent conversation id 39 | const findByAgentId = (id) => { 40 | return data.find((conversation) => conversation.agent && conversation.agent.conversation.id === id); 41 | }; 42 | 43 | // find a conversation by its agent conversation id 44 | const peekConversation = (agent) => { 45 | var conversation = data.sort((a,b) => a.timestamp < b.timestamp).find((conversation) => conversation.state === ConversationState.WaitingForAgent); 46 | if (conversation) { 47 | conversation.state = ConversationState.ConnectedToAgent; 48 | conversation.agent = agent; 49 | } 50 | return conversation; 51 | }; 52 | 53 | return { 54 | createConversation, 55 | currentConversations, 56 | findByAgentId, 57 | findByConversationId, 58 | peekConversation 59 | }; 60 | } 61 | 62 | module.exports = { Provider, ConversationState }; -------------------------------------------------------------------------------- /Node/exercise8-BackChannel/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backchannel", 3 | "version": "0.1.0", 4 | "license": "MIT", 5 | "description": "Add Backchannel feature", 6 | "scripts": { 7 | "nodewatch": "nodemon app.js", 8 | "start": "nodemon app.js", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "dependencies": { 12 | "botbuilder": "^3.8.4", 13 | "dotenv": "^4.0.0", 14 | "restify": "^4.3.0" 15 | }, 16 | "devDependencies": { 17 | "nodemon": "^1.11.0" 18 | } 19 | } -------------------------------------------------------------------------------- /Node/exercise8-BackChannel/textAnalyticsApiClient.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | const restify = require('restify'); 3 | 4 | module.exports = (config) => { 5 | return (query, callback) => { 6 | const client = restify.createJsonClient({ 7 | url: `https://westus.api.cognitive.microsoft.com`, 8 | headers: { 9 | 'Ocp-Apim-Subscription-Key': config.apiKey 10 | } 11 | }); 12 | 13 | const payload = { 14 | documents: [{ 15 | language: 'en', 16 | id: 'singleId', 17 | text: query 18 | }] 19 | }; 20 | 21 | const urlPath = '/text/analytics/v2.0/sentiment'; 22 | 23 | client.post(urlPath, payload, (err, request, response, result) => { 24 | if (!err && 25 | response && 26 | response.statusCode == 200 && 27 | result.documents[0]) { 28 | callback(null, result.documents[0].score); 29 | } else { 30 | callback(err, null); 31 | } 32 | }); 33 | }; 34 | }; 35 | 36 | -------------------------------------------------------------------------------- /Node/exercise8-BackChannel/ticketsApi.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | 3 | var tickets = []; 4 | var lastTicketId = 1; 5 | 6 | module.exports = (req, res) => { 7 | console.log('Ticket received: ', req.body); 8 | let ticketId = lastTicketId++; 9 | var ticket = req.body; 10 | ticket.id = ticketId; 11 | tickets.push(ticket); 12 | 13 | res.send(ticketId.toString()); 14 | }; 15 | -------------------------------------------------------------------------------- /Node/images/exercise1-echo-bot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise1-echo-bot.png -------------------------------------------------------------------------------- /Node/images/exercise2-console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise2-console.png -------------------------------------------------------------------------------- /Node/images/exercise2-dialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise2-dialog.png -------------------------------------------------------------------------------- /Node/images/exercise2-emulator-adaptivecards.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise2-emulator-adaptivecards.png -------------------------------------------------------------------------------- /Node/images/exercise2-full-conversation-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise2-full-conversation-1.png -------------------------------------------------------------------------------- /Node/images/exercise2-full-conversation-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise2-full-conversation-2.png -------------------------------------------------------------------------------- /Node/images/exercise2-start-new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise2-start-new.png -------------------------------------------------------------------------------- /Node/images/exercise3-addluisapp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise3-addluisapp.png -------------------------------------------------------------------------------- /Node/images/exercise3-dialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise3-dialog.png -------------------------------------------------------------------------------- /Node/images/exercise3-hello.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise3-hello.png -------------------------------------------------------------------------------- /Node/images/exercise3-hi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise3-hi.png -------------------------------------------------------------------------------- /Node/images/exercise3-luis-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise3-luis-dashboard.png -------------------------------------------------------------------------------- /Node/images/exercise3-luis-entity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise3-luis-entity.png -------------------------------------------------------------------------------- /Node/images/exercise3-luis-recognizedutterances.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise3-luis-recognizedutterances.png -------------------------------------------------------------------------------- /Node/images/exercise3-save-utterances.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise3-save-utterances.png -------------------------------------------------------------------------------- /Node/images/exercise3-severity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise3-severity.png -------------------------------------------------------------------------------- /Node/images/exercise3-suggested-utterances.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise3-suggested-utterances.png -------------------------------------------------------------------------------- /Node/images/exercise3-test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise3-test.png -------------------------------------------------------------------------------- /Node/images/exercise3-unknown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise3-unknown.png -------------------------------------------------------------------------------- /Node/images/exercise4-azuresearch-createdatasource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise4-azuresearch-createdatasource.png -------------------------------------------------------------------------------- /Node/images/exercise4-azuresearch-createindexer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise4-azuresearch-createindexer.png -------------------------------------------------------------------------------- /Node/images/exercise4-azuresearch-managekeys.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise4-azuresearch-managekeys.png -------------------------------------------------------------------------------- /Node/images/exercise4-createdocumentdb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise4-createdocumentdb.png -------------------------------------------------------------------------------- /Node/images/exercise4-createsearchservice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise4-createsearchservice.png -------------------------------------------------------------------------------- /Node/images/exercise4-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise4-diagram.png -------------------------------------------------------------------------------- /Node/images/exercise4-documentdb-addcollection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise4-documentdb-addcollection.png -------------------------------------------------------------------------------- /Node/images/exercise4-documentdb-uploadfiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise4-documentdb-uploadfiles.png -------------------------------------------------------------------------------- /Node/images/exercise4-emulator-detailsofarticle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise4-emulator-detailsofarticle.png -------------------------------------------------------------------------------- /Node/images/exercise4-emulator-explorecategory2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise4-emulator-explorecategory2.png -------------------------------------------------------------------------------- /Node/images/exercise4-emulator-explorekb2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise4-emulator-explorekb2.png -------------------------------------------------------------------------------- /Node/images/exercise4-emulator-search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise4-emulator-search.png -------------------------------------------------------------------------------- /Node/images/exercise4-emulator-showarticle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise4-emulator-showarticle.png -------------------------------------------------------------------------------- /Node/images/exercise4-emulator-showkbresults.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise4-emulator-showkbresults.png -------------------------------------------------------------------------------- /Node/images/exercise4-faq-index-facets-matrix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise4-faq-index-facets-matrix.png -------------------------------------------------------------------------------- /Node/images/exercise4-import-data-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise4-import-data-button.png -------------------------------------------------------------------------------- /Node/images/exercise4-new-intent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise4-new-intent.png -------------------------------------------------------------------------------- /Node/images/exercise4-new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise4-new.png -------------------------------------------------------------------------------- /Node/images/exercise4-testbit-explorehardware.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise4-testbit-explorehardware.png -------------------------------------------------------------------------------- /Node/images/exercise5-addappsettings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise5-addappsettings.png -------------------------------------------------------------------------------- /Node/images/exercise5-addbottoskype.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise5-addbottoskype.png -------------------------------------------------------------------------------- /Node/images/exercise5-botchannels.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise5-botchannels.png -------------------------------------------------------------------------------- /Node/images/exercise5-botconfiguration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise5-botconfiguration.png -------------------------------------------------------------------------------- /Node/images/exercise5-botname.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise5-botname.png -------------------------------------------------------------------------------- /Node/images/exercise5-createwebapp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise5-createwebapp.png -------------------------------------------------------------------------------- /Node/images/exercise5-deploymentcredentials.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise5-deploymentcredentials.png -------------------------------------------------------------------------------- /Node/images/exercise5-deploymentoption-localgit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise5-deploymentoption-localgit.png -------------------------------------------------------------------------------- /Node/images/exercise5-deploymentsuccessful.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise5-deploymentsuccessful.png -------------------------------------------------------------------------------- /Node/images/exercise5-entergitcredentials.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise5-entergitcredentials.png -------------------------------------------------------------------------------- /Node/images/exercise5-essentials-gitclone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise5-essentials-gitclone.png -------------------------------------------------------------------------------- /Node/images/exercise5-generateappid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise5-generateappid.png -------------------------------------------------------------------------------- /Node/images/exercise5-generatepassword.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise5-generatepassword.png -------------------------------------------------------------------------------- /Node/images/exercise5-savebutton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise5-savebutton.png -------------------------------------------------------------------------------- /Node/images/exercise5-testskype.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise5-testskype.png -------------------------------------------------------------------------------- /Node/images/exercise5-testwebchannel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise5-testwebchannel.png -------------------------------------------------------------------------------- /Node/images/exercise6-negativefeedback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise6-negativefeedback.png -------------------------------------------------------------------------------- /Node/images/exercise6-possitivefeedback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise6-possitivefeedback.png -------------------------------------------------------------------------------- /Node/images/exercise6-test-providefeedback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise6-test-providefeedback.png -------------------------------------------------------------------------------- /Node/images/exercise6-text-analytics-keys.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise6-text-analytics-keys.png -------------------------------------------------------------------------------- /Node/images/exercise7-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise7-diagram.png -------------------------------------------------------------------------------- /Node/images/exercise7-test-agent-connect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise7-test-agent-connect.png -------------------------------------------------------------------------------- /Node/images/exercise7-test-agent-login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise7-test-agent-login.png -------------------------------------------------------------------------------- /Node/images/exercise7-test-agent-resume.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise7-test-agent-resume.png -------------------------------------------------------------------------------- /Node/images/exercise7-test-agent-talk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise7-test-agent-talk.png -------------------------------------------------------------------------------- /Node/images/exercise7-test-user-connect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise7-test-user-connect.png -------------------------------------------------------------------------------- /Node/images/exercise7-test-user-resume.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise7-test-user-resume.png -------------------------------------------------------------------------------- /Node/images/exercise7-test-user-talk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise7-test-user-talk.png -------------------------------------------------------------------------------- /Node/images/exercise7-test-user-ticketfeedback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise7-test-user-ticketfeedback.png -------------------------------------------------------------------------------- /Node/images/exercise7-test-user-waitagent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise7-test-user-waitagent.png -------------------------------------------------------------------------------- /Node/images/exercise8-addnewsite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise8-addnewsite.png -------------------------------------------------------------------------------- /Node/images/exercise8-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise8-diagram.png -------------------------------------------------------------------------------- /Node/images/exercise8-edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise8-edit.png -------------------------------------------------------------------------------- /Node/images/exercise8-ngrok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise8-ngrok.png -------------------------------------------------------------------------------- /Node/images/exercise8-webchat-articles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise8-webchat-articles.png -------------------------------------------------------------------------------- /Node/images/exercise8-webchat-articlesdetail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise8-webchat-articlesdetail.png -------------------------------------------------------------------------------- /Node/images/exercise8-webchatsecrets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Node/images/exercise8-webchatsecrets.png -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # UPDATE - CODE MOVED!!! 2 | 3 | Please note, all code has been migrated to [MissionMarsFourthHorizon/operation-max](https://github.com/MissionMarsFourthHorizon/operation-max). No further updates will be made to this repository; all updates will be made on [MissionMarsFourthHorizon/operation-max](https://github.com/MissionMarsFourthHorizon/operation-max) 4 | -------------------------------------------------------------------------------- /Slides/1 - Bots in the real world.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Slides/1 - Bots in the real world.pptx -------------------------------------------------------------------------------- /Slides/2 - Mastering the user experience.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Slides/2 - Mastering the user experience.pptx -------------------------------------------------------------------------------- /Slides/3 - Natural Language Processing and LUIS.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Slides/3 - Natural Language Processing and LUIS.pptx -------------------------------------------------------------------------------- /Slides/4 - Knowledge base and Azure Search.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Slides/4 - Knowledge base and Azure Search.pptx -------------------------------------------------------------------------------- /Slides/5 - Deploying your bot.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Slides/5 - Deploying your bot.pptx -------------------------------------------------------------------------------- /Slides/6 - Cognitive Services.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Slides/6 - Cognitive Services.pptx -------------------------------------------------------------------------------- /Slides/7 - Handoff to Human.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Slides/7 - Handoff to Human.pptx -------------------------------------------------------------------------------- /Slides/8 - Backchannel.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Slides/8 - Backchannel.pptx -------------------------------------------------------------------------------- /Slides/MissionMars/1 - Bot Design.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Slides/MissionMars/1 - Bot Design.pptx -------------------------------------------------------------------------------- /Slides/MissionMars/2 - Mastering the interface.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Slides/MissionMars/2 - Mastering the interface.pptx -------------------------------------------------------------------------------- /Slides/MissionMars/3 - Natural language processing.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Slides/MissionMars/3 - Natural language processing.pptx -------------------------------------------------------------------------------- /Slides/MissionMars/4 - Knowledge base bots.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Slides/MissionMars/4 - Knowledge base bots.pptx -------------------------------------------------------------------------------- /Slides/MissionMars/5 - Deploying M.A.X.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Slides/MissionMars/5 - Deploying M.A.X.pptx -------------------------------------------------------------------------------- /Slides/MissionMars/6 - Cognitive Services.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Slides/MissionMars/6 - Cognitive Services.pptx -------------------------------------------------------------------------------- /Slides/MissionMars/7 - Middleware and human handoff.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Slides/MissionMars/7 - Middleware and human handoff.pptx -------------------------------------------------------------------------------- /Slides/MissionMars/8 - WebChat and Backchannel.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/Slides/MissionMars/8 - WebChat and Backchannel.pptx -------------------------------------------------------------------------------- /assets/botimages/head-sad-medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/assets/botimages/head-sad-medium.png -------------------------------------------------------------------------------- /assets/botimages/head-sad-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/assets/botimages/head-sad-small.png -------------------------------------------------------------------------------- /assets/botimages/head-smiling-medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/assets/botimages/head-smiling-medium.png -------------------------------------------------------------------------------- /assets/botimages/head-smiling-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/assets/botimages/head-smiling-small.png -------------------------------------------------------------------------------- /assets/categories.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "canonicalForm": "security", 4 | "list": ["password", "log in", "reset", "account", "user", "pin", "access", "authentication"] 5 | }, 6 | { 7 | "canonicalForm": "networking", 8 | "list": ["network", "connectivity", "internet", "ethernet", "wifi", "vpn", "RAS", "connect", "remote"] 9 | }, 10 | { 11 | "canonicalForm": "software", 12 | "list": ["outlook", "skype", "windows", "explorer", "office", "account", "office", "sound", "web page", "antivirus", "malware", "files", "app", "backup", "video"] 13 | }, 14 | { 15 | "canonicalForm": "hardware", 16 | "list": ["keyboard", "mouse", "monitor", "printer", "notebook", "computer", "desktop", "phone", "replacement", "device"] 17 | } 18 | ] -------------------------------------------------------------------------------- /assets/exercise2-TicketSubmissionDialog/TicketAPIClient.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Util 2 | { 3 | using System; 4 | using System.Net.Http; 5 | using System.Net.Http.Headers; 6 | using System.Threading.Tasks; 7 | using System.Web.Configuration; 8 | 9 | public class Ticket 10 | { 11 | public string Category { get; set; } 12 | 13 | public string Severity { get; set; } 14 | 15 | public string Description { get; set; } 16 | } 17 | 18 | public class TicketAPIClient 19 | { 20 | public async Task PostTicketAsync(string category, string severity, string description) 21 | { 22 | try 23 | { 24 | using (var client = new HttpClient()) 25 | { 26 | client.BaseAddress = new Uri(WebConfigurationManager.AppSettings["TicketsAPIBaseUrl"]); 27 | client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 28 | 29 | var ticket = new Ticket 30 | { 31 | Category = category, 32 | Severity = severity, 33 | Description = description 34 | }; 35 | 36 | var response = await client.PostAsJsonAsync("api/tickets", ticket); 37 | return await response.Content.ReadAsAsync(); 38 | } 39 | } 40 | catch 41 | { 42 | return -1; 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /assets/exercise2-TicketSubmissionDialog/TicketsController.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Web.Http; 6 | using Util; 7 | 8 | public class TicketsController : ApiController 9 | { 10 | private static int nextTicketId = 1; 11 | private static Dictionary tickets = new Dictionary(); 12 | 13 | [HttpPost] 14 | public IHttpActionResult Post(Ticket ticket) 15 | { 16 | int ticketId; 17 | 18 | Console.WriteLine("Ticket accepted: category:" + ticket.Category + " severity:" + ticket.Severity + " description:" + ticket.Description); 19 | 20 | lock (tickets) 21 | { 22 | ticketId = nextTicketId++; 23 | TicketsController.tickets.Add(ticketId, ticket); 24 | } 25 | 26 | return this.Ok(ticketId.ToString()); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /assets/exercise4-KnowledgeBase/Category.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | public class Category 4 | { 5 | public int Count { get; set; } 6 | 7 | public string Value { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /assets/exercise4-KnowledgeBase/FacetResult.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | using Newtonsoft.Json; 4 | 5 | public class FacetResult 6 | { 7 | [JsonProperty("@odata.context")] 8 | public string ODataContext { get; set; } 9 | 10 | [JsonProperty("@search.facets")] 11 | public SearchFacets Facets { get; set; } 12 | 13 | public SearchResultHit[] Value { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /assets/exercise4-KnowledgeBase/FurtherChallenge/ImageSearchService.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Services 2 | { 3 | using Newtonsoft.Json; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Net.Http; 7 | using System.Threading.Tasks; 8 | 9 | [Serializable] 10 | public class ImageSearchService 11 | { 12 | private static Random random = new Random(); 13 | 14 | public async Task GetImage(string text) 15 | { 16 | using (var httpClient = new HttpClient()) 17 | { 18 | httpClient.BaseAddress = new Uri("https://api.cognitive.microsoft.com/bing/v5.0/images/search"); 19 | httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", WebConfigurationManager.AppSettings["ImageSearchApiKey"]); 20 | 21 | string uri = $"?q={text}&count=10&safeSearch=Strict&imageType=Clipart"; 22 | 23 | var response = await httpClient.PostAsync(uri, null); 24 | var responseString = await response.Content.ReadAsStringAsync(); 25 | var result = JsonConvert.DeserializeObject(responseString); 26 | 27 | var index = random.Next(9); 28 | 29 | if (result?.Value.Count == 10) 30 | { 31 | return result.Value[index].ThumbnailUrl; 32 | } 33 | return null; 34 | } 35 | } 36 | 37 | internal class ImageResult 38 | { 39 | public IList Value { get; set; } 40 | } 41 | 42 | internal class ImageResultItem 43 | { 44 | public string ThumbnailUrl { get; set; } 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /assets/exercise4-KnowledgeBase/FurtherChallenge/imageSearchApiClient.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | const restify = require('restify'); 3 | 4 | module.exports = (config) => { 5 | return (query, callback) => { 6 | const client = restify.createJsonClient({ 7 | url: 'https://api.cognitive.microsoft.com', 8 | headers: { 9 | 'Ocp-Apim-Subscription-Key': config.apiKey 10 | } 11 | }); 12 | 13 | const urlPath = `/bing/v5.0/images/search?q=${query}&count=10&safeSearch=Strict&imageType=ClipArt`; 14 | 15 | var index = Math.floor(Math.random() * 9); 16 | 17 | client.post(urlPath, null, (err, request, response, result) => { 18 | if (!err && 19 | response && 20 | response.statusCode == 200 && 21 | result.value[0]) { 22 | callback(null, result.value[index].thumbnailUrl); 23 | } else { 24 | callback(err, null); 25 | } 26 | }); 27 | }; 28 | }; 29 | 30 | -------------------------------------------------------------------------------- /assets/exercise4-KnowledgeBase/SearchFacets.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | using Newtonsoft.Json; 4 | 5 | public class SearchFacets 6 | { 7 | [JsonProperty("category@odata.type")] 8 | public string CategoryOdataType { get; set; } 9 | 10 | public Category[] Category { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /assets/exercise4-KnowledgeBase/SearchResult.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | using Newtonsoft.Json; 4 | 5 | public class SearchResult 6 | { 7 | [JsonProperty("@odata.context")] 8 | public string ODataContext { get; set; } 9 | 10 | public SearchResultHit[] Value { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /assets/exercise4-KnowledgeBase/SearchResultHit.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.Model 2 | { 3 | using Newtonsoft.Json; 4 | 5 | public class SearchResultHit 6 | { 7 | [JsonProperty("@search.score")] 8 | public float SearchScore { get; set; } 9 | 10 | public string Title { get; set; } 11 | 12 | public string Category { get; set; } 13 | 14 | public string Text { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /assets/exercise7-HandOffToHuman/AgentExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace HelpDeskBot.HandOff 2 | { 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using Microsoft.Bot.Builder.Dialogs.Internals; 6 | 7 | public static class AgentExtensions 8 | { 9 | private const string ISAGENT = "isAgent"; 10 | 11 | public static bool IsAgent(this IBotData botData) 12 | { 13 | bool isAgent = false; 14 | botData.ConversationData.TryGetValue(ISAGENT, out isAgent); 15 | return isAgent; 16 | } 17 | 18 | public static Task SetAgent(this IBotData botData, bool value, CancellationToken token) 19 | { 20 | botData.ConversationData.SetValue(ISAGENT, value); 21 | return botData.FlushAsync(token); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /assets/exercise7-HandOffToHuman/provider.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | 3 | // Conversation state enumeration 4 | const ConversationState = { 5 | ConnectedToBot: 0, 6 | WaitingForAgent: 1, 7 | ConnectedToAgent: 2 8 | }; 9 | 10 | function Provider () { 11 | 'use strict'; 12 | 13 | const data = []; 14 | 15 | // return all conversations 16 | const currentConversations = () => { 17 | return data; 18 | }; 19 | 20 | // creates a new conversation 21 | const createConversation = (address) => { 22 | const conversation = { 23 | timestamp: new Date().getTime(), 24 | user: address, 25 | state: ConversationState.ConnectedToBot 26 | }; 27 | 28 | data.push(conversation); 29 | 30 | return conversation; 31 | }; 32 | 33 | // find a conversation by its user conversation id 34 | const findByConversationId = (id) => { 35 | return data.find((conversation) => conversation.user.conversation.id === id); 36 | }; 37 | 38 | // find a conversation by its agent conversation id 39 | const findByAgentId = (id) => { 40 | return data.find((conversation) => conversation.agent && conversation.agent.conversation.id === id); 41 | }; 42 | 43 | // find a conversation by its agent conversation id 44 | const peekConversation = (agent) => { 45 | var conversation = data.sort((a,b) => a.timestamp < b.timestamp).find((conversation) => conversation.state === ConversationState.WaitingForAgent); 46 | if (conversation) { 47 | conversation.state = ConversationState.ConnectedToAgent; 48 | conversation.agent = agent; 49 | } 50 | return conversation; 51 | }; 52 | 53 | return { 54 | createConversation, 55 | currentConversations, 56 | findByAgentId, 57 | findByConversationId, 58 | peekConversation 59 | }; 60 | } 61 | 62 | module.exports = { Provider, ConversationState }; -------------------------------------------------------------------------------- /assets/exercise8-BackChannel/default.htm: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 42 | 43 | 44 | 45 |
46 |
47 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /assets/kb/1.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Tips to improve PC performance in Windows 10", 3 | "category": "software", 4 | "text": "Does a slow PC have you down? If so, try some of the following suggestions to help make your Windows 10 PC run better. The tips are listed in order, so start with the first one, see if that fixes the problem, and then continue to the next one if it doesn't.\n\n- Make sure you have the latest updates for Windows and device drivers\n- Restart your PC and open only the apps you need\n- Check memory and memory usage\n- Restore your PC from a system restore point\n- Disable unnecessary startup programs\n- Check for and remove viruses and malware\n- Check for corrupted Windows system files\n- Adjust the appearance and performance of Windows\n- Adjust or turn off OneDrive sync\n- Reset your PC" 5 | } -------------------------------------------------------------------------------- /assets/kb/10.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "How to use Remote Desktop", 3 | "category": "networking", 4 | "text": "Use Remote Desktop on your Windows 10 PC or on your Windows, Android, or iOS device to connect to a PC from afar.\n\n1. First, you'll need to set up the remote PC to allow remote connections. On the remote PC, open **Settings** and select **System** > **About**. Note the PC name. You'll need this later. Then, under **Related settings** , select **System info**.\n2. In the left pane of the **System** window, select **Advanced system settings**.\n3. On the **Remote** tab of the **System Properties** dialog box, under **Remote Desktop** , select **Allow remote connections to this computer** , and then select **OK**.\n4. Next, in **Settings** , select **System** > **Power & sleep** and check to make sure **Sleep** is set to **Never**.\n5. Do one of the following:\n - **On your local Windows 10 PC:** In the search box on the taskbar, type **Remote Desktop Connection** , and then select **Remote Desktop Connection**. In Remote Desktop Connection, type the full name of the remote PC, and select **Connect**.\n - **On your Windows, Android, or iOS device:** Open the Remote Desktop app (available for free from the Windows Store, Google Play, or the Mac App Store), and add your remote PC. Select the remote PC, and then wait for the connection to complete." 5 | } -------------------------------------------------------------------------------- /assets/kb/11.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Turn off OneDrive in Windows 10", 3 | "category": "software", 4 | "text": "If you don't want to use OneDrive, you can disable it, hide it on your computer, or, in some versions of Windows, uninstall it.\n\n1. Select the Start button, type Programs in the search box, and then select Add or remove programs in the list of results.\n\n1. Under Apps & features, find and select Microsoft OneDrive, and then select Uninstall. If you're prompted for an administrator password or confirmation, type the password or provide confirmation." 5 | } -------------------------------------------------------------------------------- /assets/kb/12.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Project to a screen", 3 | "category": "hardware", 4 | "text": "Press the Windows key + P, and then choose a way to project:\n\n- PC screen only\n- Duplicate\n- Extend\n- Second screen only" 5 | } -------------------------------------------------------------------------------- /assets/kb/13.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Protect your PC from Malware", 3 | "category": "security", 4 | "text": "Windows 10 is safer than ever, and security is easier thanks to Windows Defender Security Center.\n\nWhen you start Windows 10 for the first time, Windows Defender Security Center, which contains Windows Defender Antivirus and Windows Firewall, is there to help protect your device.\n\nWindows Defender uses real-time protection to scan everything you download or run on your PC.\n\nWindows Defender Antivirus works help protect your device by scanning for malicious or unwanted software and uses real-time protection to scan everything you download or run on your device.\n\nGet more info about the Windows Defender Antivirus experience in [Help protect my device with Windows Defender Antivirus (Windows 10 Creators Update)](https://go.microsoft.com/fwlink/?linkid=840934)." 5 | } -------------------------------------------------------------------------------- /assets/kb/14.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Use your PC like a tablet", 3 | "category": "hardware", 4 | "text": "Tablet mode makes Windows easier and more intuitive to use with touch on devices like 2-in-1s, or when you don't want to use a keyboard and mouse. To turn on tablet mode, select **action center** on the taskbar and then select **Tablet mode**.\n\nStart and apps (including older programs) open full screen, giving you more space to work in. To use two apps side by side, drag an app to one side. You'll see where it'll snap, along with any open apps that can snap right next to it.\n\nIn tablet mode, there are a few more things you can do:\n\n- Use the shared edge between two snapped apps to resize both at the same time.\n- Select **Task view** on the taskbar and then drag an app to a side to snap it directly from task view.\n- Use the back button on the taskbar to go back in an app or to the previous app you were using.\n- Drag an app to the bottom of the screen to close it.\n\nFor more about using touch, see [Use touch with Windows](https://support.microsoft.com/en-us/help/17209)." 5 | } -------------------------------------------------------------------------------- /assets/kb/15.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "My Lumia phone does not work or respond as expected", 3 | "category": "hardware", 4 | "text": "Try these fixes if, for example, your phone randomly reboots, freezes or does not switch on, if an app crashes, if you have sound problems, or if the screen is blank:\n\n**1. Charge your phone**\n\nCharge your phone for at least 20 minutes.\n\n**2. Restart your phone**\n\nPress and hold the **Power** and **Volume down ** keys simultaneously for 10-15 seconds. Release and the phone will restart. After this operation, you may need to set the date and time on the phone.\n\nIf the problem persists, reset and restore your phone as instructed below.\n\n**3. Reset your phone**\n\nBefore you continue with the reset, make sure your phone's battery level is above 50%.\nTo check the remaining battery life, go to **Settings** > **System** > **Battery saver**** **(Lumia with Windows Phone 8: **Settings ** > ** battery saver**). If you are not able to check it, or the level is too low, charge your phone for at least 20 minutes.\n\nReset your phone by using the phone settings.\nSelect **Settings** > **System** > **About** > **Reset your phone ** (Lumia with Windows Phone 8: **Settings** > **About** > **Reset your phone** )." 5 | } -------------------------------------------------------------------------------- /assets/kb/16.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "My memory card is not working properly in Lumia phone", 3 | "category": "hardware", 4 | "text": "Make sure of the following:\n\n- You have a fast **4–200GB microSD ** (Lumia with Windows Phone 8: **4-128GB microSD** ) memory card by a well-known manufacturer.\n- Your memory card is not full (there should be at least about 50 MB of free memory on the card).\n- Your memory card is not password protected. To check if your memory card is password protected, connect it to a PC with a USB reader that has a microSD card slot. If the card cannot be accessed, it is password protected. Remove the password from your memory card using the device where it was previously used.\n\nIf your memory card has thousands of media items, the file system scan may consume considerable amounts of your phone processing power even when running in the background. If you think that is the issue, go to **Settings** > **System** > **Storage** , tap on the **SD card (D:)**** **and at the bottom of the screen tap ** Remove** (Lumia with Windows Phone 8: **App ** list, select ** Storage Sense **, tap the ** SD card **** ** bar and tap **remove SD card** ). You can access your memory card next time you restart your phone.\n\nIf you see the Scan SD card and fix errors message box, tap **Yes** to have your phone scan the card and try to fix any errors. If you see an SD card scan failed message, insert the memory card into a PC and try and fix it there with these steps." 5 | } -------------------------------------------------------------------------------- /assets/kb/17.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Use your voice with HoloLens", 3 | "category": "hardware", 4 | "text": "Use your voice to do many of the same things you do with gestures on HoloLens—even take a quick photo or open an app. And when you're using the holographic keyboard, try dictation mode for an easy way to type.\n\nGet around HoloLens faster with these basic commands. To see more commands, check out [Cortana on HoloLens](https://support.microsoft.com/en-us/help/12630), or just say "Hey Cortana, what can I say?"\n\n**Select**. Use this instead of air tap. Gaze at a hologram, then say "Select."\n\n**Place**. Instead of air tapping to place a hologram, say "Place."\n\n**Face me**. Gaze at a hologram, then say "Face me" to turn it your way.\n\n**Bigger/Smaller**. Gaze at a hologram, then say "Bigger" or "Smaller" to resize it.\n\n**Hey Cortana, go to Start**. Use this instead of [bloom](https://support.microsoft.com/en-us/help/12644) to get to Start.\n\n**Hey Cortana, shut down**. Turn off your HoloLens.\n\n**Hey Cortana, move <app name> here**. Gaze at the spot you want the app to move to.\n\n**Hey Cortana, take a picture**. Snap a quick photo.\n\nMany buttons and other elements on HoloLens also respond to your voice—for example, **Adjust** and **Remove** on the app bar. To find out if a button is voice enabled, rest your gaze on it for a moment. If it is, you'll see a voice tip." 5 | } -------------------------------------------------------------------------------- /assets/kb/2.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Get free apps and games in Windows Store", 3 | "category": "software", 4 | "text": "The Store in Windows 10 has thousands of free apps and games, all kinds, for you to download and play.\n\n1. Select Store on your taskbar, or select Start , and on the apps list select Store.\n2. In the Store, select Apps or Games.\n3. On the apps or games page, find Top Free Apps or Top Free Games and select Show all at the other end of the row.\n\nHaving problems with a free game? Run the app troubleshooter.\n\nIf Windows Store won't open, get more info to fix it." 5 | } -------------------------------------------------------------------------------- /assets/kb/3.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Connect to Bluetooth devices", 3 | "category": "networking", 4 | "text": "Thanks to Bluetooth, you can use all sorts of wireless devices with your Windows PC—Bluetooth headphones, speakers, phones, fitness trackers—just to name a few. Start by pairing your Bluetooth device with your PC. The way you do this depends on the kind of Bluetooth device you're using.\n\nTo connect a Bluetooth headset, speaker, or other audio device\n\n1. Turn on your Bluetooth audio device and make it discoverable. The way you make it discoverable depends on the device. Check the device or visit the manufacturer's website to learn how.\n2. Turn on Bluetooth on your PC if it's not on already. To do this, on the taskbar, select action center > Bluetooth.\n3. In action center, select Connect > the device name.\n4. Follow any more instructions that might appear. Otherwise, you're done and connected.\n5. Your Bluetooth device and PC will usually automatically connect anytime the two devices are in range of each other with Bluetooth turned on." 5 | } -------------------------------------------------------------------------------- /assets/kb/4.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Turn on device encryption", 3 | "category": "security", 4 | "text": "Device encryption helps protect your data by encrypting it. Only someone with the right encryption key (like a password) can decrypt it.\n\n1. Sign in to Windows with an administrator account.\n2. Go to Start, enter encryption, and select Change device encryption settings from the list of results.\n3. Select Manage BitLocker, select Turn on BitLocker, and then follow the instructions.\n\nIf you need to decrypt your PC, find your recovery key." 5 | } -------------------------------------------------------------------------------- /assets/kb/5.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Back up and restore your files in Windows 10", 3 | "category": "security", 4 | "text": "It's always good to have a backup. Keep copies of your files on another drive in case something happens to the originals.\n\n1. Select the Start button, select Settings > Update & security > Backup > Add a drive, and then choose an external drive or network location for your backups.\n2. All set. Every hour, we'll back up everything in your user folder (C:\\Users\\username). To change which files get backed up or how often backups happen, go to More options.\n\nIf you're missing an important file or folder, here's how to get it back:\n\n1. Type Restore files in the search box on the taskbar, and then select Restore your files with File History.\n2. Look for the file you need, then use the arrows to see all its versions.\n3. When you find the version you want, select Restore to save it in its original location. To save it in a different place, press and hold (or right-click) Restore, select Restore to, and then choose a new location." 5 | } -------------------------------------------------------------------------------- /assets/kb/7.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Set up your email and calendar", 3 | "category": "software", 4 | "text": "Windows 10 has Mail and Calendar apps already built in. Find them by selecting the Start button, or type mail or calendar in the search box on the taskbar.\n\nYou've found the apps, now make them useful by adding your accounts. If this is the first time you're opening either Mail or Calendar, follow the instructions on the Welcome page. Otherwise, do the following:\n\n1. In the Mail or Calendar app, select **Settings** at the lower left.\n2. Select **Manage Accounts** > **Add account** , choose an account, and then follow the instructions.\n\nYour mail and calendar start syncing as soon as your account is set up. To add more accounts, return to Settings.\n\nA few more handy things:\n\n- No need to add the same account twice—when you add it to one app, the other app automatically connects to the same account.\n- Switch between Mail and Calendar by selecting **Switch to Mail** or **Switch to Calendar** on the lower-left side of the window. To see the contacts associated with your accounts, select **Switch to People** to open the People app." 5 | } -------------------------------------------------------------------------------- /assets/kb/8.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Fix sound problems", 3 | "category": "software", 4 | "text": "1. For help fixing audio or sound problems, [try the audio troubleshooter](http://aka.ms/diag_cssemerg69319). It might be able to fix audio problems automatically.\n2. If the link doesn't open the troubleshooter, select the **Start** button, type **Troubleshooting** , and then select **Troubleshooting ** from the list of results. Under **Hardware and Sound** , select **Troubleshoot audio playback**." 5 | } -------------------------------------------------------------------------------- /assets/kb/9.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Zip and unzip files", 3 | "category": "software", 4 | "text": "To zip a file, open File Explorer from the taskbar. Right-click (or press and hold) the file you want to zip, and then select **Send to** > **Compressed (zipped) folder.**" 5 | } -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekTrainer/help-desk-bot-lab/cc7d514d8b6a3affda37986488035c911a7ec0a4/assets/logo.png -------------------------------------------------------------------------------- /assets/severities.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "canonicalForm": "high", 4 | "list": ["crashing", "blocked", "important", "urgent", "lost", "privacy", "ASAP", "risk"] 5 | }, 6 | { 7 | "canonicalForm": "normal", 8 | "list": [] 9 | }, 10 | { 11 | "canonicalForm": "low", 12 | "list": ["small", "minor", "unimportant", "suggestion", "idea"] 13 | } 14 | ] -------------------------------------------------------------------------------- /exercise1-EchoBot.md: -------------------------------------------------------------------------------- 1 | # Exercise 1: Creating Your First "Echo" Bot with the Bot Builder SDK 2 | 3 | The goal of the first exercise is to create your first bot using [Microsoft Bot Framework](https://dev.botframework.com). 4 | 5 | ## Exercise Goals 6 | 7 | To successfully complete this exercise, you must complete the following tasks: 8 | 9 | * Configure your development environment 10 | * Create a bot that accepts input from a user, "echoes" or sends the same text back to the user 11 | 12 | ## C# 13 | 14 | ### Prerequisites 15 | 16 | [Visual Studio 2017 Community](https://www.visualstudio.com/vs/) or higher is required to create bots. [Bot Framework Emulator](https://emulator.botframework.com/), which is the client you will use for testing your bot, is also required. 17 | 18 | ## Node.js 19 | 20 | ### Prerequisites 21 | 22 | You will need both a code editor installed, such as [Visual Studio Code](https://code.visualstudio.com), and the [Node.js](https://nodejs.org/en/) runtime. [Bot Framework Emulator](https://emulator.botframework.com/), which is the client you will use for testing your bot, is also required. 23 | 24 | ## Resources 25 | 26 | * You may find helpful resources in the [Bot Framework documentation](https://docs.microsoft.com/en-us/bot-framework/). 27 | 28 | * For Node.js, you may also want to use an additional package for managing environmental variables, such as [dotenv](https://github.com/motdotla/dotenv). --------------------------------------------------------------------------------