Feb2019Update_ContosoHelpdeskChatBot_PBI4 End Update to v4 (master) (#40)

* PBI4 End Updates

PBI4 End Updates

* pbi4end fabrikam updates

* pbi4end fabrikam updates

* v4 update

v4 update

* updates and cleaning

* Update MainDialog.cs

cleanup
This commit is contained in:
wandrille-hubert 2019-02-12 12:54:36 -06:00 коммит произвёл Leo Leong
Родитель 6f3ccbf735
Коммит 7889b68025
24 изменённых файлов: 810 добавлений и 555 удалений

2
.gitignore поставляемый
Просмотреть файл

@ -286,3 +286,5 @@ __pycache__/
*.btm.cs
*.odx.cs
*.xsd.cs
/ContosoHelpdeskChatBot/ContosoHelpdeskChatBot/contosohelpdeskchatbot_AZURE.bot
/ContosoHelpdeskChatBot/ContosoHelpdeskChatBot/contosohelpdeskchatbot_NOINFO.bot

Просмотреть файл

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Hosting;
using System.Web.Http;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Integration.AspNet.WebApi;
using Microsoft.Bot.Configuration;
using Unity;
using Unity.Lifetime;
namespace ContosoHelpdeskChatBot.App_Start
{
public class BotConfig
{
public static void Register(HttpConfiguration config)
{
config.MapBotFramework(botConfig =>
{
// Load Connected Services from .bot file
var path = HostingEnvironment.MapPath(@"~/contosohelpdeskchatbot.bot");
var botConfigurationFile = BotConfiguration.Load(path);
var endpointService = (EndpointService)botConfigurationFile.Services.First(s => s.Type == "endpoint");
botConfig
.UseMicrosoftApplicationIdentity(endpointService?.AppId, endpointService?.AppPassword);
// The Memory Storage used here is for local bot debugging only. When the bot
// is restarted, everything stored in memory will be gone.
IStorage dataStore = new MemoryStorage();
// Create Conversation State object.
// The Conversation State object is where we persist anything at the conversation-scope.
var conversationState = new ConversationState(dataStore);
// Create the custom state accessor.
// State accessors enable other components to read and write individual properties of state.
var accessors = new ConsotoChatBotAccessors(conversationState)
{
//ContosoBotState = conversationState.CreateProperty<BotState>(ConsotoChatBotAccessors.CounterStateName),
};
UnityConfig.Container.RegisterInstance<ConsotoChatBotAccessors>(accessors, new ContainerControlledLifetimeManager());
});
}
}
}

Просмотреть файл

@ -0,0 +1,48 @@
using Microsoft.Bot.Builder;
using System;
using Unity;
namespace ContosoHelpdeskChatBot
{
/// <summary>
/// Specifies the Unity configuration for the main container.
/// </summary>
public static class UnityConfig
{
#region Unity Container
private static Lazy<IUnityContainer> container =
new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});
/// <summary>
/// Configured Unity Container.
/// </summary>
public static IUnityContainer Container => container.Value;
#endregion
/// <summary>
/// Registers the type mappings with the Unity container.
/// </summary>
/// <param name="container">The unity container to configure.</param>
/// <remarks>
/// There is no need to register concrete types such as controllers or
/// API controllers (unless you want to change the defaults), as Unity
/// allows resolving a concrete type even if it was not previously
/// registered.
/// </remarks>
public static void RegisterTypes(IUnityContainer container)
{
// NOTE: To load from web.config uncomment the line below.
// Make sure to add a Unity.Configuration to the using statements.
// container.LoadConfiguration();
// TODO: Register your type's mappings here.
container.RegisterType<IBot, ContosoChatBot>();
}
}
}

Просмотреть файл

@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.Web.Http.Dependencies;
using Unity;
using Unity.Exceptions;
namespace ContosoHelpdeskChatBot.App_Start
{
/// <summary>
/// Resolves dependencies for dependency injection.
/// </summary>
/// <seealso cref="https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/dependency-injection"/>
public class UnityResolver : IDependencyResolver
{
private readonly IUnityContainer _container;
/// <summary>
/// Initializes a new instance of the <see cref="UnityResolver"/> class.
/// </summary>
/// <param name="container">The container that resolution will be performed upon.</param>
public UnityResolver(IUnityContainer container)
{
_container = container;
}
/// <summary>
/// Resolves singly registered services that support arbitrary object creation.
/// </summary>
/// <param name="serviceType">Type of the service to resolve.</param>
/// <returns>The requested service.</returns>
public object GetService(Type serviceType)
{
try
{
return _container.Resolve(serviceType);
}
catch (ResolutionFailedException)
{
return null;
}
}
/// <summary>
/// Creates a collection of objects of a specified type.
/// </summary>
/// <param name="serviceType">Type of the service to resolve.</param>
/// <returns>Collection of the requested services.</returns>
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return _container.ResolveAll(serviceType);
}
catch (ResolutionFailedException)
{
return new List<object>();
}
}
/// <summary>
/// Starts a resolution scope.
/// </summary>
/// <remarks>Objects which are resolved in the given scope will belong to that scope,
/// and when the scope is disposed, those objects are returned to the container.
/// </remarks>
/// <returns>The dependency scope.</returns>
public IDependencyScope BeginScope()
{
var child = _container.CreateChildContainer();
return new UnityResolver(child);
}
/// <summary>
/// Performs container-associated tasks with releasing resources.
/// </summary>
public void Dispose()
{
_container.Dispose();
}
}
}

Просмотреть файл

@ -0,0 +1,36 @@
using System.Web.Http;
using Unity.AspNet.WebApi;
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(ContosoHelpdeskChatBot.UnityWebApiActivator), nameof(ContosoHelpdeskChatBot.UnityWebApiActivator.Start))]
[assembly: WebActivatorEx.ApplicationShutdownMethod(typeof(ContosoHelpdeskChatBot.UnityWebApiActivator), nameof(ContosoHelpdeskChatBot.UnityWebApiActivator.Shutdown))]
namespace ContosoHelpdeskChatBot
{
/// <summary>
/// Provides the bootstrapping for integrating Unity with WebApi when it is hosted in ASP.NET.
/// </summary>
public static class UnityWebApiActivator
{
/// <summary>
/// Integrates Unity when the application starts.
/// </summary>
public static void Start()
{
// Use UnityHierarchicalDependencyResolver if you want to use
// a new child container for each IHttpController resolution.
// var resolver = new UnityHierarchicalDependencyResolver(UnityConfig.Container);
var resolver = new UnityDependencyResolver(UnityConfig.Container);
GlobalConfiguration.Configuration.DependencyResolver = resolver;
}
/// <summary>
/// Disposes the Unity container when the application is shut down.
/// </summary>
public static void Shutdown()
{
UnityConfig.Container.Dispose();
}
}
}

Просмотреть файл

@ -1,37 +0,0 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace ContosoHelpdeskChatBot
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Json settings
config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
config.Formatters.JsonFormatter.SerializerSettings.Formatting = Formatting.Indented;
JsonConvert.DefaultSettings = () => new JsonSerializerSettings()
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
Formatting = Newtonsoft.Json.Formatting.Indented,
NullValueHandling = NullValueHandling.Ignore,
};
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}

