From a33f3e52dfab6d70b78c29d2cc8685bb612e5e77 Mon Sep 17 00:00:00 2001 From: "Brady Stroud [SSW]" Date: Sat, 7 Oct 2023 20:21:32 +1000 Subject: [PATCH] DI the Graph client Remove a bunch of comments Work on teams call data --- .vscode/settings.json | 3 ++ .../Services/GraphService.cs | 44 ++++++++++++------- .../Services/TimesheetService.cs | 20 ++++----- src/TimesheetGPT.Gateway/Program.cs | 5 +-- .../DependencyInjection.cs | 34 +++----------- src/TimesheetGPT.WebUI/Pages/Index.razor | 2 +- 6 files changed, 46 insertions(+), 62 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..489fbf6 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "dotnet.defaultSolution": "TimesheetGPT.sln" +} \ No newline at end of file diff --git a/src/TimesheetGPT.Core/Services/GraphService.cs b/src/TimesheetGPT.Core/Services/GraphService.cs index 935c006..13533f9 100644 --- a/src/TimesheetGPT.Core/Services/GraphService.cs +++ b/src/TimesheetGPT.Core/Services/GraphService.cs @@ -1,5 +1,6 @@ using Microsoft.Graph; using Microsoft.Graph.Models; +using Microsoft.Graph.Models.ODataErrors; using TimesheetGPT.Core.Interfaces; using TimesheetGPT.Core.Models; @@ -24,7 +25,6 @@ public async Task> GetEmailSubjects(DateTime date) var dateUtc = date.ToUniversalTime(); var nextDayUtc = nextDay.ToUniversalTime(); - // GET https://graph.microsoft.com/v1.0/me/mailFolders('sentitems')/messages var messages = await _client.Me.MailFolders["sentitems"].Messages .GetAsync(rc => { @@ -52,7 +52,7 @@ public async Task> GetMeetings(DateTime date) var nextDay = date.AddDays(1); var dateUtc = date.ToUniversalTime(); var nextDayUtc = nextDay.ToUniversalTime(); - + var meetings = await _client.Me.CalendarView.GetAsync(rc => { rc.QueryParameters.Top = 999; @@ -61,7 +61,7 @@ public async Task> GetMeetings(DateTime date) rc.QueryParameters.Orderby = new[] { "start/dateTime" }; rc.QueryParameters.Select = new[] { "subject", "start", "end", "occurrenceId" }; }); - + if (meetings is { Value.Count: > 1 }) { return meetings.Value.Select(m => new Meeting @@ -72,28 +72,38 @@ public async Task> GetMeetings(DateTime date) // Sender = m.EmailAddress.Address TODO: Why is Organizer and attendees null? permissions? }).ToList(); } - + return new List(); //slack } - public async Task> GetTeamsCalls(DateTime date) { + public async Task> GetTeamsCalls(DateTime date) + { var nextDay = date.AddDays(1); var dateUtc = date.ToUniversalTime(); var nextDayUtc = nextDay.ToUniversalTime(); - - var calls = await _client.Communications.CallRecords.GetAsync(rc => - { - rc.QueryParameters.Top = 999; - rc.QueryParameters.Orderby = new[] { "start/dateTime" }; - rc.QueryParameters.Select = new[] { "subject", "start", "end", "occurrenceId" }; - }); - if (calls is { Value.Count: > 1 }) + try { - return calls.Value.Select(m => new TeamsCall + var calls = await _client.Communications.CallRecords.GetAsync(rc => { - Attendees = m.Participants.Select(p => p.User.DisplayName).ToList(), - Length = m.EndDateTime - m.StartDateTime ?? TimeSpan.Zero, - }).ToList(); + rc.QueryParameters.Top = 999; + rc.QueryParameters.Orderby = new[] { "startDateTime" }; + rc.QueryParameters.Select = new[] { "startDateTime", "endDateTime", "participants" }; + rc.QueryParameters.Filter = $"startDateTime ge {dateUtc:o} and endDateTime lt {nextDayUtc:o}"; + }); + + if (calls is { Value.Count: > 1 }) + { + return calls.Value.Select(m => new TeamsCall + { + Attendees = m.Participants.Select(p => p.User.DisplayName).ToList(), + Length = m.EndDateTime - m.StartDateTime ?? TimeSpan.Zero, + }).ToList(); + } + } + catch (ODataError e) + { + Console.WriteLine("Need CallRecords.Read.All scopes"); + throw; } return new List(); diff --git a/src/TimesheetGPT.Core/Services/TimesheetService.cs b/src/TimesheetGPT.Core/Services/TimesheetService.cs index 6fd5166..b77ef77 100644 --- a/src/TimesheetGPT.Core/Services/TimesheetService.cs +++ b/src/TimesheetGPT.Core/Services/TimesheetService.cs @@ -5,23 +5,18 @@ namespace TimesheetGPT.Core.Services; -public class TimesheetService +public class TimesheetService(IAiService aiService, GraphServiceClient graphServiceClient) { - private readonly IAiService _aiService; - - public TimesheetService(IAiService aiService) + public async Task GenerateSummary(DateTime date, string extraPrompts = "", string additionalNotes = "") { - _aiService = aiService; - } - - public async Task GenerateSummary(DateTime date, GraphServiceClient client, string extraPrompts = "", string additionalNotes = "") - { - IGraphService graphService = new GraphService(client); + var graphService = new GraphService(graphServiceClient); var emailSubjects = await graphService.GetEmailSubjects(date); var meetings = await graphService.GetMeetings(date); + // var calls = await graphService.GetTeamsCalls(date); + // TODO: SSW needs to allow the CallRecords.Read.All scope for this to work - var summary = await _aiService.GetSummary(StringifyData(emailSubjects, meetings), extraPrompts, additionalNotes); + var summary = await aiService.GetSummary(StringifyData(emailSubjects, meetings), extraPrompts, additionalNotes); return new SummaryWithRaw { @@ -32,7 +27,7 @@ public async Task GenerateSummary(DateTime date, GraphServiceCli }; } - private string StringifyData(List emails, List meetings) + private string StringifyData(IEnumerable emails, IList meetings) { var result = "Sent emails (subject) \n"; foreach (var email in emails) @@ -40,6 +35,7 @@ private string StringifyData(List emails, List meetings) result += email + "\n"; } result += "\n Calendar Events (name - length) \n"; + foreach (var meeting in meetings) { result += $"{meeting.Name} - {meeting.Length} \n"; diff --git a/src/TimesheetGPT.Gateway/Program.cs b/src/TimesheetGPT.Gateway/Program.cs index 9f8b8ca..25b2ade 100644 --- a/src/TimesheetGPT.Gateway/Program.cs +++ b/src/TimesheetGPT.Gateway/Program.cs @@ -6,15 +6,12 @@ builder.Configuration.AddUserSecrets(typeof(Program).Assembly); builder.Services.AddTimesheetGptUi(builder.Configuration); -/* builder.Services.AddTimesheetGptApi(builder.Configuration); -*/ var app = builder.Build(); -/* app.UseTimesheetGptApi(); -*/ + app.UseTimesheetGptUi(); app.Run(); \ No newline at end of file diff --git a/src/TimesheetGPT.WebAPI/DependencyInjection.cs b/src/TimesheetGPT.WebAPI/DependencyInjection.cs index d43e703..164c030 100644 --- a/src/TimesheetGPT.WebAPI/DependencyInjection.cs +++ b/src/TimesheetGPT.WebAPI/DependencyInjection.cs @@ -2,7 +2,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Microsoft.Identity.Web; + using TimesheetGPT.WebAPI.Endpoints; namespace TimesheetGPT.WebAPI; @@ -11,44 +11,22 @@ public static class DependencyInjection { public static IServiceCollection AddTimesheetGptApi(this IServiceCollection services, IConfiguration config) { - // Add services to the container. - // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle services.AddEndpointsApiExplorer(); services.AddSwaggerGen(); - - services.AddMicrosoftIdentityWebApiAuthentication(config, "AzureAd") - .EnableTokenAcquisitionToCallDownstreamApi() - .AddInMemoryTokenCaches(); - - // Get tenantId, clientId and clientSecret from appsettings.json - // and pass them to GraphService - // - // var tenantId = configuration["AzureAd:TenantId"]; - // var clientId = configuration["AzureAd:ClientId"]; - // var clientSecret = configuration["AzureAd:ClientSecret"]; - // - // // ensure the above values are set - // if (string.IsNullOrEmpty(tenantId) || - // string.IsNullOrEmpty(clientId) || - // string.IsNullOrEmpty(clientSecret)) - // { - // throw new Exception("TenantId, ClientId and ClientSecret must be set in appsettings.json"); - // } - + return services; } - + public static WebApplication UseTimesheetGptApi(this WebApplication app) { - // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } - - app.MapGetSubjects(); + app.MapGetSubjects(); + return app; } -} \ No newline at end of file +} diff --git a/src/TimesheetGPT.WebUI/Pages/Index.razor b/src/TimesheetGPT.WebUI/Pages/Index.razor index 2f4788b..2a0e67c 100644 --- a/src/TimesheetGPT.WebUI/Pages/Index.razor +++ b/src/TimesheetGPT.WebUI/Pages/Index.razor @@ -165,7 +165,7 @@ return; } var dateTime = _date ?? DateTime.Today; - var summary = await TimesheetService.GenerateSummary(dateTime, GraphServiceClient, _extraPrompt ?? "", _additionalNotes); + var summary = await TimesheetService.GenerateSummary(dateTime, _extraPrompt ?? "", _additionalNotes); _emailSubjects = summary.Emails; _meetings = summary.Meetings;