Google DocsにAPI経由でアクセスする(準備編その1)

# 概要
Google DocsにAPI経由でアクセスする方法を説明します。
API経由でアクセスできると、フォーマットに従ったドキュメントファイルがプログラムで自動で生成できるようになって便利です。
まずは、準備について解説します。

ポイントは

- codeをもらうのは、手動でよい。一回だけやればよい。
- アクセストークン、リフレッシュトークン入りのJSONを取得する（初回のみ）
- リフレッシュトークンを使って、有効期限を3600秒延長する（ここをアプリで繰り返す）


# 前提
- Googleアカウントが必要です。

# Googleの開発者サイトに登録

- https://developers.google.com/ にアクセス
- 歯車マークから「Create Google Developer Profile」をクリック
- 名前を入れて「Next」
- メルマガを受け取る場合はチェックをいれて、「Finish」
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142577/eaee5398-67da-d5cc-c16c-7b15846faf3d.jpeg" width="300px">



# Google Cloud Platformでプロジェクトを作成
- 上部メニューから、プロジェクトを作成
  - プロジェクト名を指定。api-test-1とした。
  - プロジェクトIDが付与される。clever-case-123456
  - 「作成」をクリック
- 上記で作成したプロジェクトを開く


# 「OAuth 同意画面」「認証情報」を作成
- Google API コンソール（ https://console.developers.google.com/ ）を開くと、上記の「Google Cloud Platform」に遷移する。
- 左上の三本線のマークから、「APIとサービス」を選択
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142577/141a1b39-3e2d-4929-ede1-db17e5f0bb17.png"  width="300px">




## OAuth 同意画面
- 左メニューの「OAuth 同意画面」をクリック
  - 「User type」を外部にして、「作成」
  - アプリ名、ユーザーサポートメールのアドレス、承認済みドメインに「`bubbleapps.io`」を指定(フロントにBubbleを使う場合)。デベロッパーの連絡先情報のメールアドレスを指定。「保存して次へ」

- 「スコープ」はそのまま、「保存して次へ」
- テストユーザに、自分のメルアドを指定して、「追加」。「保存して次へ」
- 概要が表示されるので、「ダッシュボードに戻る」
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142577/cb866b15-6fee-a1df-0c9a-27923f384543.jpeg" width="300px">



## 認証情報
- 左メニューの「認証情報」をクリック
- 上部メニューの「認証情報を作成」ー「OAuth クライアントID」をクリック。
- アプリケーションの種類に「ウェブ　アプリケーション」を選択し、名前を入力して、
- 「承認済みのリダイレクト URI」は「`http://localhost`」にして、「作成」

- 一覧に上記で作成したウェブクライアントが表示される。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142577/fbc43434-ed16-6f4f-a87f-8fb06cf90e46.png" width="300px">

- 鉛筆マークをクリックすると、`クライアントID`と`クライアントシークレット`が表示される。



# 使用するライブラリを指定

- 「APIとサービス」に戻り、左メニューの「ライブラリ」をクリック
- 「Google Docs API」を検索して、クリックし、「有効にする」をクリック
- 「Google Drive API」を検索して、クリックし、「有効にする」をクリック

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142577/b3d8c796-2c70-8116-6524-fda0e96056f3.png" width="300px">



# 認証のスコープを調べておく

- https://developers.google.com/identity/protocols/oauth2/scopes から検索する。
    - Google Docsは、https://www.googleapis.com/auth/documents
    - Googleドライブは、https://www.googleapis.com/auth/drive


# 認証コードの取得

- 以下のURLにブラウザからアクセスして、認証コードを取得する。

```
https://accounts.google.com/o/oauth2/auth
?client_id=[上記で取得したクライアントID]
&redirect_uri=[上記で設定したリダイレクトURI]
&scope=https://www.googleapis.com/auth/documents (使用したいサービスのスコープ)
&response_type=code (認証をコードとして出力)
&access_type=offline (オフラインでAPIを使用＝リフレッシュキーを発行)
&include_granted_scopes=true
```

例