Просмотреть файл

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace ContosoHelpdeskChatBot
{
public class BotState
{
public string AppName { get; set; }
public string MachineName { get; set; }
public int AdminDuration { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Dialogs;
namespace ContosoHelpdeskChatBot
{
public class ConsotoChatBotAccessors
{
public ConsotoChatBotAccessors(ConversationState conversationState)
{
ConversationState = conversationState ?? throw new ArgumentNullException(nameof(conversationState));
}
//public static string CountosoBotStateName { get; } = $"{nameof(ConsotoChatBotAccessors)}.ContosoBotState";
//public IStatePropertyAccessor<BotState> ContosoBotState { get; set; }
public ConversationState ConversationState { get; }
}
}

Просмотреть файл

@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Schema;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using ContosoHelpdeskChatBot.Dialogs;
namespace ContosoHelpdeskChatBot
{
/// <summary>
/// Main entry point and orchestration for bot.
/// </summary>
public class ContosoChatBot : IBot
{
private static log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private DialogSet dialogs { get; set; }
private readonly ConsotoChatBotAccessors _accessors;
public ContosoChatBot(ConsotoChatBotAccessors accessors)
{
_accessors = accessors ?? throw new System.ArgumentNullException(nameof(accessors));
// Create top - level dialog(s)
dialogs = new DialogSet(_accessors.ConversationState.CreateProperty<DialogState>(nameof(ContosoChatBot)));
dialogs.Add(new MainDialog("MainDialog"));
dialogs.Add(new ChoicePrompt("promptChoice"));
dialogs.Add(new TextPrompt("promptText"));
dialogs.Add(new NumberPrompt<int>("promptNumber"));
dialogs.Add(new InstallAppDialog("InstallAppDialog"));
dialogs.Add(new LocalAdminDialog("LocalAdminDialog"));
dialogs.Add(new ResetPasswordDialog("ResetPasswordDialog"));
}
public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
{
if (turnContext.Activity.Type == ActivityTypes.Message)
{
var dialogContext = await dialogs.CreateContextAsync(turnContext, cancellationToken);
try
{
bool cancelled = false;
// Globally interrupt the dialog stack if the user sent 'cancel'
if (turnContext.Activity.Text.Equals("cancel", StringComparison.InvariantCultureIgnoreCase))
{
var reply = turnContext.Activity.CreateReply($"Ok restarting conversation.");
await turnContext.SendActivityAsync(reply);
await dialogContext.CancelAllDialogsAsync();
cancelled = true;
}
if (!dialogContext.Context.Responded || cancelled)
{
DialogTurnResult dialogResult = await dialogContext.ContinueDialogAsync(cancellationToken);
if (dialogResult.Status == DialogTurnStatus.Empty)
{
await dialogContext.BeginDialogAsync(MainDialog.dialogId, cancellationToken);
}
else if (dialogResult.Status == DialogTurnStatus.Complete)
{
await dialogContext.EndDialogAsync();
// Uncomment if want to automatically restart a dialog when the last dialog completes
//await dialogContext.BeginDialogAsync(MainDialog.dialogId, cancellationToken);
}
else if (dialogResult.Status == DialogTurnStatus.Waiting)
{
// Currently waiting on a response for a user
}
else
{
await dialogContext.CancelAllDialogsAsync();
}
}
}
catch (Exception ex) // For production would want to catch more specific exception
{
logger.Error(ex);
await turnContext.SendActivityAsync("An error occured, cancelling.");
await dialogContext.CancelAllDialogsAsync();
await dialogContext.BeginDialogAsync(MainDialog.dialogId, cancellationToken);
}
await _accessors.ConversationState.SaveChangesAsync(turnContext, false, cancellationToken);
}
}
}
}

Просмотреть файл

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\SourceLink.Create.CommandLine.2.8.1\build\SourceLink.Create.CommandLine.props" Condition="Exists('..\packages\SourceLink.Create.CommandLine.2.8.1\build\SourceLink.Create.CommandLine.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -53,6 +54,9 @@
<Reference Include="Chronic, Version=0.3.2.0, Culture=neutral, PublicKeyToken=3bd1f1ef638b0d3c, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\Chronic.Signed.0.3.2\lib\net40\Chronic.dll</HintPath>
</Reference>
<Reference Include="CommonServiceLocator, Version=2.0.4.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\packages\Unity.5.8.13\lib\net47\CommonServiceLocator.dll</HintPath>
</Reference>
<Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll</HintPath>
</Reference>
@ -68,20 +72,29 @@
<Reference Include="Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Azure.KeyVault.Core.1.0.0\lib\net40\Microsoft.Azure.KeyVault.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bot.Builder, Version=3.16.0.38344, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bot.Builder.3.16.0.38344\lib\net46\Microsoft.Bot.Builder.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bot.Builder.Autofac, Version=3.16.0.38344, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bot.Builder.3.16.0.38344\lib\net46\Microsoft.Bot.Builder.Autofac.dll</HintPath>
<Reference Include="Microsoft.Bot.Builder, Version=4.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bot.Builder.4.2.0\lib\netstandard2.0\Microsoft.Bot.Builder.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bot.Builder.Azure, Version=3.16.0.38373, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bot.Builder.Azure.3.16.0.38373\lib\net46\Microsoft.Bot.Builder.Azure.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bot.Builder.Dialogs, Version=4.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bot.Builder.Dialogs.4.2.0\lib\netstandard2.0\Microsoft.Bot.Builder.Dialogs.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bot.Builder.History, Version=3.16.0.38344, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bot.Builder.History.3.16.0.38344\lib\net46\Microsoft.Bot.Builder.History.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bot.Connector, Version=3.16.0.38344, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bot.Connector.3.16.0.38344\lib\net46\Microsoft.Bot.Connector.dll</HintPath>
<Reference Include="Microsoft.Bot.Builder.Integration.AspNet.WebApi, Version=4.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bot.Builder.Integration.AspNet.WebApi.4.2.0\lib\net461\Microsoft.Bot.Builder.Integration.AspNet.WebApi.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bot.Configuration, Version=4.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bot.Configuration.4.2.0\lib\netstandard2.0\Microsoft.Bot.Configuration.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bot.Connector, Version=4.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bot.Connector.4.2.0\lib\netstandard2.0\Microsoft.Bot.Connector.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bot.Schema, Version=4.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bot.Schema.4.2.0\lib\netstandard2.0\Microsoft.Bot.Schema.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.Data.Edm, Version=5.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
@ -93,23 +106,68 @@
<Reference Include="Microsoft.Data.Services.Client, Version=5.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Data.Services.Client.5.7.0\lib\net40\Microsoft.Data.Services.Client.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Logging, Version=1.1.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IdentityModel.Logging.1.1.4\lib\net451\Microsoft.IdentityModel.Logging.dll</HintPath>
<Reference Include="Microsoft.Extensions.Configuration, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Configuration.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Configuration.Abstractions, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Configuration.Abstractions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Configuration.Binder, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Configuration.Binder.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Logging.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Logging.Abstractions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Options, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Options.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Options.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Primitives, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Primitives.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Logging, Version=5.2.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IdentityModel.Logging.5.2.1\lib\net451\Microsoft.IdentityModel.Logging.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Protocol.Extensions, Version=1.0.40306.1554, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\Microsoft.IdentityModel.Protocol.Extensions.1.0.4.403061554\lib\net45\Microsoft.IdentityModel.Protocol.Extensions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Protocols, Version=2.1.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IdentityModel.Protocols.2.1.4\lib\net451\Microsoft.IdentityModel.Protocols.dll</HintPath>
<Reference Include="Microsoft.IdentityModel.Protocols, Version=5.2.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IdentityModel.Protocols.5.2.1\lib\net451\Microsoft.IdentityModel.Protocols.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect, Version=2.1.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IdentityModel.Protocols.OpenIdConnect.2.1.4\lib\net451\Microsoft.IdentityModel.Protocols.OpenIdConnect.dll</HintPath>
<Reference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect, Version=5.2.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IdentityModel.Protocols.OpenIdConnect.5.2.1\lib\net451\Microsoft.IdentityModel.Protocols.OpenIdConnect.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Tokens, Version=5.1.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IdentityModel.Tokens.5.1.4\lib\net451\Microsoft.IdentityModel.Tokens.dll</HintPath>
<Reference Include="Microsoft.IdentityModel.Tokens, Version=5.2.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IdentityModel.Tokens.5.2.1\lib\net451\Microsoft.IdentityModel.Tokens.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Recognizers.Definitions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Recognizers.Text.1.1.3\lib\net462\Microsoft.Recognizers.Definitions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Recognizers.Text, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Recognizers.Text.1.1.3\lib\net462\Microsoft.Recognizers.Text.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Recognizers.Text.Choice, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Recognizers.Text.Choice.1.1.3\lib\net462\Microsoft.Recognizers.Text.Choice.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Recognizers.Text.DateTime, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Recognizers.Text.DateTime.1.1.3\lib\net462\Microsoft.Recognizers.Text.DateTime.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Recognizers.Text.Number, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Recognizers.Text.Number.1.1.3\lib\net462\Microsoft.Recognizers.Text.Number.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Recognizers.Text.NumberWithUnit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Recognizers.Text.NumberWithUnit.1.1.3\lib\net462\Microsoft.Recognizers.Text.NumberWithUnit.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Rest.ClientRuntime, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Rest.ClientRuntime.2.3.10\lib\net452\Microsoft.Rest.ClientRuntime.dll</HintPath>
<HintPath>..\packages\Microsoft.Rest.ClientRuntime.2.3.13\lib\net452\Microsoft.Rest.ClientRuntime.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Configuration, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.WindowsAzure.ConfigurationManager.3.2.3\lib\net40\Microsoft.WindowsAzure.Configuration.dll</HintPath>
@ -120,23 +178,49 @@
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System.Buffers, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Collections.Immutable, Version=1.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Collections.Immutable.1.4.0\lib\netstandard2.0\System.Collections.Immutable.dll</HintPath>
</Reference>
<Reference Include="System.Configuration.ConfigurationManager, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Configuration.ConfigurationManager.4.4.1\lib\net461\System.Configuration.ConfigurationManager.dll</HintPath>
</Reference>
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.IdentityModel.Tokens.Jwt, Version=5.1.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\System.IdentityModel.Tokens.Jwt.5.1.4\lib\net451\System.IdentityModel.Tokens.Jwt.dll</HintPath>
<Reference Include="System.IdentityModel.Tokens.Jwt, Version=5.2.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\System.IdentityModel.Tokens.Jwt.5.2.1\lib\net451\System.IdentityModel.Tokens.Jwt.dll</HintPath>
</Reference>
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.Memory, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.5.1\lib\netstandard2.0\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Net" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
<Reference Include="System.Net.Http.Formatting, Version=5.2.6.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.6\lib\net45\System.Net.Http.Formatting.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Runtime" />
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.1\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Security" />
<Reference Include="System.Spatial, Version=5.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\System.Spatial.5.7.0\lib\net40\System.Spatial.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.1.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.4.0\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.ValueTuple">
<HintPath>..\packages\System.ValueTuple.4.4.0\lib\net47\System.ValueTuple.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.DynamicData" />
<Reference Include="System.Web.Entity" />
<Reference Include="System.Web.ApplicationServices" />
@ -146,17 +230,44 @@
<Reference Include="System.Drawing" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
<Reference Include="System.Web.Http, Version=5.2.6.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.6\lib\net45\System.Web.Http.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http.WebHost, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll</HintPath>
<Reference Include="System.Web.Http.WebHost, Version=5.2.6.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.6\lib\net45\System.Web.Http.WebHost.dll</HintPath>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="System.Configuration" />
<Reference Include="System.Web.Services" />
<Reference Include="System.EnterpriseServices" />
<Reference Include="System.Xml.Linq" />
<Reference Include="Unity.Abstractions, Version=3.3.1.0, Culture=neutral, PublicKeyToken=6d32ff45e0ccc69f, processorArchitecture=MSIL">
<HintPath>..\packages\Unity.Abstractions.3.3.1\lib\net47\Unity.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Unity.AspNet.WebApi, Version=5.0.15.0, Culture=neutral, PublicKeyToken=6d32ff45e0ccc69f, processorArchitecture=MSIL">
<HintPath>..\packages\Unity.AspNet.WebApi.5.0.15\lib\net47\Unity.AspNet.WebApi.dll</HintPath>
</Reference>
<Reference Include="Unity.Configuration, Version=5.2.5.0, Culture=neutral, PublicKeyToken=6d32ff45e0ccc69f, processorArchitecture=MSIL">
<HintPath>..\packages\Unity.5.8.13\lib\net47\Unity.Configuration.dll</HintPath>
</Reference>
<Reference Include="Unity.Container, Version=5.8.10.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\packages\Unity.Container.5.8.10\lib\net47\Unity.Container.dll</HintPath>
</Reference>
<Reference Include="Unity.Interception, Version=5.5.5.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\packages\Unity.5.8.13\lib\net47\Unity.Interception.dll</HintPath>
</Reference>
<Reference Include="Unity.Interception.Configuration, Version=5.1.7.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\packages\Unity.5.8.13\lib\net47\Unity.Interception.Configuration.dll</HintPath>
</Reference>
<Reference Include="Unity.RegistrationByConvention, Version=2.1.9.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\packages\Unity.5.8.13\lib\net47\Unity.RegistrationByConvention.dll</HintPath>
</Reference>
<Reference Include="Unity.ServiceLocation, Version=2.1.2.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\packages\Unity.5.8.13\lib\net47\Unity.ServiceLocation.dll</HintPath>
</Reference>
<Reference Include="WebActivatorEx, Version=2.0.0.0, Culture=neutral, PublicKeyToken=7b26dc2a43f6a0d4, processorArchitecture=MSIL">
<HintPath>..\packages\WebActivatorEx.2.2.0\lib\net40\WebActivatorEx.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Content Include="default.htm" />
@ -166,31 +277,34 @@
</Content>
</ItemGroup>
<ItemGroup>
<Compile Include="App_Start\WebApiConfig.cs" />
<Compile Include="Controllers\MessagesController.cs" />
<Compile Include="App_Start\BotConfig.cs" />
<Compile Include="App_Start\UnityConfig.cs" />
<Compile Include="App_Start\UnityResolver.cs" />
<Compile Include="App_Start\UnityWebApiActivator.cs" />
<Compile Include="BotState.cs" />
<Compile Include="ConsotoChatBotAccessors.cs" />
<Compile Include="ContosoChatBot.cs" />
<Compile Include="Dialogs\LocalAdminDialog.cs" />
<Compile Include="Dialogs\MainDialog.cs" />
<Compile Include="Dialogs\ResetPasswordDialog.cs" />
<Compile Include="Models\AppMsi.cs" />
<Compile Include="Models\ContosoHelpdeskContext.cs" />
<Compile Include="Models\InstallApp.cs" />
<Compile Include="Models\LocalAdmin.cs" />
<Compile Include="Models\LocalAdminPrompt.cs" />
<Compile Include="Models\Log.cs" />
<Compile Include="Models\ResetPassword.cs" />
<Compile Include="Dialogs\CancelScorable.cs" />
<Compile Include="Dialogs\InstallAppDialog.cs" />
<Compile Include="Dialogs\RootDialog.cs" />
<Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon>
</Compile>
<Compile Include="GlobalMessageHandlersBotModule.cs" />
<Compile Include="Models\ResetPasswordPrompt.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="packages.config">
<SubType>Designer</SubType>
</Content>
<Content Include="contosohelpdeskchatbot.bot" />
<None Include="Properties\PublishProfiles\ContosoHelpdeskChatBot111 - Web Deploy.pubxml" />
<None Include="Web.Debug.config">
<DependentUpon>Web.config</DependentUpon>
</None>
@ -238,7 +352,10 @@
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Azure.DocumentDB.1.22.0\build\Microsoft.Azure.DocumentDB.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Azure.DocumentDB.1.22.0\build\Microsoft.Azure.DocumentDB.targets'))" />
<Error Condition="!Exists('..\packages\SourceLink.Create.CommandLine.2.8.1\build\SourceLink.Create.CommandLine.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\SourceLink.Create.CommandLine.2.8.1\build\SourceLink.Create.CommandLine.props'))" />
<Error Condition="!Exists('..\packages\SourceLink.Create.CommandLine.2.8.1\build\SourceLink.Create.CommandLine.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\SourceLink.Create.CommandLine.2.8.1\build\SourceLink.Create.CommandLine.targets'))" />
</Target>
<Import Project="..\packages\SourceLink.Create.CommandLine.2.8.1\build\SourceLink.Create.CommandLine.targets" Condition="Exists('..\packages\SourceLink.Create.CommandLine.2.8.1\build\SourceLink.Create.CommandLine.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">

Просмотреть файл

@ -1,63 +0,0 @@
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Connector;
using System;
namespace ContosoHelpdeskChatBot
{
[BotAuthentication]
public class MessagesController : ApiController
{
/// <summary>
/// POST: api/Messages
/// Receive a message from a user and reply to it
/// </summary>
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
if (activity.Type == ActivityTypes.Message)
{
await Conversation.SendAsync(activity, () => new Dialogs.RootDialog());
}
else
{
HandleSystemMessage(activity);
}
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
private Activity HandleSystemMessage(Activity message)
{
if (message.Type == ActivityTypes.DeleteUserData)
{
// Implement user deletion here
// If we handle user deletion, return a real message
}
else if (message.Type == ActivityTypes.ConversationUpdate)
{
// Handle conversation state changes, like members being added and removed
// Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info
// Not available in all channels
}
else if (message.Type == ActivityTypes.ContactRelationUpdate)
{
// Handle add/remove from contact lists
// Activity.From + Activity.Action represent what happened
}
else if (message.Type == ActivityTypes.Typing)
{
// Handle knowing tha the user is typing
}
else if (message.Type == ActivityTypes.Ping)
{
}
return null;
}
}
}

Просмотреть файл

@ -1,65 +0,0 @@
namespace ContosoHelpdeskChatBot.Dialogs
{
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.Dialogs.Internals;
using Microsoft.Bot.Builder.Internals.Fibers;
using Microsoft.Bot.Connector;
using Microsoft.Bot.Builder.Scorables.Internals;
using Autofac;
#pragma warning disable 1998
public class CancelScorable : ScorableBase<IActivity, string, double>
{
private readonly IDialogTask task;
public CancelScorable(IDialogTask task)
{
SetField.NotNull(out this.task, nameof(task), task);
}
protected override async Task<string> PrepareAsync(IActivity activity, CancellationToken token)
{
var message = activity as IMessageActivity;
if (message != null && !string.IsNullOrWhiteSpace(message.Text))
{
if (message.Text.Equals("cancel", StringComparison.InvariantCultureIgnoreCase))
{
return message.Text;
}
}
return null;
}
protected override bool HasScore(IActivity item, string state)
{
return state != null;
}
protected override double GetScore(IActivity item, string state)
{
return 1.0;
}
protected override async Task PostAsync(IActivity item, string state, CancellationToken token)
{
var activity = (Activity)item;
var reply = activity.CreateReply($"Ok restarting conversation.");
//Refer to Connector service
//https://docs.microsoft.com/en-us/bot-framework/dotnet/bot-builder-dotnet-connector
var connector = new ConnectorClient(new Uri(activity.ServiceUrl));
await connector.Conversations.ReplyToActivityAsync(reply);
this.task.Reset();
}
protected override Task DoneAsync(IActivity item, string state, CancellationToken token)
{
return Task.CompletedTask;
}
}
}

Просмотреть файл

@ -1,41 +1,45 @@
namespace ContosoHelpdeskChatBot.Dialogs
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.FormFlow;
using Microsoft.Bot.Connector;
using ContosoHelpdeskChatBot.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.Dialogs;
using ContosoHelpdeskChatBot.Models;
using System.Threading;
using Microsoft.Bot.Builder;
namespace ContosoHelpdeskChatBot.Dialogs
{
[Serializable]
public class InstallAppDialog : IDialog<object>
public class InstallAppDialog : WaterfallDialog
{
private Models.InstallApp install = new InstallApp();
List<string> names = new List<string>();
public static string dialogId = "InstallAppDialog";
public async Task StartAsync(IDialogContext context)
public InstallAppDialog(string dialogId, IEnumerable<WaterfallStep> steps = null) : base(dialogId, steps)
{
await context.PostAsync("Ok let's get started. What is the name of the application? ");
context.Wait(appNameAsync);
AddStep(greetingStepAsync);
AddStep(responseConfirmStepAsync);
AddStep(multipleAppsStepAsync);
AddStep(multipleAppsStepAsync); // Added twice for dialog path where multiple applications are returned to user, and user must select one
}
private async Task appNameAsync(IDialogContext context, IAwaitable<IMessageActivity> userReply)
private static async Task<DialogTurnResult> greetingStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
//this will trigger a wait for user's reply
//in this case we are waiting for an app name which will be used as keyword to search the AppMsi table
var message = await userReply;
return await stepContext.PromptAsync("promptText", new PromptOptions { Prompt = MessageFactory.Text("Ok let's get started. What is the name of the application?") }, cancellationToken);
}
var appname = message.Text;
var names = await this.getAppsAsync(appname);
private async Task<DialogTurnResult> responseConfirmStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
var appName = (string)stepContext.Result;
stepContext.Values["AppName"] = appName;
names = await this.getAppsAsync(appName);
if (names.Count == 1)
{
install.AppName = names.First();
await context.PostAsync($"Found {install.AppName}. What is the name of the machine to install application?");
context.Wait(machineNameAsync);
return await stepContext.PromptAsync("promptText", new PromptOptions { Prompt = MessageFactory.Text($"Found {install.AppName}. What is the name of the machine to install application?") }, cancellationToken);
}
else if (names.Count > 1)
{
@ -44,66 +48,63 @@
{
appnames += $"<br/>&nbsp;&nbsp;&nbsp;{i + 1}.&nbsp;" + names[i];
}
await context.PostAsync($"I found {names.Count()} applications.<br/> {appnames}<br/> Please reply 1 - {names.Count()} to indicate your choice.");
//at a conversation scope, store state data in ConversationData
context.ConversationData.SetValue("AppList", names);
context.Wait(multipleAppsAsync);
return await stepContext.PromptAsync("promptNumber", new PromptOptions { Prompt = MessageFactory.Text($"I found {names.Count()} applications.<br/> {appnames}<br/> Please reply 1 - {names.Count()} to indicate your choice.") }, cancellationToken);
}
else
{
await context.PostAsync($"Sorry, I did not find any application with the name \"{appname}\".");
context.Done<object>(null);
await stepContext.Context.SendActivityAsync($"Sorry, I did not find any application with the name \"{appName}\".");
return await stepContext.EndDialogAsync();
}
}
private async Task multipleAppsAsync(IDialogContext context, IAwaitable<IMessageActivity> userReply)
private async Task<DialogTurnResult> multipleAppsStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
//this will trigger a wait for user's reply
//here we ask the user which specific app to install when we found more than one
var message = await userReply;
// Check to see if user selected app when there are multiple applications to pick from
if (stepContext.Values.ContainsKey("AppSelected"))
names.Clear();
else
names = await this.getAppsAsync(stepContext.Values["AppName"].ToString());
int choice;
var isNum = int.TryParse(message.Text, out choice);
List<string> applist;
context.ConversationData.TryGetValue("AppList", out applist);
if (isNum && choice <= applist.Count && choice > 0)
// If multiple apps returned then need to prompt user for which one to select
if (names.Count > 1)
{
//minus becoz index zero base
this.install.AppName = applist[choice - 1];
await context.PostAsync($"What is the name of the machine to install?");
context.Wait(machineNameAsync);
int choice = (int)stepContext.Result;
if (choice <= names.Count && choice > 0)
{
//minus because index zero base
stepContext.Values["AppName"] = names[choice - 1];
stepContext.Values["AppSelected"] = true;
return await stepContext.PromptAsync("promptText", new PromptOptions { Prompt = MessageFactory.Text($"What is the name of the machine to install?") }, cancellationToken);
}
else
{
return await stepContext.PromptAsync("promptNumber", new PromptOptions { Prompt = MessageFactory.Text($"Invalid response. Please reply 1 - {names.Count()} to indicate your choice.") }, cancellationToken);
}
}
else
{
await context.PostAsync($"Invalid response. Please reply 1 - {applist.Count()} to indicate your choice.");
context.Wait(multipleAppsAsync);
// Proceed with saving entry into database
var machineName = (string)stepContext.Result;
Models.InstallApp install = new InstallApp();
install.AppName = (string)stepContext.Values["AppName"];
install.MachineName = machineName;
stepContext.Values["MachineName"] = machineName;
//TODO: Save to database
using (var db = new ContosoHelpdeskContext())
{
db.InstallApps.Add(install);
db.SaveChanges();
}
await stepContext.Context.SendActivityAsync($"Great, your request to install {install.AppName} on {install.MachineName} has been scheduled.");
return await stepContext.EndDialogAsync();
}
}
private async Task machineNameAsync(IDialogContext context, IAwaitable<IMessageActivity> userReply)
{
//this will trigger a wait for user's reply
//finally we ask for the machine name on which to install the app
var message = await userReply;
var machinename = message.Text;
this.install.MachineName = machinename;
//TODO: Save to database
using (var db = new ContosoHelpdeskContext())
{
db.InstallApps.Add(install);
db.SaveChanges();
}
await context.PostAsync($"Great, your request to install {this.install.AppName} on {this.install.MachineName} has been scheduled.");
context.Done<object>(null);
}
private async Task<List<string>> getAppsAsync(string Name)
{
//TODO: Add EF to lookup database

Просмотреть файл

@ -3,58 +3,65 @@ using System.Threading.Tasks;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Connector;
using ContosoHelpdeskChatBot.Models;
using Microsoft.Bot.Builder.FormFlow;
using System.Collections.Generic;
using Microsoft.Bot.Builder;
using System.Threading;
namespace ContosoHelpdeskChatBot.Dialogs
{
[Serializable]
public class LocalAdminDialog : IDialog<object>
public class LocalAdminDialog : WaterfallDialog
{
private LocalAdmin admin = new LocalAdmin();
public async Task StartAsync(IDialogContext context)
public static string dialogId = "LocalAdminDialog";
public LocalAdminDialog(string dialogId, IEnumerable<WaterfallStep> steps = null) : base(dialogId, steps)
{
await context.PostAsync("Great I will help you request local machine admin.");
var localAdminDialog = FormDialog.FromForm(this.BuildLocalAdminForm, FormOptions.PromptInStart);
context.Call(localAdminDialog, this.ResumeAfterLocalAdminFormDialog);
AddStep(GreetingStepAsync);
AddStep(ResponseConfirmStepAsync);
AddStep(finalStepAsync);
}
private async Task ResumeAfterLocalAdminFormDialog(IDialogContext context, IAwaitable<LocalAdminPrompt> userReply)
private static async Task<DialogTurnResult> GreetingStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
using (var db = new ContosoHelpdeskContext())
await stepContext.Context.SendActivityAsync($"Great! I will help you request local machine admin.");
return await stepContext.PromptAsync("promptText", new PromptOptions { Prompt = MessageFactory.Text("What is the machine name to add you to local admin group?") }, cancellationToken);
}
private async Task<DialogTurnResult> ResponseConfirmStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
var MachineName = (string)stepContext.Result;
stepContext.Values["MachineName"] = MachineName;
return await stepContext.PromptAsync("promptNumber", new PromptOptions { Prompt = MessageFactory.Text("How many days do you need the admin access?") }, cancellationToken);
}
private async Task<DialogTurnResult> finalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
int days = (int)stepContext.Result;
if (days >= 0)
{
db.LocalAdmins.Add(admin);
db.SaveChanges();
stepContext.Values["AdminDuration"] = days;
admin.AdminDuration = (int)stepContext.Values["AdminDuration"];
admin.MachineName = (string)stepContext.Values["MachineName"];
using (var db = new ContosoHelpdeskContext())
{
db.LocalAdmins.Add(admin);
db.SaveChanges();
}
var ticketNumber = new Random().Next(0, 20000);
await stepContext.Context.SendActivityAsync($"Thank you for using the Helpdesk Bot. Your ticket number is {ticketNumber}.");
return await stepContext.EndDialogAsync();
}
else
{
await stepContext.Context.SendActivityAsync($"Invalid response provided. Ending dialog.");
return await stepContext.EndDialogAsync();
}
context.Done<object>(null);
}
private IForm<LocalAdminPrompt> BuildLocalAdminForm()
{
//here's an example of how validation can be used in form builder
return new FormBuilder<LocalAdminPrompt>()
.Field(nameof(LocalAdminPrompt.MachineName),
validate: async (state, value) =>
{
var result = new ValidateResult { IsValid = true, Value = value };
//add validation here
this.admin.MachineName = (string)value;
return result;
})
.Field(nameof(LocalAdminPrompt.AdminDuration),
validate: async (state, value) =>
{
var result = new ValidateResult { IsValid = true, Value = value };
//add validation here
this.admin.AdminDuration = Convert.ToInt32((long)value) as int?;
return result;
})
.Build();
}
}
}

Просмотреть файл

@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Dialogs;
using System.Threading.Tasks;
using System.Threading;
using Microsoft.Bot.Builder.Dialogs.Choices;
namespace ContosoHelpdeskChatBot.Dialogs
{
public class MainDialog : WaterfallDialog
{
private const string InstallAppOption = "Install Application (install)";
private const string ResetPasswordOption = "Reset Password (password)";
private const string LocalAdminOption = "Request Local Admin (admin)";
private const string GreetMessage = "Welcome to **Contoso Helpdesk Chat Bot**.\n\nI am designed to use with mobile email app, make sure your replies do not contain signatures. \n\nFollowing is what I can help you with, just reply with word in parenthesis:";
private const string ErrorMessage = "Not a valid option. Please select one of the possible choices:";
private static List<Choice> HelpdeskOptions = new List<Choice>
{
new Choice { Value = InstallAppOption, Synonyms = new List<string>{ "install", "application", "install application" } },
new Choice { Value = ResetPasswordOption, Synonyms = new List<string>{ "password", "reset", "reset password" } },
new Choice { Value = LocalAdminOption, Synonyms = new List<string>{ "admin", "request", "local", "request local admin" } }
};
public static string dialogId = "MainDialog";
public MainDialog(string dialogId) : base(dialogId)
{
AddStep(GreetingStepAsync);
AddStep(ChoiceSelectedStepAsync);
}
private static async Task<DialogTurnResult> GreetingStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
return await stepContext.PromptAsync("promptChoice", new PromptOptions
{
Prompt = MessageFactory.Text(GreetMessage),
Choices = HelpdeskOptions,
RetryPrompt = MessageFactory.Text(ErrorMessage)
}, cancellationToken);
}
private static async Task<DialogTurnResult> ChoiceSelectedStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
var optionSelected = (stepContext.Result as FoundChoice)?.Value;
switch (optionSelected)
{
case InstallAppOption:
return await stepContext.BeginDialogAsync(InstallAppDialog.dialogId);
case ResetPasswordOption:
return await stepContext.BeginDialogAsync(ResetPasswordDialog.dialogId);
case LocalAdminOption:
return await stepContext.BeginDialogAsync(LocalAdminDialog.dialogId);
}
return await stepContext.NextAsync();
}
}
}

