全く初めてのGoogle Tasks API リスト取得

全くゼロ知識からGoogleTasksAPIを使えるようにしていこうと思う。
わかったことを順々に書いていこうと思う。つまりは開発メモ

-----

# Document&Reference
https://developers.google.com/tasks/v1/reference/tasks/list
とりあえず、色々ググっていたらここにたどり着いた。
`Try it Now`を押すとcurlのコマンドっぽいのが出てくる。
これを叩けばとりあえず自分自身のToDoリストの情報を引っ張ることはできそう。
最終的には第三者の情報を取得したいわけだけど、とりあえず第一歩として自分のリストを取得したいと思う。

```
curl \
  'https://www.googleapis.com/tasks/v1/lists/[TASKLIST]/tasks?key=[YOUR_API_KEY]' \
  --header 'Authorization: Bearer [YOUR_ACCESS_TOKEN]' \
  --header 'Accept: application/json' \
  --compressed
```
ざっとみ、
・TASK_LIST
・YOUR_API_KEY
・YOUR_ACCESS_TOKEN
がわかれば、なんとかなりそう。


# TASK_LIST
TASK_LISTの部分にはおそらくTaskListIDを入れるのだと思う。
まだ確証はないが、ユニークなそれっぽいモノが他に無いので多分そうであろうと思う。

意外とTASK_LISTを調べる方法が検索しても出なくて出てきた情報がこちら。

[Google Tasksのtasklistidの調べ方 by GAS](https://qiita.com/cranpun/items/d04975df3b6cd2e67aa8)

ここに乗っているソース

```
var list = Tasks.Tasklists.list();
list.items.forEach(function(item) {
  Logger.log(item.title + " : " + item.id); 
});
```
を使って調べた。

1.Googleスプレットシートを起動
2.新規シート作成
3.ツール > スクリプトエディッタ
4.リソース > Googleの拡張サービス
5.Tasks APIを有効にする（これをしないとTasksって何？って聞かれて動かない)
6.myFunction() のメソッド内にソースを貼り付け

```
function myFunction() {
  var list = Tasks.Tasklists.list();
  list.items.forEach(function(item) {
    Logger.log(item.title + " : " + item.id); 
  });
}
```
7.実行ボタンを押す
8.表示 > ログ
するとこんなのが出てくる

```
[19-08-16 09:16:59:842 PDT] 本日やる事 : MDgxMAA9NDQ9MDkAMjQ9MjcxMDk9MDAw
[19-08-16 09:16:59:844 PDT] リスト : MDgxMjU9NDQ9MDkAMjQ9MjCXMDA9MJY9MAk9NTA99jA
```
おそらくこのコードをTASK_LIST欄に入れて使えばいいのだろうと思う。



# YOUR_API_KEY & YOUR_ACCESS_TOKEN
次に`API_KEY`&`ACCESS_TOKEN`を調べる。
よく聞く`OAuth2.0`というのを使うらしい。
こちらが、OAuth2.0のドキュメント
https://developers.google.com/tasks/auth?hl=ja
ここに書かれている手順をGoogle翻訳で翻訳すると以下の通り

```
1. アプリケーションを作成するとき、Google API Consoleを使用して登録します。Googleは、クライアントIDやクライアントシークレットなど、後で必要になる情報を提供します。
2. Google APIコンソールでGoogle Tasks APIを有効にします。（APIがAPIコンソールにリストされていない場合は、この手順をスキップしてください。）
3. アプリケーションがユーザーデータにアクセスする必要がある場合、特定のアクセス範囲をGoogleに要求します。
4. Googleはユーザーに同意画面を表示し、ユーザーにデータの一部を要求するためのアプリケーションの承認を求めます。
5. ユーザーが承認すると、Googleはアプリケーションに短命のアクセストークンを提供します。
6. アプリケーションはユーザーデータを要求し、アクセストークンを要求に添付します。
7. Googleは、リクエストとトークンが有効であると判断した場合、リクエストされたデータを返します。
```
とりあえず、
5.でACCESS_TOKENが手に入ることだけはわかる。
API_KEYは1.で登録したときにでも発行されそう。
とりあえず、１つづつ進めていく。

