Google Calendar APIを使用してみる #2

#シリーズ
[Google Calendar APIを使用してみる #1](https://qiita.com/GodPhwng/items/4310586e1ec3bda4d91f)
[Google Calendar APIを使用してみる #3](https://qiita.com/GodPhwng/items/4e3b35946a8806fd89d9)

#環境
**IDE**：VisualStudio2019
**アプリケーション**：コンソールアプリ
**フレームワーク**：.NET Core 3.1

#カレンダーに予定を追加
前回は予定取得を試してみました。
今回はカレンダーの予定追加~~／更新~~を行ってみます。

まずわかりやすいように自分のカレンダーの直近の予定を空にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526982/53cdd09e-9726-bce3-48a7-1eae8e9d4c4c.png)

予定を追加するコードを記述します。
以下公式にサンプルがありました。
[Events: insert](https://developers.google.com/calendar/v3/reference/events/insert)

以下のようなスケジュール追加メソッドを用意

```C#
        /// <summary>
        /// カレンダーイベントを追加
        /// </summary>
        /// <param name="calendarId">カレンダーID</param>
        public void InsertEvent(string calendarId)
        {
            var newEvent = new Event()
            {
                Summary = "Google I/O 2020",
                Location = "神奈川県横浜市",
                Description = "テスト備考",
                Start = new EventDateTime()
                {
                    DateTime = DateTime.Parse("2020/02/28 9:00:00"),
                    TimeZone = "Asia/Tokyo",
                },
                End = new EventDateTime()
                {
                    DateTime = DateTime.Parse("2020/02/28 17:00:00"),
                    TimeZone = "Asia/Tokyo",
                },
                
                //以下があるとエラーになっていたのでコメントアウト・・・
                //Recurrence = new string[] { "RRULE:FREQ=DAILY;COUNT=2" },
                //Attendees = new EventAttendee[] {
                //    new EventAttendee() { Email = "lpage@example.com" },
                //    new EventAttendee() { Email = "sbrin@example.com" },
                //},
                //Reminders = new Event.RemindersData()
                //{
                //    UseDefault = false,
                //    Overrides = new EventReminder[] {
                //        new EventReminder() { Method = "email", Minutes = 24 * 60 },
                //        new EventReminder() { Method = "sms", Minutes = 10 },
                //    }
                //}
            };

            var request = this.Serive.Events.Insert(newEvent, calendarId);
            var createdEvent = request.Execute();
            Console.WriteLine("Event created: {0}", createdEvent.HtmlLink);
        }
```

**結果**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526982/5361b4e9-151a-92ec-4bfb-62faf704f513.png)

#サンプル全文
基底クラスを作りました。

```C#
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Newtonsoft.Json.Linq;
using System.IO;

namespace GoogleAPITest
{
    /// <summary>
    /// GoogleAPI利用においての基底クラス
    /// </summary>
    public abstract class GoogleAPIBase<T> where T : IClientService
    {
        /// <summary>
        /// クライアントサービスインターフェース
        /// </summary>
        protected T Serive { get; set; }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="keyJsonPath">APIキーのJSONファイルのパス</param>
        public GoogleAPIBase(string keyJsonPath, string[] scope)
        {
            var jObject = JObject.Parse(File.ReadAllText(keyJsonPath));
            var serviceAccountEmail = jObject["client_email"].ToString();
            var privateKey = jObject["private_key"].ToString();

            var credential = new ServiceAccountCredential(
            new ServiceAccountCredential.Initializer(serviceAccountEmail)
            {
                Scopes = scope
            }.FromPrivateKey(privateKey));

            this.Serive = this.CreateService(credential);
        }

        /// <summary>
        /// サービス作成メソッド
        /// </summary>
        /// <param name="credential">認証情報</param>
        /// <returns>クライアントサービスインターフェース</returns>
        protected abstract T CreateService(ICredential credential);
    }
}
```
カレンダーAPI以外でも使用できるように、サービス作成メソッドを継承先に強制し、サービスの型をジェネリックにしている。

**カレンダーAPIテストクラス**

```C#
using Google.Apis.Auth.OAuth2;
using Google.Apis.Calendar.v3;
using Google.Apis.Calendar.v3.Data;
using Google.Apis.Services;
using System;

namespace GoogleAPITest.Calendar
{
    /// <summary>
    /// カレンダーAPIテストクラス
    /// </summary>
    public class CalendarAPITest : GoogleAPIBase<CalendarService>
    {
        /// <summary>
        /// アプリケーション名
        /// </summary>
        private const string APP_NAME = "Google Calendar API .NET";

        /// <summary>
        /// カレンダーテストクラス
        /// </summary>
        public CalendarAPITest(string keyJsonPath) : base(keyJsonPath, new string[] { CalendarService.Scope.Calendar })
        {
        }

        /// <summary>
        /// クライアントサービス作成
        /// </summary>
        /// <param name="credential">認証情報</param>
        /// <returns>クライアントサービスインターフェース</returns>
        protected override CalendarService CreateService(ICredential credential)
        {
            return new CalendarService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = APP_NAME
            });
        }

        /// <summary>
        /// 予定読み取り
        /// </summary>
        /// <param name="calendarId">カレンダーID</param>
        public void ReadEvents(string calendarId)
        {
            // ここで第2引数にサービスアカウントに公開したカレンダーIDを指定する
            var request = new EventsResource.ListRequest(this.Serive, calendarId);
            request.TimeMin = DateTime.Now;
            request.ShowDeleted = false;
            request.SingleEvents = true;
            request.MaxResults = 10;
            request.OrderBy = EventsResource.ListRequest.OrderByEnum.StartTime;

            // List events.
            var events = request.Execute();
            Console.WriteLine("Upcoming events:");
            if (events.Items != null && events.Items.Count > 0)
            {
                foreach (var eventItem in events.Items)
                {
                    var when = eventItem.Start.DateTime.ToString();
                    if (String.IsNullOrEmpty(when))
                    {
                        when = eventItem.Start.Date;
                    }

                    Console.WriteLine("{0} start：({1}) end：({2})", 
                        eventItem.Summary, when, eventItem.End.DateTime.ToString());
                }
            }
            else
            {
                Console.WriteLine("No upcoming events found.");
            }
        }

        /// <summary>
        /// カレンダーイベントを追加
        /// </summary>
        /// <param name="calendarId">カレンダーID</param>
        public void InsertEvent(string calendarId)
        {
            var newEvent = new Event()
            {
                Summary = "Google I/O 2020",
                Location = "神奈川県横浜市",
                Description = "テスト備考",
                Start = new EventDateTime()
                {
                    DateTime = DateTime.Parse("2020/02/28 9:00:00"),
                    TimeZone = "Asia/Tokyo",
                },
                End = new EventDateTime()
                {
                    DateTime = DateTime.Parse("2020/02/28 17:00:00"),
                    TimeZone = "Asia/Tokyo",
                },
                //Recurrence = new string[] { "RRULE:FREQ=DAILY;COUNT=2" },
                //Attendees = new EventAttendee[] {
                //    new EventAttendee() { Email = "lpage@example.com" },
                //    new EventAttendee() { Email = "sbrin@example.com" },
                //},
                //Reminders = new Event.RemindersData()
                //{
                //    UseDefault = false,
                //    Overrides = new EventReminder[] {
                //        new EventReminder() { Method = "email", Minutes = 24 * 60 },
                //        new EventReminder() { Method = "sms", Minutes = 10 },
                //    }
                //}
            };

            var request = this.Serive.Events.Insert(newEvent, calendarId);
            var createdEvent = request.Execute();
            Console.WriteLine("Event created: {0}", createdEvent.HtmlLink);
        }
    }
}
```
**プログラムメインエントリ**

```C#
using Google.Apis.Auth.OAuth2;
using Google.Apis.Calendar.v3;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using GoogleAPITest.Calendar;
using Newtonsoft.Json.Linq;
using System;
using System.IO;
using System.Threading;

namespace GoogleAPITest
{
    /// <summary>
    /// メインクラス
    /// </summary>
    public class Program
    {
        /// <summary>
        /// メインエントリ
        /// </summary>
        /// <param name="args">実行時引数</param>
        public static void Main(string[] args)
        {
            try
            {
                // カレンダーID
                var calendarId = "カレンダーID";

                // Googleカレンダーテストクラスインスタンス化
                var calApi = new CalendarAPITest(
                    @"C:\job\TestProject\GoogleAPITest\testproject-269217-813bf9be17a5.json");

                // イベント読み取り
                calApi.ReadEvents(calendarId);

                // イベント追加
                calApi.InsertEvent(calendarId);
            }
            catch (Exception err)
            {
                Console.WriteLine(err.Message);
            }
            finally
            {
                Console.Read();
            }
        }
    }
}
```

次回は更新をやってみたいと思います。
[次回](https://qiita.com/GodPhwng/items/4e3b35946a8806fd89d9)