Просмотреть файл

@ -3,40 +3,81 @@ using System.Linq;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Connector;
using Microsoft.Bot.Builder.FormFlow;
using ContosoHelpdeskChatBot.Models;
using ContosoHelpdeskSms;
using System.Collections.Generic;
using System.Threading;
using Microsoft.Bot.Builder;
namespace ContosoHelpdeskChatBot.Dialogs
{
[Serializable]
public class ResetPasswordDialog : IDialog<object>
public class ResetPasswordDialog : WaterfallDialog
{
public async Task StartAsync(IDialogContext context)
public static string dialogId = "ResetPasswordDialog";
public ResetPasswordDialog(string dialogId, IEnumerable<WaterfallStep> steps = null) : base(dialogId, steps)
{
await context.PostAsync("Alright I will help you create a temp password");
AddStep(GreetingStepAsync);
AddStep(PasscodeReceivedStepAsync);
}
if (sendPassCode(context))
private async Task<DialogTurnResult> GreetingStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
await stepContext.Context.SendActivityAsync("Alright I will help you create a temp password");
if (sendPassCode(stepContext))
{
var resetPasswordDialog = FormDialog.FromForm(this.BuildResetPasswordForm, FormOptions.PromptInStart);
context.Call(resetPasswordDialog, this.ResumeAfterResetPasswordFormDialog);
return await stepContext.PromptAsync("promptNumber", new PromptOptions { Prompt = MessageFactory.Text("Please provide four digit pass code") }, cancellationToken);
}
else
{
//here we can simply fail the current dialog because we have root dialog handling all exceptions
context.Fail(new Exception("Failed to send SMS. Make sure email & phone number has been added to database."));
await stepContext.Context.SendActivityAsync("Failed to send SMS. Make sure email & phone number has been added to database.");
return await stepContext.EndDialogAsync();
}
}
private bool sendPassCode(IDialogContext context)
private async Task<DialogTurnResult> PasscodeReceivedStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
int result;
bool isNum = int.TryParse(stepContext.Context.Activity.Text, out result);
if (isNum)
{
var email = stepContext.Context.Activity.From.Id;
int? passcode;
using (var db = new ContosoHelpdeskContext())
{
passcode = db.ResetPasswords.Where(r => r.EmailAddress == email).First().PassCode;
}
if (result == passcode)
{
string temppwd = "TempPwd" + new Random().Next(0, 5000);
await stepContext.Context.SendActivityAsync($"Your temp password is {temppwd}");
return await stepContext.EndDialogAsync();
}
else
{
await stepContext.Context.SendActivityAsync($"Incorrect passcode.");
return await stepContext.EndDialogAsync();
}
}
else
{
await stepContext.Context.SendActivityAsync($"Invalid passcode.");
return await stepContext.EndDialogAsync();
}
}
private bool sendPassCode(WaterfallStepContext context)
{
bool result = false;
//Recipient Id varies depending on channel
//refer ChannelAccount class https://docs.botframework.com/en-us/csharp/builder/sdkreference/dd/def/class_microsoft_1_1_bot_1_1_connector_1_1_channel_account.html#a0b89cf01fdd73cbc00a524dce9e2ad1a
//as well as Activity class https://docs.botframework.com/en-us/csharp/builder/sdkreference/dc/d2f/class_microsoft_1_1_bot_1_1_connector_1_1_activity.html
var email = context.Activity.From.Id;
var email = context.Context.Activity.From.Id;
int passcode = new Random().Next(1000, 9999);
Int64? smsNumber = 0;
string smsMessage = "Your Contoso Pass Code is ";
@ -63,32 +104,5 @@ namespace ContosoHelpdeskChatBot.Dialogs
return result;
}
private IForm<ResetPasswordPrompt> BuildResetPasswordForm()
{
return new FormBuilder<ResetPasswordPrompt>()
.Field(nameof(ResetPasswordPrompt.PassCode))
.Build();
}
private async Task ResumeAfterResetPasswordFormDialog(IDialogContext context, IAwaitable<ResetPasswordPrompt> userReply)
{
var prompt = await userReply;
var email = context.Activity.From.Id;
int? passcode;
using (var db = new ContosoHelpdeskContext())
{
passcode = db.ResetPasswords.Where(r => r.EmailAddress == email).First().PassCode;
}
if (prompt.PassCode == passcode)
{
string temppwd = "TempPwd" + new Random().Next(0, 5000);
await context.PostAsync($"Your temp password is {temppwd}");
}
context.Done<object>(null);
}
}
}

