[Gmail API] Javaでメールボックスのプッシュ通知を開始・更新・停止する

Gmail API v1（Java）を使用して、
Gmailメールボックスのプッシュ通知を開始・更新・停止する方法
についてご紹介します。

Gmailのプッシュ通知はPub/SubというGCPのサービスを利用します。

:::note info
Pub/Sub、Cloud Functionsの準備や設定に関してましては、
[⧉[Pub/Sub - Cloud Functions] Google Cloud APIからの通知を受け取る](https://qiita.com/doran/items/343dac28c46143d61917)
を参照ください。
:::
:::note info
APIを利用する環境の準備から始める場合や、コードを実行する際は、
[⧉[Gmail API] JavaでGmail APIを使う](https://qiita.com/doran/items/a078e966bfd93c4b19c2)
を参照ください。
:::

本文中の引数にある「メールアドレス」の指定は、
OAuth 2.0使用の場合は「me」（自身）と指定してください。
「me」は認証されたユーザーを示します。

|No||目次|
|---|---|---|
|1||[プッシュ通知を開始・更新](#1-プッシュ通知を開始更新)|
||1|[スコープ](#11-スコープ)|
||2|[実行](#12-実行)|
||3|[レスポンスの内容](#13-レスポンスの内容)|
|2||[プッシュ通知を停止](#2-プッシュ通知を停止)|
||1|[スコープ](#21-スコープ)|
||2|[実行](#22-実行)|
||3|[レスポンスの内容](#23-レスポンスの内容)|
|3||[プッシュ通知の内容](#3-プッシュ通知の内容)|
||1|[変更通知の受信](#31-変更通知の受信)|
||2|[変更内容の取得](#32-変更内容の取得)|

## 1. プッシュ通知を開始・更新
プッシュ通知を開始します。
既に登録済みである場合は更新されます。

### 1.1. スコープ
このAPIを実行するには、以下のいずれかのスコープを指定してください。
```
GmailScopes.MAIL_GOOGLE_COM
GmailScopes.GMAIL_MODIFY
GmailScopes.GMAIL_READONLY
GmailScopes.GMAIL_METADATA
```
[⧉[Gmail API] JavaでGmail APIを使う(2.2 Gmailインスタンスを取得)](https://qiita.com/doran/items/a078e966bfd93c4b19c2#22-gmailインスタンスを取得)
でスコープを指定してください。

### 1.2. 実行
```java
public static void main(String[] args) throws Exception{
    Gmail gmail = getGmail();
    Gmail.Users users = gmail.users();
    
    WatchRequest content = new WatchRequest();
    content.setTopicName("トピックの名前");
    Gmail.Users.Watch watch = users.watch("メールアドレス",content);

    WatchResponse res = watch.execute();
    System.out.println(res);
}
```
#### 1.2.1. HTTPリクエスト
POST:　https:\//gmail.googleapis.com/gmail/v1/users/{メールアドレス}/watch
が実行されます。

#### 1.2.2. クエリパラメータ
クエリパラメータはありません。

#### 1.2.3. リクエストボディ
WatchRequestのsetメソッドにより、リクエストボディを追加できます。

|メソッド|引数|説明|
|---|---|---|
|setLabelIds|List\<String\>|通知を制限するラベルのリスト<br><br>ラベルについては、<br>[⧉[Gmail API] Javaでメールボックス内のラベルを取得する](https://qiita.com/doran/items/859f752a4bdf35167873)<br>を参照ください。|
|setLabelFilterBehavior|[LabelFilterAction(enum)](#labelfilteraction)|プッシュ通知のフィルタリング|
|setTopicName|String|GoogleCloud Pub/Sub APIのトピック名|

#### LabelFilterAction
|定義値|説明|
|---|---|
|include|指定したラベルに関連するメッセージの変更についてのみを受信|
|exclude|指定したラベルに関連するものを除く、すべてのメッセージの変更を受信|

### 1.3. レスポンスの内容
#### WatchResponse

|メソッド|戻り値|説明|
|---|---|---|
|getHistoryId|String|履歴ID|
|getExpiration|Long|更新通知の送信を停止する時間（エポックミリ秒）<br>この時間を超えると監視を停止します|

## 2. プッシュ通知を停止
プッシュ通知を停止します。

### 2.1. スコープ
このAPIを実行するには、以下のいずれかのスコープを指定してください。
```
GmailScopes.MAIL_GOOGLE_COM
GmailScopes.GMAIL_MODIFY
GmailScopes.GMAIL_READONLY
GmailScopes.GMAIL_METADATA
```
[⧉[Gmail API] JavaでGmail APIを使う(2.2 Gmailインスタンスを取得)](https://qiita.com/doran/items/a078e966bfd93c4b19c2#22-gmailインスタンスを取得)
でスコープを指定してください。

### 2.2. 実行
```java
public static void main(String[] args) throws Exception{
    Gmail gmail = getGmail();
    Gmail.Users users = gmail.users();

    Gmail.Users.Stop watch = users.stop("メールアドレス");
    
    watch.execute();
}
```
#### 2.2.1. HTTPリクエスト
POST:　https:\//gmail.googleapis.com/gmail/v1/users/{メールアドレス}/stop
が実行されます。

#### 2.2.2. クエリパラメータ
クエリパラメータはありません。

#### 2.2.3. リクエストボディ
リクエストボディはありません。

### 2.3. レスポンスの内容
レスポンスはありません。

## 3. プッシュ通知の内容
プッシュ通知は、Google PUB/SUBを使用して受信します。
PUB/SUBからPUSH先にURIを指定しますが、
今回はプッシュ通知の内容を見るだけなのでCloud Functionsを使用します。

Pub/SubとCloud Functionsを使用したメッセージの受信する方法は
[⧉[Pub/Sub - Cloud Functions] Google Cloud APIからの通知を受け取る](https://qiita.com/doran/items/343dac28c46143d61917)
を参照ください。

Gmail APIからの通知を受信するには、トピックの権限に下記を追加してください。
追加方法は、上記記事の[⧉1.3. 権限の設定](https://qiita.com/doran/items/343dac28c46143d61917#13-権限の設定)をご覧ください。
|設定|設定値|
|---|---|
|プリンシバル|`gmail-api-push@system.gserviceaccount.com`|
|ロール|`Pub/Sub パブリッシャー`|

#### 3.1. 変更通知の受信
プッシュ通知で次のフィールドが取得できます。
<img width=420 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/47d23934-e858-53f3-50bd-72aefa5a1ddb.png">

|フィールド|説明|
|---|---|
|emailAddress|メールアドレス|
|historyId|履歴ID|

#### 3.2. 変更内容の取得
[3.1. 変更通知の受信](#31-変更通知の受信)で取得した履歴IDを使用し変更内容を取得します。

変更履歴の取得方法は、
[⧉[Gmail API] Javaでメールボックスの変更履歴一覧を取得する](https://qiita.com/doran/items/74da36f79d19dad20164)
を参照ください。

<br>
<br>
おしまい。。