diff --git a/VQCalendarAttention/Program.cs b/VQCalendarAttention/Program.cs
index 0a5cac5..66c84eb 100644
--- a/VQCalendarAttention/Program.cs
+++ b/VQCalendarAttention/Program.cs
@@ -38,6 +38,23 @@
string CredentialsFilePath = DotNetEnv.Env.GetString("CREDENTIALS_FILE_PATH");
return new NextDayCalendarAttentionService(cronExpression, timeZoneInfo, serviceProvider, CredentialsFilePath, calendarId);
});
+
+ // 重要な予定を通知する
+ services.AddHostedService(serviceProvider =>
+ {
+ // Cron式を設定 (例: 毎日午前9時に実行)
+ //var cronExpression = CronExpression.Parse("0 9 * * *");
+ // 毎晩21時2分に実行
+ var cronExpression = CronExpression.Parse("2 21 * * *");
+ //var cronExpression = CronExpression.Parse("* * * * *");
+
+ // タイムゾーンを東京に設定
+ var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time");
+
+ string calendarId = DotNetEnv.Env.GetString("CALENDAR_ID");
+ string CredentialsFilePath = DotNetEnv.Env.GetString("CREDENTIALS_FILE_PATH");
+ return new ImportantCalendarAttentionService(cronExpression, timeZoneInfo, serviceProvider, CredentialsFilePath, calendarId);
+ });
});
}
}
diff --git a/VQCalendarAttention/Services/ImportantCalendarAttentionService.cs b/VQCalendarAttention/Services/ImportantCalendarAttentionService.cs
new file mode 100644
index 0000000..a899909
--- /dev/null
+++ b/VQCalendarAttention/Services/ImportantCalendarAttentionService.cs
@@ -0,0 +1,105 @@
+using System;
+using System.Text;
+using Cronos;
+using Google.Apis.Calendar.v3;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using ServiceWorkerCronJobDemo.Services;
+
+namespace VestalisQuintet.VQCalendarAttention
+{
+ ///
+ /// 説明に[重要]という文字列がついている予定について、
+ /// 今からちょうど3日後か7日後である場合に、指定のロールに
+ /// メンションを送りつつDiscordのwebhookに通知するタスク
+ ///
+ public class ImportantCalendarAttentionService : CronJobService
+ {
+ private readonly IServiceProvider _serviceProvider;
+
+ ///
+ /// Googleカレンダー用の認証情報
+ ///
+ private string _credentialsFilePath;
+
+ ///
+ /// 取得先のカレンダーID
+ ///
+ private string _calendarId;
+
+ public ImportantCalendarAttentionService(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);
+
+ // カレンダーから予定を取得して、3日後と7日後に行われる予定を抽出する
+ 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.TimeMax = jst.AddDays(8); // 7日後までのイベントを取得
+ request.ShowDeleted = false;
+ request.SingleEvents = true;
+ request.MaxResults = 250;
+ request.OrderBy = EventsResource.ListRequest.OrderByEnum.StartTime;
+
+ // イベントリストのリクエストを実行
+ var events = await request.ExecuteAsync();
+
+ // 3日後と7日後に行われる[重要]な予定を抽出する
+ var importantEvents = events.Items
+ .Where(e => e.Description != null && e.Description.Contains("[重要]") &&
+ (
+ (e.Start.DateTime.HasValue &&
+ (e.Start.DateTime.Value.Date == jst.AddDays(3).Date ||
+ e.Start.DateTime.Value.Date == jst.AddDays(7).Date)) ||
+ (e.Start.Date != null &&
+ (DateTime.Parse(e.Start.Date).Date == jst.AddDays(3).Date ||
+ DateTime.Parse(e.Start.Date).Date == jst.AddDays(7).Date))
+ )
+ )
+ .ToList();
+
+ // [重要]な予定をDiscordに送信
+ if (importantEvents.Count > 0)
+ {
+ // DiscordWebhook インスタンスを作成
+ string webhookUrl = DotNetEnv.Env.GetString("DISCORD_WEBHOOK_URL");
+ var discordWebhook = new DiscordWebhook(webhookUrl);
+
+ // 通知先ロールIDを指定
+ string roleId = DotNetEnv.Env.GetString("DISCORD_ROLE_ID");
+
+ // [重要]な予定をメッセージとして組み立て
+ var sb = new StringBuilder("重要な予定が迫っています:\n");
+ foreach (var importantEvent in importantEvents)
+ {
+ string startTime = importantEvent.Start.DateTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? DateTime.Parse(importantEvent.Start.Date).ToString("yyyy-MM-dd");
+ sb.AppendLine($"<@&{roleId}> {importantEvent.Summary}: {startTime}"); // ロールIDを使用したメンションを作成
+ }
+
+ // メッセージをDiscordに送信
+ await discordWebhook.SendMessageAsync(sb.ToString());
+ }
+ else
+ {
+ Console.WriteLine("重要な予定はありません。");
+ }
+
+ await Task.CompletedTask;
+ }
+ }
+}