Просмотреть файл

@ -1,90 +0,0 @@
namespace ContosoHelpdeskChatBot.Dialogs
{
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Connector;
[Serializable]
public class RootDialog : IDialog<object>
{
private static log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private const string InstallAppOption = "Install Application (install)";
private const string ResetPasswordOption = "Reset Password (password)";
private const string LocalAdminOption = "Request Local Admin (admin)";
private const string GreetMessage = "Welcome to **Contoso Helpdesk Chat Bot**.\n\nI am designed to use with mobile email app, make sure your replies do not contain signatures. \n\nFollowing is what I can help you with, just reply with word in parenthesis:";
private const string ErrorMessage = "Not a valid option";
private static List<string> HelpdeskOptions = new List<string>()
{
InstallAppOption,
ResetPasswordOption,
LocalAdminOption
};
public async Task StartAsync(IDialogContext context)
{
context.Wait(this.MessageReceivedAsync);
}
public virtual async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> userReply)
{
var message = await userReply;
this.ShowOptions(context);
}
private void ShowOptions(IDialogContext context)
{
PromptDialog.Choice(context, this.OnOptionSelected, HelpdeskOptions, GreetMessage, ErrorMessage, 3, PromptStyle.PerLine);
}
private async Task OnOptionSelected(IDialogContext context, IAwaitable<string> userReply)
{
try
{
string optionSelected = await userReply;
switch (optionSelected)
{
case InstallAppOption:
context.Call(new InstallAppDialog(), this.ResumeAfterOptionDialog);
break;
case ResetPasswordOption:
context.Call(new ResetPasswordDialog(), this.ResumeAfterOptionDialog);
break;
case LocalAdminOption:
context.Call(new LocalAdminDialog(), this.ResumeAfterOptionDialog);
break;
}
}
catch (TooManyAttemptsException ex)
{
await context.PostAsync($"Ooops! Too many attemps :(. But don't worry, I'm handling that exception and you can try again!");
context.Wait(this.MessageReceivedAsync);
}
}
private async Task ResumeAfterOptionDialog(IDialogContext context, IAwaitable<object> userReply)
{
try
{
var message = await userReply;
var ticketNumber = new Random().Next(0, 20000);
await context.PostAsync($"Thank you for using the Helpdesk Bot. Your ticket number is {ticketNumber}.");
context.Done(ticketNumber);
}
catch (Exception ex)
{
await context.PostAsync($"Failed with message: {ex.Message}");
// In general resume from task after calling a child dialog is a good place to handle exceptions
// try catch will capture exceptions from the bot framework awaitable object which is essentially "userReply"
logger.Error(ex);
}
}
}
}

