Google Calendar APIで祝日を取得する

# 記事の概要
- MavenでGoogle Calendar APIを利用して祝日を取得する方法
- 公式のサンプルコードをいじれば使える
- トークンは定期的にリセット

# 背景
Google Calendar APIは有名なので利用方法はすぐに見つかるが、PHPやPythonばかりで少し手こずったので自分と同じような人のために書く。

# 目的
公式に載っているサンプルコードをMaven向けに書き換えて祝日を取得する。その内容を新卒半年の情弱エンジニアがわかりやすく書く。

# 手順
- [公式サンプル](https://developers.google.com/calendar/quickstart/java) 参考
- 実際に自身でつくってみたリポジトリは[これ](https://github.com/Ikeponias/GoogleCalendarApi)

## 1. Mavenのプロジェクトを作成する([このあたりを参考](https://qiita.com/hide/items/6593f3f02c3f28e57f2d))

- プロジェクト内に`src`フォルダと`pom.xml`ができるはず

``` bash
$ mvn archetype:generate \
  -DarchetypeArtifactId=maven-archetype-quickstart \
  -DinteractiveMode=false \
  -DgroupId={com.ikeponias} \
  -DartifactId={google-calendar-sample}
```

## 2. Credentialファイルをダウンロード
- [公式サンプル](https://developers.google.com/calendar/quickstart/java)のページで

1. "ENABLE GOOGLE CALENDAR API"をクリック

<img width="790" alt="スクリーンショット_2018-11-04_14_09_17.png" src="https://qiita-image-store.s3.amazonaws.com/0/212284/51410245-2665-99ca-f83c-4202977d2df7.png">
2. "Select or create project"をクリック
<img width="577" alt="スクリーンショット_2018-11-04_14_09_54.png" src="https://qiita-image-store.s3.amazonaws.com/0/212284/b3d59967-9f1f-be61-6202-a901c91e04e7.png">
3. すでに存在するプロジェクトを選択するか"Create a new project"を選択してプロジェクト名を入力
4. "DOWNLOAD CLIENT CONFIGURATION"をクリック

<img width="337" alt="スクリーンショット_2018-11-04_14_09_39.png" src="https://qiita-image-store.s3.amazonaws.com/0/212284/ea41ec43-3d32-3e16-4bec-3db010f1e624.png">
5. ダウンロードした`json`ファイルをプロジェクト内の`src/main/resources`フォルダ内に配置（おそらく`resources`フォルダは存在しないので新規作成）
6. 配置した`json`ファイルを`credentials.json`という名前にリネーム

## 3. ソースをコピー

1. `src/main`内の`App.java`ファイルを`CalendarQuickstart.java`へリネーム
2. `CalendarQuickstart.java`へ[公式サンプル](https://developers.google.com/calendar/quickstart/java)の`CalendarQuickstart.java`の中身を丸コピ

## 4. ソースファイルを編集

1. `src/main/CalendarQuickstart.java`の先頭行にパッケージ名を追加（フォルダ階層変更の有無にもよるが、基本的に最初に生成した際のgroupId。自分は`package com.ikeponias;`と追加）
2. `src/main/CalendarQuickstart.java`の`main`メソッド内の`service.events().list()`に渡す引数を`primary`から`japanese__ja@holiday.calendar.google.com`にする(あくまでカレンダーのイベントを取得するAPIなのでこれやらないと自分のイベントが出てくる、[参考](https://gist.github.com/wokamoto/5771b3b0b9b83d2e1642))

<img width="703" alt="スクリーンショット_2018-11-04_14_30_55.png" src="https://qiita-image-store.s3.amazonaws.com/0/212284/988f2868-32c8-8206-614c-3b4bcd84902a.png">

## 5. `pom.xml`を編集
1. 以下の`dependency`を追加

- google-api-client
- google-oauth-client-jetty
- google-api-services-calendar

2. `plugin`に`exec-maven-plugin`を追加

- コマンドラインからmain関数を呼び出すため
- `goal`に`java`を指定
- `mainClass`には`CalendarQuickstart.java`の場所を指定（自分の場合は`com.ikeponias.CalendarQuickstart`）

以下自分の例（junitはプロジェクト生成時に書かれている）

``` xml
  <dependencies>
    <!-- https://mvnrepository.com/artifact/com.google.api-client/google-api-client -->
    <dependency>
      <groupId>com.google.api-client</groupId>
      <artifactId>google-api-client</artifactId>
      <version>1.26.0</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.google.oauth-client/google-oauth-client-jetty -->
    <dependency>
      <groupId>com.google.oauth-client</groupId>
      <artifactId>google-oauth-client-jetty</artifactId>
      <version>1.26.0</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.google.apis/google-api-services-calendar -->
    <dependency>
      <groupId>com.google.apis</groupId>
      <artifactId>google-api-services-calendar</artifactId>
      <version>v3-rev355-1.25.0</version>
    </dependency>

    <!-- プロジェクト生成時にすでに存在するはず -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <!-- https://mvnrepository.com/artifact/org.codehaus.mojo/exec-maven-plugin -->
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <version>1.6.0</version>
        <executions>
          <execution>
            <goals>
              <goal>java</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <mainClass>com.ikeponias.CalendarQuickstart</mainClass>
        </configuration>
      </plugin>
    </plugins>
  </build>
```

## 6. 実行する
1. ターミナルで`mvn clean install`を実行
2. `mvn exec:java`を実行
3. 実行日以降の祝日の一覧が10件出力される（詳しくはソースや公式ドキュメントを読むこと）

 <img width="310" alt="スクリーンショット 2018-11-04 14.53.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/212284/1941d833-2039-7527-ff8e-2a92a8e58f51.png">
4. 以降ソースの変更を反映する場合は`mvn compile`を行ってから`mvn exec:java`を実行

# ハマった点
以下自分がハマった点を書く
## `401 Unauthorized Error`がでる
`com.google.api.client.auth.oauth2.TokenResponseException: 401 Unauthorized`
### 理由
トークンの有効期限が切れているため
### 対策
`tokens`フォルダを削除して再実行（実行時に`tokens`フォルダを削除する処理を入れておくと良いかも）

## `No upcoming events found.`でイベントが見つからない
### 理由
`src/main/CalendarQuickstart.java`の`main`メソッド内の`service.events().list()`に渡す引数が`primary`になっている
### 対策
`primary`を`japanese__ja@holiday.calendar.google.com`にする