diff --git a/VQCalendarAttention/CalendarApiTest.cs b/VQCalendarAttention/CalendarApiTest.cs index 7784f1f..f427786 100644 --- a/VQCalendarAttention/CalendarApiTest.cs +++ b/VQCalendarAttention/CalendarApiTest.cs @@ -7,25 +7,13 @@ using Google.Apis.Calendar.v3.Data; using Google.Apis.Services; -internal class CalendarApiTest +public class CalendarApiTest { public static async Task GetLatestEventAsync(string calendarId, string credentialsFilePath) { - try { - - // サービスアカウントの認証情報を読み込む - GoogleCredential credential; - using (var stream = new FileStream(credentialsFilePath, FileMode.Open, FileAccess.Read)) - { - credential = GoogleCredential.FromStream(stream).CreateScoped(CalendarService.Scope.CalendarReadonly); - } - - // GoogleカレンダーAPIのサービスを作成 - var service = new CalendarService(new BaseClientService.Initializer - { - HttpClientInitializer = credential, - ApplicationName = "VQCalendarAttention", - }); + try + { + CalendarService service = getCalendarService(credentialsFilePath); // イベントリストのリクエストを作成 var request = service.Events.List(calendarId); @@ -63,4 +51,22 @@ Console.WriteLine($"Error: {ex.Message}"); } } -} \ No newline at end of file + + public static CalendarService getCalendarService(string credentialsFilePath) + { + // サービスアカウントの認証情報を読み込む + GoogleCredential credential; + using (var stream = new FileStream(credentialsFilePath, FileMode.Open, FileAccess.Read)) + { + credential = GoogleCredential.FromStream(stream).CreateScoped(CalendarService.Scope.CalendarReadonly); + } + + // GoogleカレンダーAPIのサービスを作成 + var service = new CalendarService(new BaseClientService.Initializer + { + HttpClientInitializer = credential, + ApplicationName = "VQCalendarAttention", + }); + return service; + } +} diff --git a/VQCalendarAttention/Program.cs b/VQCalendarAttention/Program.cs index d9f5c87..5222b68 100644 --- a/VQCalendarAttention/Program.cs +++ b/VQCalendarAttention/Program.cs @@ -7,13 +7,15 @@ { public class Program { - public static async Task Main(string[] args) + private const string CredentialsFilePath = "../calendartowebhook-fa30e21f081f.json"; + private const string CalendarId = "3e39821e10e795b311f93c79490960c3196632a465a794ca32e8a44c50115dde@group.calendar.google.com"; + + public static void Main(string[] args) { - //CreateHostBuilder(args).Build().Run(); + CreateHostBuilder(args).Build().Run(); // テストとしてCalendarApiTestを実行する - await CalendarApiTest.GetLatestEventAsync("3e39821e10e795b311f93c79490960c3196632a465a794ca32e8a44c50115dde@group.calendar.google.com", "../calendartowebhook-fa30e21f081f.json"); - + // await CalendarApiTest.GetLatestEventAsync("3e39821e10e795b311f93c79490960c3196632a465a794ca32e8a44c50115dde@group.calendar.google.com", "../calendartowebhook-fa30e21f081f.json"); } public static IHostBuilder CreateHostBuilder(string[] args) => @@ -21,16 +23,19 @@ .ConfigureServices((hostContext, services) => { // Cronosで定義したCronジョブサービスを追加 - services.AddHostedService(serviceProvider => + // 翌日の予定を通知する + services.AddHostedService(serviceProvider => { // Cron式を設定 (例: 毎日午前9時に実行) //var cronExpression = CronExpression.Parse("0 9 * * *"); - var cronExpression = CronExpression.Parse("* * * * *"); + // 毎晩21時に実行 + var cronExpression = CronExpression.Parse("0 21 * * *"); + //var cronExpression = CronExpression.Parse("* * * * *"); - // タイムゾーンを設定 (例: UTC) - var timeZoneInfo = TimeZoneInfo.Utc; + // タイムゾーンを東京に設定 + var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time"); - return new CalendarAttentionService(cronExpression, timeZoneInfo, serviceProvider); + return new NextDayCalendarAttentionService(cronExpression, timeZoneInfo, serviceProvider, CredentialsFilePath, CalendarId); }); }); } diff --git a/VQCalendarAttention/Services/CalendarAttentionService.cs b/VQCalendarAttention/Services/CalendarAttentionService.cs index 3ca1af6..efe8091 100644 --- a/VQCalendarAttention/Services/CalendarAttentionService.cs +++ b/VQCalendarAttention/Services/CalendarAttentionService.cs @@ -1,5 +1,6 @@ using System; using Cronos; +using Google.Apis.Calendar.v3; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using ServiceWorkerCronJobDemo.Services; @@ -10,10 +11,16 @@ { private readonly IServiceProvider _serviceProvider; - public CalendarAttentionService(CronExpression expression, TimeZoneInfo timeZoneInfo, IServiceProvider serviceProvider) + /// + /// Googleカレンダー用の認証情報 + /// + private string _credentialsFilePath; + + public CalendarAttentionService(CronExpression expression, TimeZoneInfo timeZoneInfo, IServiceProvider serviceProvider, string credentialsFilePath) : base(expression, timeZoneInfo) { _serviceProvider = serviceProvider; + _credentialsFilePath = credentialsFilePath; } public override async Task DoWork(CancellationToken cancellationToken) diff --git a/VQCalendarAttention/Services/NextDayCalendarAttentionService.cs b/VQCalendarAttention/Services/NextDayCalendarAttentionService.cs new file mode 100644 index 0000000..09f87dc --- /dev/null +++ b/VQCalendarAttention/Services/NextDayCalendarAttentionService.cs @@ -0,0 +1,80 @@ +using System; +using Cronos; +using Google.Apis.Calendar.v3; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using ServiceWorkerCronJobDemo.Services; + +namespace VestalisQuintet.VQCalendarAttention +{ + /// + /// 次の日に実施される予定を出力するタスク + /// + public class NextDayCalendarAttentionService : CronJobService + { + private readonly IServiceProvider _serviceProvider; + + /// + /// Googleカレンダー用の認証情報 + /// + private string _credentialsFilePath; + + /// + /// 取得先のカレンダーID + /// + private string _calendarId; + + public NextDayCalendarAttentionService(CronExpression expression, TimeZoneInfo timeZoneInfo, IServiceProvider serviceProvider, + string credentialsFilePath, string calendarId) + : base(expression, timeZoneInfo) + { + _serviceProvider = serviceProvider; + _credentialsFilePath = credentialsFilePath; + _calendarId = calendarId; + } + + public override async Task DoWork(CancellationToken cancellationToken) + { + Console.WriteLine("Cron job executed at: " + DateTimeOffset.Now); + + // カレンダーから予定を取得して、翌日に行われる予定を抽出する + CalendarService service = CalendarApiTest.getCalendarService(_credentialsFilePath); + + // タイムゾーンを指定してUTCからJSTへ変換 + TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time"); + DateTime jst = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, tzi); + + // イベントリストのリクエストを作成 + var request = service.Events.List(_calendarId); + request.TimeMin = jst; + request.ShowDeleted = false; + request.SingleEvents = true; + request.MaxResults = 250; + request.OrderBy = EventsResource.ListRequest.OrderByEnum.StartTime; + + // イベントリストのリクエストを実行 + var events = await request.ExecuteAsync(); + + // 明日に行われる予定を抽出する + DateTime startOfTomorrow = jst.Date.AddDays(1); + DateTime endOfTomorrow = startOfTomorrow.AddDays(1); + + var tomorrowEvents = events.Items.Where(e => e.Start.DateTime >= startOfTomorrow && e.Start.DateTime < endOfTomorrow).ToList(); + // 明日の予定を表示 + if (tomorrowEvents.Count > 0) + { + Console.WriteLine("明日の予定:"); + foreach (var tomorrowEvent in tomorrowEvents) + { + Console.WriteLine($"{tomorrowEvent.Summary}: {tomorrowEvent.Start.DateTime}"); + } + } + else + { + Console.WriteLine("明日の予定はありません。"); + } + + await Task.CompletedTask; + } + } +}