Просмотреть файл

@ -1,7 +1,5 @@
using Autofac;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.Dialogs.Internals;
using Microsoft.Bot.Builder.Internals.Fibers;
using Microsoft.Bot.Connector;
using Microsoft.Bot.Builder.Azure;
using System;
@ -11,6 +9,8 @@ using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Routing;
using ContosoHelpdeskChatBot.App_Start;
namespace ContosoHelpdeskChatBot
{
@ -18,49 +18,12 @@ namespace ContosoHelpdeskChatBot
{
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
BotConfig.UpdateConversationContainer();
this.RegisterBotModules();
GlobalConfiguration.Configure(config =>
{
BotConfig.Register(config);
});
log4net.Config.XmlConfigurator.Configure();
}
//setting Bot data store policy to use last write win
//example if bot service got restarted, existing conversation would just overwrite data to store
public static class BotConfig
{
public static void UpdateConversationContainer()
{
var store = new InMemoryDataStore();
Conversation.UpdateContainer(
builder =>
{
builder.Register(c => store)
.Keyed<IBotDataStore<BotData>>(AzureModule.Key_DataStore)
.AsSelf()
.SingleInstance();
builder.Register(c => new CachingBotDataStore(store,
CachingBotDataStoreConsistencyPolicy
.ETagBasedConsistency))
.As<IBotDataStore<BotData>>()
.AsSelf()
.InstancePerLifetimeScope();
});
}
}
private void RegisterBotModules()
{
Conversation.UpdateContainer(builder =>
{
builder.RegisterModule(new ReflectionSurrogateModule());
builder.RegisterModule<GlobalMessageHandlersBotModule>();
});
}
}
}

