├── ExcelBot
├── Global.asax
├── Model
│ ├── UserData.cs
│ ├── ObjectType.cs
│ └── ChartAttachment.cs
├── Helpers
│ ├── RequestHelper.cs
│ ├── IndexOf.cs
│ ├── TelemetryHelper.cs
│ ├── BotStateHelper.cs
│ ├── ServicesHelper.cs
│ ├── LuisHelper.cs
│ └── ExcelHelper.cs
├── Constants
│ └── Constants.cs
├── Forms
│ ├── OpenWorkbookForm.cs
│ └── SelectWorksheetForm.cs
├── PrivateSettings.config.example
├── loggedin.htm
├── Properties
│ └── AssemblyInfo.cs
├── chat.htm
├── Web.Debug.config
├── App_Start
│ └── WebApiConfig.cs
├── Web.Release.config
├── default.htm
├── ExcelBot.csproj.user
├── Global.asax.cs
├── Dialogs
│ ├── OpenWorkbookDialog.cs
│ ├── GraphDialog.cs
│ ├── DialogExtensions.cs
│ ├── WorkbooksDialog.cs
│ ├── ChartsDialog.cs
│ ├── ExcelBotDialog.cs
│ ├── TablesDialog.cs
│ ├── NamedItemsDialog.cs
│ ├── WorksheetsDialog.cs
│ └── CellsDialog.cs
├── Workers
│ ├── WorkbookWorker.cs
│ ├── CellWorker.cs
│ ├── WorksheetWorker.cs
│ └── ChartsWorker.cs
├── Controllers
│ ├── ChartController.cs
│ └── MessagesController.cs
├── packages.config
├── ApplicationInsights.config
└── Web.config
├── readme-images
├── appID.png
├── create.png
├── idandkey.png
├── luisimport.png
├── testpublish.png
├── aad-application-id.PNG
├── aad-register-an-app.PNG
├── aad-copy-client-secret.png
├── aad-new-client-secret.png
└── aad-portal-app-registrations.png
├── .gitignore
├── ExcelBot.sln
├── LICENSE
├── .gitattributes
├── README-localized
├── README-zh-cn.md
├── README-ja-jp.md
├── README-pt-br.md
├── README-ru-ru.md
├── README-es-es.md
└── README-fr-fr.md
├── README.md
└── CONTRIBUTING.md
/ExcelBot/Global.asax:
--------------------------------------------------------------------------------
1 | <%@ Application Codebehind="Global.asax.cs" Inherits="ExcelBot.WebApiApplication" Language="C#" %>
2 |
--------------------------------------------------------------------------------
/readme-images/appID.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoftgraph/botframework-csharp-excelbot-rest-sample/HEAD/readme-images/appID.png
--------------------------------------------------------------------------------
/readme-images/create.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoftgraph/botframework-csharp-excelbot-rest-sample/HEAD/readme-images/create.png
--------------------------------------------------------------------------------
/readme-images/idandkey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoftgraph/botframework-csharp-excelbot-rest-sample/HEAD/readme-images/idandkey.png
--------------------------------------------------------------------------------
/readme-images/luisimport.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoftgraph/botframework-csharp-excelbot-rest-sample/HEAD/readme-images/luisimport.png
--------------------------------------------------------------------------------
/readme-images/testpublish.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoftgraph/botframework-csharp-excelbot-rest-sample/HEAD/readme-images/testpublish.png
--------------------------------------------------------------------------------
/readme-images/aad-application-id.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoftgraph/botframework-csharp-excelbot-rest-sample/HEAD/readme-images/aad-application-id.PNG
--------------------------------------------------------------------------------
/readme-images/aad-register-an-app.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoftgraph/botframework-csharp-excelbot-rest-sample/HEAD/readme-images/aad-register-an-app.PNG
--------------------------------------------------------------------------------
/readme-images/aad-copy-client-secret.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoftgraph/botframework-csharp-excelbot-rest-sample/HEAD/readme-images/aad-copy-client-secret.png
--------------------------------------------------------------------------------
/readme-images/aad-new-client-secret.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoftgraph/botframework-csharp-excelbot-rest-sample/HEAD/readme-images/aad-new-client-secret.png
--------------------------------------------------------------------------------
/readme-images/aad-portal-app-registrations.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoftgraph/botframework-csharp-excelbot-rest-sample/HEAD/readme-images/aad-portal-app-registrations.png
--------------------------------------------------------------------------------
/ExcelBot/Model/UserData.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 | namespace ExcelBot.Model
7 | {
8 | public class UserData
9 | {
10 | public string AuthResult { get; set; }
11 | }
12 | }
--------------------------------------------------------------------------------
/ExcelBot/Model/ObjectType.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 | namespace ExcelBot.Model
7 | {
8 | public enum ObjectType
9 | {
10 | Cell,
11 | NamedItem,
12 | Chart,
13 | Table
14 | }
15 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ################################################################################
2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio.
3 | ################################################################################
4 |
5 | /ExcelBot/bin
6 | /ExcelBot/obj
7 | /packages
8 | /ExcelBotEmbedded/ExcelBotEmbedded/bin
9 | /.vs
10 | ExcelBot/PrivateSettings.config
11 | PublishProfiles/
12 |
--------------------------------------------------------------------------------
/ExcelBot/Model/ChartAttachment.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 | namespace ExcelBot.Model
7 | {
8 | public class ChartAttachment
9 | {
10 | public string WorkbookId { get; set; }
11 | public string WorksheetId { get; set; }
12 | public string ChartId { get; set; }
13 | }
14 | }
--------------------------------------------------------------------------------
/ExcelBot/Helpers/RequestHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | /*
4 | * Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
5 | * See LICENSE in the project root for license information.
6 | */
7 |
8 | namespace ExcelBot.Helpers
9 | {
10 | public static class RequestHelper
11 | {
12 | #region Properties
13 | public static Uri RequestUri { get; set; }
14 | #endregion
15 |
16 | #region Methods
17 | #endregion
18 | }
19 | }
--------------------------------------------------------------------------------
/ExcelBot/Constants/Constants.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 | using System.Configuration;
7 |
8 | namespace ExcelBot
9 | {
10 | public static class Constants
11 | {
12 | internal static string microsoftAppId = ConfigurationManager.AppSettings["MicrosoftAppId"];
13 | internal static string microsoftAppPassword = ConfigurationManager.AppSettings["MicrosoftAppPassword"];
14 | }
15 |
16 | }
--------------------------------------------------------------------------------
/ExcelBot/Helpers/IndexOf.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 |
10 | namespace ExcelBot.Helpers
11 | {
12 | public static class Extensions
13 | {
14 | public static int IndexOf(this IEnumerable list, Predicate condition)
15 | {
16 | int i = -1;
17 | return list.Any(x => { i++; return condition(x); }) ? i : -1;
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/ExcelBot/Forms/OpenWorkbookForm.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 | using Microsoft.Bot.Builder.FormFlow;
7 | using System;
8 |
9 | namespace ExcelBot.Forms
10 | {
11 | [Serializable]
12 | public class OpenWorkbookForm
13 | {
14 | [Prompt("What is the name of the workbook you want to work with?")]
15 | public string WorkbookName;
16 |
17 | public static IForm BuildForm()
18 | {
19 | return new FormBuilder()
20 | .AddRemainingFields()
21 | .Build();
22 | }
23 | };
24 | }
--------------------------------------------------------------------------------
/ExcelBot/PrivateSettings.config.example:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/ExcelBot.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27428.2011
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExcelBot", "ExcelBot\ExcelBot.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 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {A77CB6A6-C57C-45F1-BBE6-435D1532D80F}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Microsoft-Graph-Bot-Framework-CSharp-ExcelBot-Rest-Sample
2 |
3 | Copyright (c) Microsoft Corporation. All rights reserved.
4 |
5 | MIT License
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining
8 | a copy of this software and associated documentation files (the
9 | "Software"), to deal in the Software without restriction, including
10 | without limitation the rights to use, copy, modify, merge, publish,
11 | distribute, sublicense, and/or sell copies of the Software, and to
12 | permit persons to whom the Software is furnished to do so, subject to
13 | the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be
16 | included in all copies or substantial portions of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ExcelBot/loggedin.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Excel Bot
7 |
8 |
18 |
19 |
20 | Sign-in Successful
21 | You can now chat with the bot.
22 |
23 |
24 |
--------------------------------------------------------------------------------
/ExcelBot/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("ExcelBot")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("ExcelBot")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
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 |
--------------------------------------------------------------------------------
/ExcelBot/chat.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Excel Bot
7 |
8 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/ExcelBot/Web.Debug.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
19 |
20 |
31 |
32 |
--------------------------------------------------------------------------------
/ExcelBot/App_Start/WebApiConfig.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 | using Newtonsoft.Json;
7 | using Newtonsoft.Json.Serialization;
8 | using System.Web.Http;
9 |
10 | namespace ExcelBot
11 | {
12 | public static class WebApiConfig
13 | {
14 | public static void Register(HttpConfiguration config)
15 | {
16 | // Json settings
17 | config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
18 | config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
19 | config.Formatters.JsonFormatter.SerializerSettings.Formatting = Formatting.Indented;
20 | JsonConvert.DefaultSettings = () => new JsonSerializerSettings()
21 | {
22 | ContractResolver = new CamelCasePropertyNamesContractResolver(),
23 | Formatting = Newtonsoft.Json.Formatting.Indented,
24 | NullValueHandling = NullValueHandling.Ignore,
25 | };
26 |
27 | // Web API configuration and services
28 |
29 | // Web API routes
30 | config.MapHttpAttributeRoutes();
31 |
32 | config.Routes.MapHttpRoute(
33 | name: "DefaultApi",
34 | routeTemplate: "api/{controller}/{id}",
35 | defaults: new { id = RouteParameter.Optional }
36 | );
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/ExcelBot/Web.Release.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
19 |
20 |
21 |
32 |
33 |
--------------------------------------------------------------------------------
/ExcelBot/default.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
18 |
19 |
20 | ExcelBot
21 | Describe your bot here and your terms of use etc.
22 | 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
23 |
24 |
25 |
--------------------------------------------------------------------------------
/ExcelBot/ExcelBot.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | true
5 | excelbotv3-staging - Web Deploy
6 | ProjectFiles
7 | Debug|Any CPU
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | default.htm
20 | SpecificPage
21 | True
22 | False
23 | False
24 | False
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | True
34 | True
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/ExcelBot/Global.asax.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 | using Autofac;
7 | using Microsoft.Bot.Builder.Azure;
8 | using Microsoft.Bot.Builder.Dialogs;
9 | using Microsoft.Bot.Builder.Dialogs.Internals;
10 | using Microsoft.Bot.Connector;
11 | using System;
12 | using System.Configuration;
13 | using System.Reflection;
14 | using System.Web.Http;
15 |
16 | namespace ExcelBot
17 | {
18 | public class WebApiApplication : System.Web.HttpApplication
19 | {
20 | protected void Application_Start()
21 | {
22 | // Need to register a bot state data store
23 | Conversation.UpdateContainer(
24 | builder =>
25 | {
26 | builder.RegisterModule(new AzureModule(Assembly.GetExecutingAssembly()));
27 |
28 | // This will create a CosmosDB store, suitable for production
29 | // NOTE: Requires an actual CosmosDB instance and configuration in
30 | // PrivateSettings.config
31 | var databaseUri = new Uri(ConfigurationManager.AppSettings["Database.Uri"]);
32 | var databaseKey = ConfigurationManager.AppSettings["Database.Key"];
33 | var store = new DocumentDbBotDataStore(databaseUri, databaseKey);
34 |
35 | builder.Register(c => store)
36 | .Keyed>(AzureModule.Key_DataStore)
37 | .AsSelf()
38 | .SingleInstance();
39 | });
40 |
41 | GlobalConfiguration.Configure(WebApiConfig.Register);
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/ExcelBot/Forms/SelectWorksheetForm.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 | using Microsoft.Bot.Builder.FormFlow;
7 | using Microsoft.Bot.Builder.FormFlow.Advanced;
8 | using System;
9 |
10 | namespace ExcelBot.Forms
11 | {
12 | [Serializable]
13 | public class SelectWorksheetForm
14 | {
15 | public static string[] Worksheets;
16 | public string WorksheetName;
17 |
18 | public static IForm BuildForm()
19 | {
20 | return new FormBuilder()
21 | .Field(new FieldReflector(nameof(WorksheetName))
22 | .SetType(null)
23 | .SetActive((state) => true)
24 | #pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
25 | .SetDefine(async (state, field) =>
26 | {
27 | foreach (var worksheet in Worksheets)
28 | {
29 | field
30 | .AddDescription(worksheet, worksheet)
31 | .AddTerms(worksheet, worksheet, worksheet.ToLower());
32 | }
33 | field
34 | .SetPrompt(new PromptAttribute("Which worksheet do you want to work with? {||}") { ChoiceFormat = @"{0}. {1}"});
35 | return true;
36 | })
37 | #pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
38 | )
39 | .Build();
40 | }
41 | };
42 | }
--------------------------------------------------------------------------------
/ExcelBot/Helpers/TelemetryHelper.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 | using Microsoft.ApplicationInsights;
7 | using Microsoft.Bot.Builder.Dialogs;
8 | using Microsoft.Bot.Builder.Luis.Models;
9 | using Microsoft.Bot.Connector;
10 | using System.Collections.Generic;
11 | using System.Text;
12 | using System.Web;
13 |
14 | namespace ExcelBot.Helpers
15 | {
16 | public static class TelemetryHelper
17 | {
18 | #region Methods
19 | public static void SetIds(Activity activity)
20 | {
21 | HttpContext.Current.Items["UserId"] = activity.From.Id;
22 | HttpContext.Current.Items["ConversationId"] = activity.Conversation.Id;
23 | HttpContext.Current.Items["ChannelId"] = activity.ChannelId;
24 | }
25 | public static void TrackEvent(string eventName, Dictionary properties = null, Dictionary metrics = null)
26 | {
27 | var tc = new TelemetryClient();
28 |
29 | tc.Context.User.AccountId = (string)(HttpContext.Current.Items["UserId"]);
30 | tc.Context.User.Id = (string)(HttpContext.Current.Items["UserId"]);
31 | tc.Context.Session.Id = (string)(HttpContext.Current.Items["ConversationId"]);
32 | tc.Context.Device.Type = (string)(HttpContext.Current.Items["ChannelId"]);
33 |
34 | tc.TrackEvent(eventName, properties, metrics);
35 | }
36 |
37 | public static void TrackDialog(IDialogContext context, LuisResult result, string moduleName, string dialogName)
38 | {
39 | var properties = new Dictionary();
40 | properties.Add("Module", moduleName);
41 | properties.Add("Dialog", dialogName);
42 | properties.Add("Query", result.Query);
43 |
44 | var metrics = new Dictionary();
45 | metrics.Add("EntityCount", result.Entities.Count);
46 |
47 | var entityTypes = new StringBuilder();
48 | var separator = "";
49 | foreach (var entity in result.Entities)
50 | {
51 | entityTypes.Append($"{separator}{entity.Type}");
52 | separator = ",";
53 | }
54 | properties.Add("EntityTypes", entityTypes.ToString());
55 |
56 | TrackEvent($"Dialog/{moduleName}/{dialogName}", properties, metrics);
57 | }
58 | #endregion
59 | }
60 | }
--------------------------------------------------------------------------------
/ExcelBot/Helpers/BotStateHelper.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 | using Microsoft.Azure.Documents;
7 | using Microsoft.Azure.Documents.Client;
8 | using Microsoft.Bot.Connector;
9 | using System;
10 | using System.Configuration;
11 | using System.Net;
12 | using System.Threading.Tasks;
13 |
14 | namespace ExcelBot.Helpers
15 | {
16 | public static class BotStateHelper
17 | {
18 | private static readonly string databaseUri = ConfigurationManager.AppSettings["Database.Uri"];
19 | private static readonly string databaseKey = ConfigurationManager.AppSettings["Database.Key"];
20 |
21 | private static readonly string databaseId = "botdb";
22 | private static readonly string collectionId = "botcollection";
23 |
24 | private static DocumentClient client = null;
25 |
26 | private static void EnsureClient()
27 | {
28 | if (client == null)
29 | {
30 | client = new DocumentClient(new Uri(databaseUri), databaseKey);
31 | }
32 | }
33 |
34 | public static async Task GetUserDataAsync(string channelId, string userId)
35 | {
36 | // Construct user doc id
37 | string userDocId = string.Format("{0}:user{1}", channelId, userId);
38 |
39 | return await GetDocumentAsync(userDocId);
40 | }
41 |
42 | public static async Task GetConversationDataAsync(string channelId, string conversationId)
43 | {
44 | // Construct user doc id
45 | string conversationDocId = string.Format("{0}:conversation{1}", channelId, conversationId);
46 |
47 | return await GetDocumentAsync(conversationDocId);
48 | }
49 |
50 | private static async Task GetDocumentAsync(string docId)
51 | {
52 | EnsureClient();
53 |
54 | try
55 | {
56 | Document document = await client.ReadDocumentAsync(
57 | UriFactory.CreateDocumentUri(databaseId, collectionId, docId));
58 |
59 | return (BotData)(dynamic)document;
60 | }
61 | catch (DocumentClientException ex)
62 | {
63 | if (HttpStatusCode.NotFound == ex.StatusCode)
64 | {
65 | return null;
66 | }
67 |
68 | throw;
69 | }
70 | }
71 | }
72 | }
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/ExcelBot/Dialogs/OpenWorkbookDialog.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 | using ExcelBot.Forms;
7 | using ExcelBot.Helpers;
8 | using ExcelBot.Workers;
9 | using Microsoft.Bot.Builder.Dialogs;
10 | using Microsoft.Bot.Builder.FormFlow;
11 | using System;
12 | using System.Threading.Tasks;
13 |
14 | namespace ExcelBot.Dialogs
15 | {
16 | [Serializable]
17 | public class ConfirmOpenWorkbookDialog : GraphDialog, IDialog
18 | {
19 | #pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
20 | public override async Task StartAsync(IDialogContext context)
21 | #pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
22 | {
23 | PromptDialog.Confirm(context, AfterConfirming_OpenWorkbook, $"I don't have a workbook open. Do you want me to open a workbook?");
24 | }
25 |
26 | private async Task AfterConfirming_OpenWorkbook(IDialogContext context, IAwaitable confirmation)
27 | {
28 | if (await confirmation)
29 | {
30 | // Call the OpenWorkbook Form
31 | context.Call(
32 | new FormDialog(new OpenWorkbookForm(), OpenWorkbookForm.BuildForm, FormOptions.PromptInStart),
33 | OpenWorkbook_FormComplete);
34 | }
35 | else
36 | {
37 | await context.PostAsync("Okay! I will just sit tight until you tell me which workbook we should work with");
38 | context.Done(false);
39 | }
40 | }
41 |
42 | private async Task OpenWorkbook_FormComplete(IDialogContext context, IAwaitable result)
43 | {
44 | OpenWorkbookForm form = null;
45 | try
46 | {
47 | form = await result;
48 | }
49 | catch
50 | {
51 | }
52 |
53 | if (form != null)
54 | {
55 | // Get access token to see if user is authenticated
56 | ServicesHelper.AccessToken = await GetAccessToken(context);
57 |
58 | // Open the workbook
59 | await WorkbookWorker.DoOpenWorkbookAsync(context, form.WorkbookName);
60 | context.Done(true);
61 | }
62 | else
63 | {
64 | await context.PostAsync("Okay! I will just sit tight until you tell me which workbook we should work with");
65 | context.Done(false);
66 | }
67 | }
68 | }
69 | }
--------------------------------------------------------------------------------
/ExcelBot/Workers/WorkbookWorker.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 | using ExcelBot.Helpers;
7 | using Microsoft.Bot.Builder.Dialogs;
8 | using System;
9 | using System.Threading.Tasks;
10 |
11 | namespace ExcelBot.Workers
12 | {
13 | public static class WorkbookWorker
14 | {
15 | public static async Task DoOpenWorkbookAsync(IDialogContext context, string workbookName)
16 | {
17 | try
18 | {
19 | // Add extension to filename, if needed
20 | var filename = workbookName.ToLower();
21 | if (!(filename.EndsWith(".xlsx")))
22 | {
23 | filename = $"{filename}.xlsx";
24 | }
25 |
26 | // Get meta data for the workbook
27 | var itemRequest = ServicesHelper.GraphClient.Me.Drive.Root.ItemWithPath(filename).Request();
28 | var item = await itemRequest.GetAsync();
29 | await ServicesHelper.LogGraphServiceRequest(context, itemRequest);
30 |
31 | context.UserData.SetValue("WorkbookId", item.Id);
32 | context.ConversationData.SetValue("WorkbookName", item.Name);
33 | context.ConversationData.SetValue("WorkbookWebUrl", item.WebUrl);
34 |
35 | context.UserData.RemoveValue("Type");
36 | context.UserData.RemoveValue("Name");
37 | context.UserData.RemoveValue("CellAddress");
38 | context.UserData.RemoveValue("TableName");
39 | context.UserData.RemoveValue("RowIndex");
40 |
41 | // Get the first worksheet in the workbook
42 | var headers = ServicesHelper.GetWorkbookSessionHeader(
43 | ExcelHelper.GetSessionIdForRead(context));
44 |
45 | var worksheetsRequest = ServicesHelper.GraphClient.Me.Drive.Items[item.Id]
46 | .Workbook.Worksheets.Request(headers).Top(1);
47 |
48 | var worksheets = await worksheetsRequest.GetAsync();
49 | await ServicesHelper.LogGraphServiceRequest(context, worksheetsRequest);
50 |
51 | context.UserData.SetValue("WorksheetId", worksheets[0].Name);
52 |
53 | // Respond
54 | await context.PostAsync($"We are ready to work with **{worksheets[0].Name}** in {ExcelHelper.GetWorkbookLinkMarkdown(context)}");
55 | }
56 | catch (Exception ex)
57 | {
58 | await context.PostAsync($"Sorry, something went wrong when I tried to open the **{workbookName}** workbook on your OneDrive for Business ({ex.Message})");
59 | }
60 | }
61 |
62 | public static async Task DoGetActiveWorkbookAsync(IDialogContext context)
63 | {
64 | await context.PostAsync($"We are working with the {ExcelHelper.GetWorkbookLinkMarkdown(context)} workbook");
65 | }
66 | }
67 | }
--------------------------------------------------------------------------------
/ExcelBot/Helpers/ServicesHelper.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 | using Microsoft.Bot.Builder.Dialogs;
7 | using Microsoft.Graph;
8 | using Newtonsoft.Json;
9 | using System.Collections.Generic;
10 | using System.Threading.Tasks;
11 | using System.Web;
12 |
13 | namespace ExcelBot.Helpers
14 | {
15 | public static class ServicesHelper
16 | {
17 | private static bool doLogging = false;
18 |
19 | #region Properties
20 | public static string AccessToken
21 | {
22 | get
23 | {
24 | return (string)(HttpContext.Current.Items["AccessToken"]);
25 | }
26 | set
27 | {
28 | HttpContext.Current.Items["AccessToken"] = value;
29 | }
30 | }
31 |
32 | public static GraphServiceClient GraphClient
33 | {
34 | get
35 | {
36 | if (!(HttpContext.Current.Items.Contains("GraphClient")))
37 | {
38 | var client = new GraphServiceClient(
39 | new DelegateAuthenticationProvider(
40 | #pragma warning disable CS1998
41 | async (requestMessage) =>
42 | {
43 | requestMessage.Headers.Authorization =
44 | new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", AccessToken);
45 | }));
46 | #pragma warning restore CS1998
47 |
48 | HttpContext.Current.Items["GraphClient"] = client;
49 | }
50 |
51 | return (GraphServiceClient)HttpContext.Current.Items["GraphClient"];
52 | }
53 | }
54 |
55 | public static List GetWorkbookSessionHeader(string sessionId)
56 | {
57 | return new List()
58 | {
59 | new HeaderOption("workbook-session-id", sessionId)
60 | };
61 | }
62 | #endregion
63 |
64 | #region Methods
65 | public static void StartLogging(bool verbose)
66 | {
67 | doLogging = verbose;
68 | }
69 |
70 | public static async Task LogGraphServiceRequest(IDialogContext context, IBaseRequest request, object payload = null)
71 | {
72 | if (doLogging)
73 | {
74 | if (request.Method == "POST" || request.Method == "PATCH")
75 | {
76 | string prettyPayload = JsonConvert.SerializeObject(payload, Formatting.Indented);
77 | await context.PostAsync($"```\n{request.Method} {request.RequestUrl}\n\n{prettyPayload}\n```");
78 | }
79 | else
80 | {
81 | await context.PostAsync($"`{request.Method} {request.RequestUrl}`");
82 | }
83 | }
84 | }
85 | #endregion
86 | }
87 | }
--------------------------------------------------------------------------------
/ExcelBot/Dialogs/GraphDialog.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 | using BotAuth;
7 | using BotAuth.AADv2;
8 | using BotAuth.Dialogs;
9 | using BotAuth.Models;
10 | using ExcelBot.Helpers;
11 | using Microsoft.Bot.Builder.Dialogs;
12 | using Microsoft.Bot.Connector;
13 | using System;
14 | using System.Configuration;
15 | using System.Threading;
16 | using System.Threading.Tasks;
17 |
18 | namespace ExcelBot.Dialogs
19 | {
20 | [Serializable]
21 | public class GraphDialog : LuisDialog