Inboxのリマインダーをエクスポートする

本日Googleが、Inbox by Gmailのクローズを発表しました。
これまで毎日お世話になってきたのですが、今後アップデートされないならGmailに移行するしかないかなと思っています。

Inboxにはいくつかの独自機能があり、その中のリマインダー（Google Reminders）は、後継のサービスであるGoogle ToDoに**データが移行されません**。
エクスポートしようにも、**APIも用意されていない**ので困ってしまいました。。

色々試した結果、Google Calendarの通信を解析し、GoogleのクローズドAPIを使用することでデータのエクスポートが可能だったのでやり方をまとめます。


### ポイント

- https://inbox.google.com/ が使用するAPIのエンドポイントは `https://inbox.google.com/sync/u/0/i/bv` というような独特の形式だったので、オープンAPIに近い形式の**Google CalendarのAPIを使用**
- 認証情報はブラウザーでログインしているものをそのまま使うと簡単
- タイムスタンプは**ミリ秒の単位**で表記


# Google Calendarが使うクローズドAPI

Googleカレンダーを開き「マイカレンダー」の中の「リマインダー」にチェックを入れ、まずはリマインダーを表示させます。

Chromeデベロッパーツールの「Network」タブを開くと、沢山の通信が行われていますので、検索ポックスに「**reminders/list**」と入力すると該当の通信を見つけられます。

<img width="752" alt="スクリーンショット 2018-09-13 18.54.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/70109/2782b2e6-6aa6-3843-577d-81e5eea8b1ba.png">

`list?key=XXX` というような名前の通信を見つけて、右クリックし、「Copy」、「Copy as cURL」とメニューをクリックしていくことで、cURL用のコマンドがコピーできます。

これには、Cookieなど認証情報も含まれていますので、そのままペーストすればCLIで認証に悩まされず済みます。

以下のようなコマンドがコピーされるはずです（ユーザーごとに違う値は `XXX` に置き換え）。

```sh
curl 'https://reminders-pa.clients6.google.com/v1internalOP/reminders/list?key=XXX' \
-H 'cookie: SID=XXX; HSID=XXX; SSID=XXX; APISID=XXX; SAPISID=XXX; NID=XXX; 1P_JAR=XXX; SIDCC=XXX' \
-H 'origin: https://reminders-pa.clients6.google.com' \
-H 'accept-encoding: gzip, deflate, br' \
-H 'x-origin: https://calendar.google.com' \
-H 'accept-language: XXX' \
-H 'authorization: SAPISIDHASH XXX' \
-H 'x-requested-with: XMLHttpRequest' \
-H 'x-client-data: XXX' \
-H 'x-goog-authuser: XXX' \
-H 'pragma: no-cache' \
-H 'x-clientdetails: appVersion=XXX&platform=XXX&userAgent=XXX' \
-H 'x-goog-encode-response-if-executable: base64' \
-H 'user-agent: XXX' \
-H 'content-type: application/json+protobuf' \
-H 'accept: */*' \
-H 'cache-control: no-cache' \
-H 'authority: reminders-pa.clients6.google.com' \
-H 'referer: https://reminders-pa.clients6.google.com/static/proxy.html?usegapi=XXX&jsh=XXX' \
-H 'x-javascript-user-agent: google-api-javascript-client/1.1.0' \
-H 'x-referer: https://calendar.google.com' \
--data-binary '{"1":{"4":"WRP / /WebCalendar/calendar_180906.14_p2"},"2":[{"1":3},{"1":16},{"1":1},{"1":8},{"1":11},{"1":5},{"1":6},{"1":13},{"1":4},{"1":12},{"1":7},{"1":17}],"5":0,"6":100,"16":"XXX"}' \
--compressed
```

リクエストの内容は `--data-binary` のJSONに記述されていることがわかります。


# リクエスト内容の詳細

リクエストのJSONを整形して見てみましょう。

```json
{
  "1": {
    "4": "WRP / /WebCalendar/calendar_180906.14_p2"
  },
  "2": [
    {
      "1": 3
    },
    {
      "1": 16
    },
    {
      "1": 1
    },
    {
      "1": 8
    },
    {
      "1": 11
    },
    {
      "1": 5
    },
    {
      "1": 6
    },
    {
      "1": 13
    },
    {
      "1": 4
    },
    {
      "1": 12
    },
    {
      "1": 7
    },
    {
      "1": 17
    }
  ],
  "5": 0,
  "6": 100,
  "16": "1514732400000"
}
```

数字で表記されているため意味不明ですが、推測しながら検証してみた結果、以下のような意味でした。
14、24、25はリマインダーのステータスが完了の場合に使用します。

ちなみに、このような数字で表記されているのは**Protocol Bufferで実装されたAPI**だからだと予想されます。


| | 意味 | 必須 | デフォルト |
|:--:|:--:|:--:|:--:|
| 1 | リクエスト元の情報 | False |
| 2 | 取得するデータ | False |
| 5 | リマインダーのステータス（0：未完了のみ／1：完了も含める） | False | 0 |
| 6 | 取得最大件数 | False | 100 |
| 14 | 不明 | False |
| 16 | 範囲指定（終了日時） | False | すべて |
| 24 | 範囲指定（終了日時） | False | すべて |
| 25 | 範囲指定（開始日時） | False | すべて |


# 実際のリクエスト

実際のリクエストとしてオススメは、以下の形です。
**省略した部分はブラウザーからコピーしたままを使用**してください。

```sh
curl --data-binary '{"5": 1, "6": 10000}' \
> reminders.json
```


# おまけ

エクスポートしたデータを `jq` などで整形すると必要なデータだけ取り出せて便利です。
例えば、リマインダーの内容だけを抜き出すには以下のようにします。

```sh
cat reminders.json | jq '.["1"][]["3"]'
```