Просмотреть файл

@ -1,21 +0,0 @@
namespace ContosoHelpdeskChatBot
{
using Autofac;
using Dialogs;
using Microsoft.Bot.Builder.Dialogs.Internals;
using Microsoft.Bot.Builder.Scorables;
using Microsoft.Bot.Connector;
public class GlobalMessageHandlersBotModule : Module
{
protected override void Load(ContainerBuilder builder)
{
base.Load(builder);
builder
.Register(c => new CancelScorable(c.Resolve<IDialogTask>()))
.As<IScorable<IActivity, double>>()
.InstancePerLifetimeScope();
}
}
}

Просмотреть файл

@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Bot.Builder.FormFlow;
namespace ContosoHelpdeskChatBot.Models
{
public class LocalAdminPrompt
{
[Prompt("What is the machine name to add you to local admin group?")]
public string MachineName { get; set; }
[Prompt("How many days do you need the admin access?")]
public int? AdminDuration { get; set; }
}
}

Просмотреть файл

@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace ContosoHelpdeskChatBot.Models
{
using System;
using Microsoft.Bot.Builder.FormFlow;
[Serializable]
public class ResetPasswordPrompt
{
[Prompt("Please provide four digit pass code")]
public int PassCode { get; set; }
}
}

Просмотреть файл