```
https://accounts.google.com/o/oauth2/auth
?client_id=401234567890-abcdefghijklmnopqrsutvwxyz123456.apps.googleusercontent.com
&redirect_uri=http://localhost
&scope=https://www.googleapis.com/auth/documents%20https://www.googleapis.com/auth/drive
&response_type=code
&access_type=offline
&include_granted_scopes=true

```


- 2回目以降は、以下も指定する
    - `approval_prompt=force` 認証をスキップしない
    - `prompt=consent` refresh_tokenの再発行
        - 公式ドキュメントを参照 https://developers.google.com/identity/protocols/oauth2/openid-connect#re-consent
        - `approval_prompt`と`prompt`を同時に指定するとエラーになるので注意




- URLを入れてリターンキーを押すと、「このアプリはGoogleで確認されていません」と出るが、「Continue」
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142577/53bd4cd8-19d2-d9e6-c1a7-3edec33ea35c.png" width="300px">

- 「(アプリ名)への権限の付与」画面が表示されるので、「許可」をクリックする
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142577/4faff5ce-952d-395b-47ad-5c9bc83a8f52.png" width="300px">


- 「選択内容を確認してください」画面が出るので、「許可」
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142577/2f552075-d9ee-0818-d737-3dbd922ca0d8.jpeg" width="300px">


- URLが、`http://localhost?code=4/ABCDEFG-hijklmn&scope=https://www.googleapis.com/auth/documents
` のようになるので、 `code=` から `&scope=`の前までをコピーする。（これが認証コード）
    - codeに`%2F`のようなURLエンコードされた文字列が含まれていたら失敗。

# アクセストークン、リフレッシュトークンの取得

- cURLで、以下のように指定してアクセス。

```
curl -d client_id=[クライアントID] -d client_secret=[クライアントシークレット] -d redirect_uri=[リダイレクトURI] -d grant_type=authorization_code -d code=[認証コード] https://accounts.google.com/o/oauth2/token
```

(https://www.googleapis.com/oauth2/v4/token ではないので注意)

例

```
curl -d client_id=401234567890-abcdefghijklmnopqrsutvwxyz123456.apps.googleusercontent.com -d client_secret=abcdefg1234567 -d redirect_uri=http://localhost -d grant_type=authorization_code -d code=4/ABCDEFG-hijklmn https://accounts.google.com/o/oauth2/token
```


- jsonが返ってくるので、`access_token`, `refresh_token` を保存。

例

```
{
  "access_token": "ya29.abcdefg12345",
  "expires_in": 3599,
  "refresh_token": "1//012345-ABCDE",
  "scope": "https://www.googleapis.com/auth/documents",
  "token_type": "Bearer"
}
```


# アクセストークンの検証（状態を確認）（デバッグ用途）
スコープ不足など、うまくいかない原因が知りたい場合に使用します。

```
curl "https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=[アクセストークン]"
```

- `v3`だと`error_description`だけしか出ませんが、`v1`は`error`と`error_description`の両方が出ます。

- アクセストークンが期限切れの場合、以下のようにエラーになります。

```
{
  "error": "invalid_token",
  "error_description": "Invalid Value"
}
```

- アクセストークンが有効な場合、以下のような情報が返ってきます。

```
{
  "issued_to": "4012345-abcdefghijklmn.apps.googleusercontent.com",
  "audience": "4012345-abcdefghijklmn.apps.googleusercontent.com",
  "scope": "https://www.googleapis.com/auth/documents",
  "expires_in": 3514,
  "access_type": "offline"
}
```

----
以降は、Bubbleでの操作になります。[こちらの記事「(Bubble)Google DocsにAPI経由でアクセスする(準備編その2)」](https://note.com/jansnap/n/n466e853dc5ec) をご覧ください。


# 参考
- OAuth2.0を使用してGoogleAPIにアクセスする
  - https://developers.google.com/identity/protocols/oauth2

- Google API OAuth2.0のアクセストークン&リフレッシュトークン取得手順 2017年2月版
  - https://qiita.com/iwaseasahi/items/2363dc1d246bc06baeae