Outlookカレンダー(クラウド版)のイベント一覧をリストとして取得する【C#】

Microsoft Graphを使ってクラウド上のカレンダーの操作を行うための方法を説明します。ここではイベントの一覧をリストとして取得する処理をユーティリティー的に使えるように静的メソッドとして実装した例をお示ししています。

なお、UWPアプリにおけるユーザー認証については以下の記事をご覧ください。

動作確認環境

  • Microsoft.Graph 3.28.0

予定表のすべてのイベントを取得する

GetEventsAsyncメソッドを作成する

GetEventsAsyncメソッド (CalendarHelperクラス)
public static async Task<List<Event>> GetEventsAsync(string calendarId = null)
{
    List<Event> events = new List<Event>();

    try
    {
        GraphServiceClient graphClient = await AuthenticationHelper.GetAuthenticatedClientAsync();

        if (calendarId == null)
        {
            var eventPage = await graphClient.Me.Calendar.Events.Request().OrderBy("Start/DateTime").GetAsync();
            var pageIterator = PageIterator<Event>.CreatePageIterator(graphClient, eventPage, m =>
            {
                events.Add(m);
                return true;
            });
            await pageIterator.IterateAsync();
        }
        else
        {
            var eventPage = await graphClient.Me.Calendars[calendarId].Events.Request().OrderBy("Start/DateTime").GetAsync();
            var pageIterator = PageIterator<Event>.CreatePageIterator(graphClient, eventPage, m =>
            {
                events.Add(m);
                return true;
            });
            await pageIterator.IterateAsync();
        }
    }
    catch (ServiceException e)
    {
        Debug.WriteLine(e.Error.Message);
        return null;
    }

    return events;
}
AuthenticationHelperについては以下の記事をご覧ください。

※ APIのアクセス許可スコープに「Calendars.Read」を追加しておく必要があります。

CalendarHelperクラスにユーティリティ的に使えるように静的メソッドとしてGetEventsAsyncメソッドを定義しましょう。

まず、7行目でユーザー認証を行いGraphServiceClientインスタンスを取得しています。ここで、カレンダーIDが指定されている場合はそのカレンダーから、指定されていない場合はデフォルトカレンダーからイベントを取得するので、カレンダーIDの指定の有無で場合分けして考えてみましょう(9-28行目)。

カレンダーIDが指定されていないときはデフォルトカレンダーからイベントを検索するので、11行目でMeCalendarEventsの3つのRequestBuilderからリクエストを構築し、Requestメソッドでリクエストを完成させます(ICalendarEventsCollectionRequest)。さらにOrderByメソッドでイベントの開始日時で並べ替えて、GetAsyncメソッドでEvent型のコレクションページを取得しましょう。

await graphClient.Me.Calendar.Events.Request().OrderBy("Start/DateTime").GetAsync();

12-17行目でEvent型のコレクションページから一つ一つのEventオブジェクトをリストとして取り出しています。

なお、OrderByメソッドでの並べ替えは以下の記事もご覧ください。

同様にしてカレンダーIDが指定されている場合の処理も記述していきましょう。

21行目でMeCalendarsEventsの3つのRequestBuilderからリクエストを構築し、Requestメソッドでリクエストを完成させます(ICalendarEventsCollectionRequest)。この時、CalendarsIUserCalendarsCollectionRequestBuilder型なので、インデクサでカレンダーIDを指定しましょう。さらにOrderByメソッドでイベントの開始日時で並べ替えて、GetAsyncメソッドでEvent型のコレクションページを取得しましょう。

await graphClient.Me.Calendars[calendarId].Events.Request().OrderBy("Start/DateTime").GetAsync();

あとは、先ほどと同様にコレクションページから一つ一つのEventオブジェクトをリストとして取り出します。

なお、予定表からイベントの取得方法は以下のドキュメントもご覧ください。

例:予定表からすべてのイベントを取得する

それではこのGetEventsAsyncメソッドを用いて、デフォルトの予定表からすべてのイベントを取得してみましょう。取得したイベントの開始時刻とイベント名を文字列として取得します。

List<Event> events = await CalendarHelper.GetEventsAsync();

string txtEvents = "";
foreach (var ev in events)
{
    txtEvents += ev.Start.DateTime + "\t" + ev.Subject + Environment.NewLine;
}

このプログラムはイベント数によっては処理に時間がかかることがあるので注意してください。

期間を指定して予定表からイベント一覧を取得する

GetEventsAsyncメソッドを作成する