@ -10,10 +10,6 @@
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<appSettings>
<!-- update these with your BotId, Microsoft App Id and your Microsoft App Password-->
<add key="BotId" value="leoleo-helpdesktestbot" />
<add key="MicrosoftAppId" value="71750bfc-f09a-46a0-80f9-4fca9f911a23" />
<add key="MicrosoftAppPassword" value="purDHCWM1-%#bfmtTF4494;" />
<!-- Uncomment this if log4net is not log to table -->
<!--<add key="log4net.Internal.Debug" value="true"/>-->
</appSettings>
@ -49,13 +45,13 @@
<add value="default.htm" />
</files>
</defaultDocument>
<handlers>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
</handlers></system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
@ -80,7 +76,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
<bindingRedirect oldVersion="0.0.0.0-5.2.6.0" newVersion="5.2.6.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da" culture="neutral" />
@ -88,11 +84,11 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Bot.Connector" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.11.1.0" newVersion="3.11.1.0" />
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.1.4.0" newVersion="5.1.4.0" />
<bindingRedirect oldVersion="0.0.0.0-5.2.1.0" newVersion="5.2.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" />
@ -108,7 +104,15 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.IdentityModel.Tokens" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.1.4.0" newVersion="5.1.4.0" />
<bindingRedirect oldVersion="0.0.0.0-5.2.1.0" newVersion="5.2.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Bot.Builder" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.6.0" newVersion="5.2.6.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>

