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

#Google Calendar API をちょろっとだけ触ってみたくなった
いろんな分野に目移りしてちょろっと触ってみたくなる悪い癖なんですが
クラウドソーシングの副業を探していたら、Gooogle Calendarに予定を突っ込む／更新する案件があり
なぜかそれきっかけで無性にAPIを呼んでみたくなったので、試してみました。
※ちなみに案件は受けていませんw

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

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

#Google Calendar API 入門
公式に入門がありました。
[Get Started with the Calendar API](https://developers.google.com/calendar/overview?hl=ja)

どうやらAPIを使用するには、認証情報を作成する必要があるようです。
以下3つの方法があるとのことです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526982/b2c14e7e-57fd-3161-f9e7-560125c44468.png)

OAuthクライアントIDを用いる方法では、すぐに認証情報が作成できるのですが、「oauth 同意画面」の設定を行わないとプライベートデータへのアクセスが１００回までと制限されるそうで
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526982/78f87717-aa1e-835b-3ae9-b263449f91e7.png)
また、「oauth 同意画面」の設定が手間そうだったので、「サービス アカウント」を用いる方法を試してみたいと思います。

# サービスアカウントの作成
以下に入力を行い作成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526982/f07653b8-a9c2-c6b8-cbf7-eaa6fe49355b.png)


出来上がったサービスアカウントのリンクをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526982/393caec9-d8c8-5ef6-c74b-3cad5b19a269.png)

キーを作成をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526982/9ae3a87b-c04e-fc30-a072-b937463d40e0.png)

JSONを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526982/5ce36ba2-5efa-f1f2-05f9-f41187119744.png)

ここでダウンロードしたJsonの中身の情報を用いてGoogleAPIを呼び出します。

# クライアントライブラリ使用して予定を取得
Nugetからカレンダー用のDLLをダウンロードしてきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526982/211fbc1a-056b-47a1-343b-617536585726.png)

次に作成したサービスアカウントに操作させたいカレンダーを公開します。
対象のカレンダーの設定から特定のユーザーとの共有にて追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526982/0889cba1-3b8b-027f-39f0-cf61b5ccc011.png)
メールアドレスのところに、サービスアカウントのメールアドレスを入れます。
※ダウンロードしたJSONのclient_emailにもあります。

**サンプルコードの実装**
以下.Netのサンプルが公式にありましたので、そちらを参考にしてみます。
[.Net Sample](https://developers.google.com/calendar/quickstart/dotnet)

とりあえずこぴって、環境に依存するところは変更。
また、サービスアカウントで認証する必要があるので以下を参考にして、credentialを作成するところは書き換えた。
[Google Calendar API ServiceAccountCredential](https://stackoverflow.com/questions/49869032/google-calendar-api-serviceaccountcredential)

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

namespace GoogleAPITest
{
    public class Program
    {
        // If modifying these scopes, delete your previously saved credentials
        // at ~/.credentials/calendar-dotnet-quickstart.json
        private static string[] Scopes = { CalendarService.Scope.CalendarReadonly };
        private static string ApplicationName = "Google Calendar API .NET Quickstart";

        public static void Main(string[] args)
        {
            var jObject = JObject.Parse(File.ReadAllText(
                @"C:\job\TestProject\GoogleAPITest\testproject-269217-813bf9be17a5.json"));
            var serviceAccountEmail = jObject["client_email"].ToString();
            var certificate = jObject["private_key"].ToString();

            var credential = new ServiceAccountCredential(
            new ServiceAccountCredential.Initializer(serviceAccountEmail)
            {
                Scopes = new[] { CalendarService.Scope.Calendar }
            }.FromPrivateKey(certificate));

            // Create Google Calendar API service.
            var service = new CalendarService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = ApplicationName,
            });

            // おそらく不必要
            // Define parameters of request.
            //var request = service.Events.List("primary");
            //request.TimeMin = DateTime.Now;
            //request.ShowDeleted = false;
            //request.SingleEvents = true;
            //request.MaxResults = 10;
            //request.OrderBy = EventsResource.ListRequest.OrderByEnum.StartTime;

            // ここで第2引数にサービスアカウントに公開したカレンダーIDを指定する
            var request = new EventsResource.ListRequest(service, "公開したカレンダーのカレンダーID");

            // List events.
            var events = request.Execute();
            Console.WriteLine("Upcoming events:");
            if (events.Items != null && events.Items.Count > 0)
            {
                foreach (var eventItem in events.Items)
                {
                    string 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.");
            }

            Console.Read();
        }
    }
}
```

**公開したカレンダーの直近**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526982/23497453-f56a-dc3d-d8c1-f2d4e13d83eb.png)


**実行結果**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526982/bb55eeff-2b3c-3a5c-f5f8-c55b791e5220.png)


正常に取得できているようです。(昔のイベントは無視で・・・)


今回はここまでにします。
次回はカレンダー更新をやってみようと思います。
[次回](https://qiita.com/GodPhwng/items/f0abc7b7ca312b4ce6fd)