GetEventsAsyncメソッド (CalendarHelperクラス)
public static async Task<List<Event>> GetEventsAsync(DateTime startDateTime, DateTime endDateTime, string calendarId = null)
{
    List<Event> events = new List<Event>();

    try
    {
        GraphServiceClient graphClient = await AuthenticationHelper.GetAuthenticatedClientAsync();

        var options = new List<QueryOption>();
        options.Add(new QueryOption("StartDateTime", DateTimeTimeZone.FromDateTime(startDateTime.ToUniversalTime());
        options.Add(new QueryOption("EndDateTime", DateTimeTimeZone.FromDateTime(endDateTime.ToUniversalTime());

        if (calendarId == null)
        {
            var eventPage = await graphClient.Me.Calendar.CalendarView.Request(options).OrderBy("Start/DateTime").GetAsync();
            var pageIterator = PageIterator<Event>.CreatePageIterator(graphClient, eventPage, m =>
            {
                events.Add(m);
                return true;
            });
            await pageIterator.IterateAsync();
        }
        else
        {
            var eventPage = await graphClient.Me.Calendars[calendarId].CalendarView.Request(options).OrderBy("Start/DateTime").GetAsync();
            var pageIterator = PageIterator<Event>.CreatePageIterator(graphClient, eventPage, m =>
            {
                events.Add(m);
                return true;
            });
            await pageIterator.IterateAsync();
        }
    }
    catch (ServiceException e)
    {
        Debug.WriteLine(e.Error.Message);
        return null;
    }

    return events;
}
AuthenticationHelperについては以下の記事をご覧ください。

※ APIのアクセス許可スコープに「Calendars.Read」を追加しておく必要があります。

先ほどと同様にCalendarHelperクラスにユーティリティ的に使えるように静的メソッドとしてGetEventsAsyncメソッドを定義しましょう(先ほどと同名のメソッドですがオーバーロードとして定義しています)。

まず、7行目でユーザー認証を行いGraphServiceClientインスタンスを取得しています。続いて、9-11行目でイベントを取得する期間と「開始/終了」の組み合わせをQueryOption型で作成し、リクエストのオプションで指定できるようにします。なお、Microsoft Graphではタイムゾーンの設定はすべてUTC(世界協定時刻)に変換して保存されているので、ここで引数で受け入れたDateTime型をToUniversalTimeメソッドでUTCに変換しています。

ここで、カレンダーIDが指定されている場合はそのカレンダーから、指定されていない場合はデフォルトカレンダーからイベントを取得するので、カレンダーIDの指定の有無で場合分けして考えてみましょう(13-32行目)。

カレンダーIDが指定されていないときはデフォルトカレンダーからイベントを検索します。この時、予定表全体からではなく指定された時間範囲からイベントを検索する必要があるので、時間範囲で定義された予定表を表すCalendarViewを用いてリクエストを構築しましょう(ICalendarCalendarViewCollectionRequest)。15行目でMeCalendarCalendarViewの3つのRequestBuilderからリクエストを構築し、先ほどのQueryOptionインスタンスをRequestメソッドのオプションに指定してリクエストを完成させます。さらにOrderByメソッドでイベントの開始日時で並べ替えて、GetAsyncメソッドでEvent型のコレクションページを取得しましょう。

await graphClient.Me.Calendar.CalendarView.Request(options).OrderBy("Start/DateTime").GetAsync();

16-21行目でEvent型のコレクションページから一つ一つのEventオブジェクトをリストとして取り出しています。

同様にしてカレンダーIDが指定されている場合の処理も記述していきましょう。25行目でMeCalendarsCalendarViewの3つのRequestBuilderからリクエストを構築します(ICalendarCalendarViewCollectionRequest)。この時、CalendarsIUserCalendarsCollectionRequestBuilder型なので、インデクサでカレンダーIDを指定しましょう。そして、先ほどのQueryOptionインスタンスをRequestメソッドのオプションに指定してリクエストを完成させます。さらにOrderByメソッドでイベントの開始日時で並べ替えて、GetAsyncメソッドでEvent型のコレクションページを取得しましょう。

await graphClient.Me.Calendars[calendarId].CalendarView.Request(options).OrderBy("Start/DateTime").GetAsync();

あとは、先ほどと同様にコレクションページから一つ一つのEventオブジェクトをリストとして取り出します。

なお、指定された期間のイベントの取得方法は以下のドキュメントもご覧ください。

例:期間を指定してイベント一覧を取得する

それではこのGetEventsAsyncメソッドを用いて、予定表から指定された範囲のイベントを取得してみましょう。例として1カ月前から昨日までのイベントを取得します。

DateTime start = DateTime.Today.AddMonths(-1);
DateTime end = DateTime.Today;

List<Event> events = await CalendarHelper.GetEventsAsync(start, end);

string txtEvents = "";
foreach (var ev in events)
{
    txtEvents += ev.Start.DateTime + "\t"  + ev.Subject + Environment.NewLine;
}

ここで期間の設定には少し注意が必要で、C#のDateTime型で「今日の日付」を表すTodayプロパティはその日の0時0分に設定されているので、それを期間の終了日時に設定するとその日自体は含まなくなってしまいます。例えば上記のコードでendに2021/04/08を設定すると、「2021/04/08 00:00までの期間」となってしまうので2021/04/08は含みません。そのために、上記のコードでは2行目で「DateTime.Today」と指定することで、昨日までのイベントを取得することになります。

さらに、Microsoft Graphでは内部的にはUTCで時刻が管理されているのですが、終日イベントと時間イベントで現地時間からUTCに変換するときの挙動が異なるため、上記のコードでは終日イベントが1日分余計に取得されてしまう可能性があることにも注意してください。

関連記事・スポンサーリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)