Просмотреть файл

@ -0,0 +1,15 @@
{
"name": "BOTNAME",
"services": [
{
"type": "endpoint",
"name": "development",
"endpoint": "ENDPOINT",
"appId": "APPID",
"appPassword": "PASSWORD",
"id": "166"
}
],
"padlock": "",
"version": "2.0"
}

Просмотреть файл

@ -4,28 +4,61 @@
<package id="Chronic.Signed" version="0.3.2" targetFramework="net46" />
<package id="EntityFramework" version="6.2.0" targetFramework="net471" />
<package id="log4net" version="2.0.8" targetFramework="net471" />
<package id="Microsoft.AspNet.WebApi" version="5.2.3" targetFramework="net46" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net46" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net46" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net46" />
<package id="Microsoft.AspNet.WebApi" version="5.2.6" targetFramework="net471" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.6" targetFramework="net471" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.6" targetFramework="net471" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.6" targetFramework="net471" />
<package id="Microsoft.Azure.DocumentDB" version="1.22.0" targetFramework="net471" />
<package id="Microsoft.Azure.KeyVault.Core" version="1.0.0" targetFramework="net471" />
<package id="Microsoft.Bot.Builder" version="3.16.0.38344" targetFramework="net471" />
<package id="Microsoft.Bot.Builder" version="4.2.0" targetFramework="net471" />
<package id="Microsoft.Bot.Builder.Azure" version="3.16.0.38373" targetFramework="net471" />
<package id="Microsoft.Bot.Builder.Dialogs" version="4.2.0" targetFramework="net471" />
<package id="Microsoft.Bot.Builder.History" version="3.16.0.38344" targetFramework="net471" />
<package id="Microsoft.Bot.Connector" version="3.16.0.38344" targetFramework="net471" />
<package id="Microsoft.Bot.Builder.Integration.AspNet.WebApi" version="4.2.0" targetFramework="net471" />
<package id="Microsoft.Bot.Configuration" version="4.2.0" targetFramework="net471" />
<package id="Microsoft.Bot.Connector" version="4.2.0" targetFramework="net471" />
<package id="Microsoft.Bot.Schema" version="4.2.0" targetFramework="net471" />
<package id="Microsoft.Data.Edm" version="5.7.0" targetFramework="net471" />
<package id="Microsoft.Data.OData" version="5.7.0" targetFramework="net471" />
<package id="Microsoft.Data.Services.Client" version="5.7.0" targetFramework="net471" />
<package id="Microsoft.IdentityModel.Logging" version="1.1.4" targetFramework="net471" />
<package id="Microsoft.Extensions.Configuration" version="2.1.1" targetFramework="net471" />
<package id="Microsoft.Extensions.Configuration.Abstractions" version="2.1.1" targetFramework="net471" />
<package id="Microsoft.Extensions.Configuration.Binder" version="2.1.1" targetFramework="net471" />
<package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="2.1.1" targetFramework="net471" />
<package id="Microsoft.Extensions.Logging" version="2.1.1" targetFramework="net471" />
<package id="Microsoft.Extensions.Logging.Abstractions" version="2.1.1" targetFramework="net471" />
<package id="Microsoft.Extensions.Options" version="2.1.1" targetFramework="net471" />
<package id="Microsoft.Extensions.Primitives" version="2.1.1" targetFramework="net471" />
<package id="Microsoft.IdentityModel.Logging" version="5.2.1" targetFramework="net471" />
<package id="Microsoft.IdentityModel.Protocol.Extensions" version="1.0.4.403061554" targetFramework="net46" />
<package id="Microsoft.IdentityModel.Protocols" version="2.1.4" targetFramework="net471" />
<package id="Microsoft.IdentityModel.Protocols.OpenIdConnect" version="2.1.4" targetFramework="net471" />
<package id="Microsoft.IdentityModel.Tokens" version="5.1.4" targetFramework="net471" />
<package id="Microsoft.Rest.ClientRuntime" version="2.3.10" targetFramework="net471" />
<package id="Microsoft.IdentityModel.Protocols" version="5.2.1" targetFramework="net471" />
<package id="Microsoft.IdentityModel.Protocols.OpenIdConnect" version="5.2.1" targetFramework="net471" />
<package id="Microsoft.IdentityModel.Tokens" version="5.2.1" targetFramework="net471" />
<package id="Microsoft.Recognizers.Text" version="1.1.3" targetFramework="net471" />
<package id="Microsoft.Recognizers.Text.Choice" version="1.1.3" targetFramework="net471" />
<package id="Microsoft.Recognizers.Text.DateTime" version="1.1.3" targetFramework="net471" />
<package id="Microsoft.Recognizers.Text.Number" version="1.1.3" targetFramework="net471" />
<package id="Microsoft.Recognizers.Text.NumberWithUnit" version="1.1.3" targetFramework="net471" />
<package id="Microsoft.Rest.ClientRuntime" version="2.3.13" targetFramework="net471" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net471" />
<package id="Microsoft.WindowsAzure.ConfigurationManager" version="3.2.3" targetFramework="net471" />
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net471" />
<package id="System.IdentityModel.Tokens.Jwt" version="5.1.4" targetFramework="net471" />
<package id="SourceLink.Create.CommandLine" version="2.8.1" targetFramework="net471" developmentDependency="true" />
<package id="System.Buffers" version="4.4.0" targetFramework="net471" />
<package id="System.Collections.Immutable" version="1.4.0" targetFramework="net471" />
<package id="System.Configuration.ConfigurationManager" version="4.4.1" targetFramework="net471" />
<package id="System.IdentityModel.Tokens.Jwt" version="5.2.1" targetFramework="net471" />
<package id="System.Memory" version="4.5.1" targetFramework="net471" />
<package id="System.Numerics.Vectors" version="4.4.0" targetFramework="net471" />
<package id="System.Reflection.Emit" version="4.3.0" targetFramework="net471" />
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.1" targetFramework="net471" />
<package id="System.Spatial" version="5.7.0" targetFramework="net471" />
<package id="System.Threading.Tasks.Extensions" version="4.4.0" targetFramework="net471" />
<package id="System.ValueTuple" version="4.4.0" targetFramework="net471" />
<package id="Unity" version="5.8.13" targetFramework="net471" />
<package id="Unity.Abstractions" version="3.3.1" targetFramework="net471" />
<package id="Unity.AspNet.WebApi" version="5.0.15" targetFramework="net471" />
<package id="Unity.Container" version="5.8.10" targetFramework="net471" />
<package id="WebActivatorEx" version="2.2.0" targetFramework="net471" />
<package id="WindowsAzure.Storage" version="7.2.1" targetFramework="net471" />
</packages>