## 1.GoogleAPIConsoleでアプリ登録し`クライアントID`・`クライアントシークレット`を取得
[Google API Console](https://console.developers.google.com/?hl=ja)にアクセス。
ロゴの`GoogleAPIs`のとなりをクリックするとポップアップが出てきてポップアップ内に`新しいプロジェクト`というリンクがあったので押下して新しいプロジェクトを作ってみた。

<img width="716" alt="スクリーンショット 2019-08-17 1.53.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98758/c5ecba30-9db5-b95c-4853-f88fcc417e06.png">

## 2. Google APIコンソールでGoogle Tasks APIを有効にします。
プロジェクトに入ると`APIとサービスの有効化`というリンクがあるので押下。
検索窓が出てきたので、`Task`で検索してみる。

<img width="1017" alt="スクリーンショット 2019-08-17 1.58.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98758/778696f3-e098-b8bc-19e5-c5754706eaf0.png">

`Tasks API`と`Clooud Tasks API`が出てきてどっち選べばいいのか全くわからないが、とりあえず、`Tasks API`を選択し有効化してみた。

有効化すると
**この API を使用するには、認証情報が必要になる可能性があります。開始するには、[認証情報を作成] をクリックしてください。**
というメッセージが出たのでとりあえず、`認証情報を作成`を押下。
<img width="1008" alt="認証.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98758/9be7b5d3-a862-f3e4-aff4-c87f5bfa2932.png">





このように選択。
すると、OAuth同意画面(ユーザの情報にアクセスすることの同意を求める画面)が必要と出てきた。

## 4. Googleはユーザーに同意画面を表示し、ユーザーにデータの一部を要求するためのアプリケーションの承認を求めます。

具体的にどうするのかわからんなと思って進めていくと、フォームが出てきた。
`アプリケーション名`と`画像`だけ登録したらとりあえず、保存ができたので保存する。

その後、`承認情報` > `承認情報を作成`を押すと
<img width="572" alt="スクリーンショット 2019-08-17 2.13.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98758/6273292d-52bc-56a4-bcad-971353a0d70c.png">
・APIキー
・OAuthクライアントID
・クライアントシークレット
はクリックすると発行される。

<img width="536" alt="スクリーンショット 2019-08-17 2.17.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98758/342e1269-603a-6135-a2f2-a9796d5a9d1f.png">
<img width="530" alt="スクリーンショット 2019-08-17 2.18.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98758/625196dd-3367-a5ae-0218-3878ccbba3ca.png">

これで、API_KEYは取得完了。

## 5. ユーザー承認でアクセストークンが提供

最初に必要だった3つの内2つがこの時点で手に入っている。
最後は、ACCESS_TOKENが取得できればなんとかなりそう。

```
5. ユーザーが承認すると、Googleはアプリケーションに短命のアクセストークンを提供します。
```

次は、先ほど取得した
・OAuthクライアントID
・クライアントシークレット
を使ってOAuthを使いACCESS_TOKENを取得していく。

GoogleのOAuthは[Google APIのAccess Tokenをお手軽に取得する](https://qiita.com/shin1ogawa/items/49a076f62e5f17f18fe5)が参考になった。

・OAuthクライアントID
・クライアントシークレット
を使い
・AuthorizationCode
を取得。

・AuthorizationCode
から
・AccessToken
・RefreshToken
を取得できる。`AccessToken`は時間制限があり、時間が経つと再取得する必要がある。
それを手軽にやるために`RefreshToken`がある。



```
CLIENT_ID=OAuthクライアントIDを入力
CLIENT_SECRET=クライアントシークレットを入力
REDIRECT_URI=urn:ietf:wg:oauth:2.0:oob
SCOPE=https://www.googleapis.com/auth/tasks
echo "https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id=$CLIENT_ID&redirect_uri=$REDIRECT_URI&scope=$SCOPE&access_type=offline" 
```
こちらを実行するとURLが取得できるため、
そのURLにアクセスする。

<img width="604" alt="accesskey.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98758/90b1d242-abee-932f-72da-b1835ae33f5f.png">

この恐ろしく説明の足りてない画面に出てくるコードが`Authorization Code`となる。

・AuthorizationCode
を使って、
・AccessToken
・RefreshToken
を取得する。

```
AUTHORIZATION_CODE=先ほどのAuthorizationCodeを入力
curl --data "code=$AUTHORIZATION_CODE" --data "client_id=$CLIENT_ID" --data "client_secret=$CLIENT_SECRET" --data "redirect_uri=$REDIRECT_URI" --data "grant_type=authorization_code" --data "access_type=offline" https://www.googleapis.com/oauth2/v4/token
```
JSON型のデータが戻ってくる

```
{
  "access_token": "ya7tmxsR45A3xfYgGT99998888UuvN_YoFhurgyZ-G4sdzTUh7RHHvDZfzE8888888_haZGK",
  "expires_in": 3600,
  "refresh_token": "9/xfqCw-3lIT6NbBE_99900999joNPgbMGZuZGR_9F4g3",
  "scope": "https://www.googleapis.com/auth/tasks",
  "token_type": "Bearer"
}
```
この中に書かれている
"access_token" 
"refresh_token"
が
・AccessToken
・RefreshToken
になる。

ここまでこれば、必要なものは全て揃ったため、
最初に紹介したドキュメントのcURLを叩くことができる。

# cURLを叩く

https://developers.google.com/tasks/v1/reference/tasks/list

に書かれているcURLのコマンド

```
curl \
  'https://www.googleapis.com/tasks/v1/lists/TaskListIDを入力/tasks?key=API_KEYを入力' \
  --header 'Authorization: Bearer ACCESS_TOKENを入力' \
  --header 'Accept: application/json' \
  --compressed
```
を実行すれば、TaskListないのタスク一覧を取得することができる。

この記事内で仮で書いてある各KEYを入力すると以下のような形

```
curl \
  'https://www.googleapis.com/tasks/v1/lists/MDgxMjU9NDQ9MDkAMjQ9MjCXMDA9MJY9MAk9NTA99jA/tasks?key=AIzaSy' \
  --header 'Authorization: Bearer ya7tmxsR45A3xfYgGT99998888UuvN_YoFhurgyZ-G4sdzTUh7RHHvDZfzE8888888_haZGK' \
  --header 'Accept: application/json' \
  --compressed
```
のようになる。

以下のように登録しているTask一覧が表示されれば成功

```
{
 "kind": "tasks#tasks",
 "etag": "\"8MEupY6AVkDup3m0O6mGjM999999999MTk0Mw\"",
 "items": [
  {
   "kind": "tasks#task",
   "id": "LURodTJ2Z9999RkVfdkIxNQ",
   "etag": "\"8MEupY6AVkD999996mGjMTpTY8/LTU1NzEzNTU1Nw\"",
   "title": "お洗濯",
   "updated": "2019-07-11T02:09:19.000Z",
   "selfLink": "https://www.googleapis.com/tasks/v1/lists/UDZxWW9999VE44RHZ4aw/tasks/LURod0000FVRkVfdkIxNQ",
   "position": "00000000000000000001",
   "status": "needsAction"
  },
  {
   "kind": "tasks#task",
   "id": "aE82OGl6Sj88888GFJOQ",
   "etag": "\"8MEupY6AVkDup3m0O6mGjMT00000099999zYxMA\"",
   "title": "お料理",
   "updated": "2019-07-11T02:09:08.000Z",
   "selfLink": "https://www.googleapis.com/tasks/v1/lists/UDZxWW8za1888888HZ4aw/tasks/aE82OGl6SjEz999OQ",
   "position": "00000000000000000002",
   "status": "needsAction"
  },
  {
   "kind": "tasks#task",
   "id": "dUdycDFRTUY99998888W5PYg",
   "etag": "\"8MEupY6AVkDup3m0O6mGjMTpTY08888882MTM4NA\"",
   "title": "お片づけ",
   "updated": "2019-07-11T02:08:54.000Z",
   "selfLink": "https://www.googleapis.com/tasks/v1/lists/UDZxWW8za1JKVE44RHZ4aw/tasks/dUdycDF0888W5PYg",
   "position": "00000000000000000003",
   "status": "needsAction"
  }
 ]
}
```



# AccessTokenをRefreshTokenから再取得する。

時間が経って使えなくなったら以下のコマンドでAccessTokenを再取得することができる。

```
REFRESH_TOKEN=REFRESH_TOKENを入力
CLIENT_SECRET=CLIENT_SECRETを入力
curl --data "refresh_token=$REFRESH_TOKEN" --data "client_id=$CLIENT_ID" --data "client_secret=$CLIENT_SECRET" --data "grant_type=refresh_token" https://www.googleapis.com/oauth2/v4/token
```