[*Ruby*] RubyでGoogle Drive APIを使ってファイル一覧取得＆ファイルアップロード

# はじめに
「[*Rubyによるクローラー開発技法*](http://www.amazon.co.jp/Ruby%E3%81%AB%E3%82%88%E3%82%8B%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%A9%E3%83%BC%E9%96%8B%E7%99%BA%E6%8A%80%E6%B3%95-%E5%B7%A1%E5%9B%9E%E3%83%BB%E8%A7%A3%E6%9E%90%E6%A9%9F%E8%83%BD%E3%81%AE%E5%AE%9F%E8%A3%85%E3%81%A821%E3%81%AE%E9%81%8B%E7%94%A8%E4%BE%8B-%E3%82%8B%E3%81%B3%E3%81%8D%E3%81%A1/dp/4797380357/ref=sr_1_1?s=books&ie=UTF8&qid=1422921103&sr=1-1&keywords=ruby+%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%A9%E3%83%BC)」を読み終わって、クローラーを作ってみたくなりました。（まだ作ってません）
好きなジャンルの画像を集めてくれるものを作ろうと思ったものの、ローカルに画像がたまると嫌なのでよく使うGoogle Driveに上げといて欲しいと思って調べてみたらAPIがあるみたいなので使ってみました。

### 環境
* MacBook Air（Yosemite）
* Ruby（2.1.2）

# 手順

### 1. Google Developers Consoleでプロジェクト作成とクライアントIDなどの取得
[*Google Developers Console*](https://console.developers.google.com/project)にアクセスし、「プロジェクトを作成」を押下します。
![スクリーンショット 2015-02-03 19.54.20.png](https://qiita-image-store.s3.amazonaws.com/0/48912/a027567f-067c-063d-939e-e829398d7ba7.png)

「プロジェクト名」に好きな名前を付けます。
「プロジェクトID」はそのままでも大丈夫です。
![スクリーンショット 2015-02-03 19.54.55.png](https://qiita-image-store.s3.amazonaws.com/0/48912/d63689d7-5afc-0e8c-3b45-36eaf165d535.png)

APIと認証　＞　API　を選択し、有効なAPIが以下のようになるようにします。
デフォルトでは「Drive API」と「Drive SDK」がOFFになっているのでONにします。
![スクリーンショット 2015-02-03 19.56.51.png](https://qiita-image-store.s3.amazonaws.com/0/48912/ab95666d-c899-3beb-a172-fbeea45b28ca.png)

APIと認証　＞　認証情報　を選択し、「新しいクライアントIDを作成」を押下します。
![スクリーンショット 2015-02-03 19.57.18.png](https://qiita-image-store.s3.amazonaws.com/0/48912/292e4b5c-37e0-19d9-6afa-c698ec5fad3b.png)

「インストールされているアプリケーション」を選択し、「同意画面を設定」をクリックします。
![スクリーンショット 2015-02-03 19.57.44.png](https://qiita-image-store.s3.amazonaws.com/0/48912/e5273b9d-386d-1703-bcac-f8ee4b40b1b7.png)

「メールアドレス」を選択し、「サービス名」を入力して「保存」を押します。
![スクリーンショット 2015-02-03 19.58.17.png](https://qiita-image-store.s3.amazonaws.com/0/48912/3c522a7b-8326-592f-8118-148aa74154c0.png)

「インストールされているアプリケーション」を選択し、「その他」を選択して「クライアントIDを作成」をクリックします。
![スクリーンショット 2015-02-03 19.58.41.png](https://qiita-image-store.s3.amazonaws.com/0/48912/06768d07-ef99-4f80-ac43-d5ee3857515e.png)

するとこのようにクライアントIDなどが作成されます。
![スクリーンショット 2015-02-03 19.59.13.png](https://qiita-image-store.s3.amazonaws.com/0/48912/d2865d8a-f09c-ac3e-2859-4f7c8019f52f.png)

以下の手順ではこの値を使用していきます。

```bash
[クライアントID]
127036428910-2cihomq21p413jtu4ebmf4kvefi8v9p1.apps.googleusercontent.com

[クライアントシークレット]
2KR6kOI2hOs0QSKqqltrkyfi

[リダイレクトURI]
http://localhost
```


### 2. Authorization Codeの取得

以下のURLの「クライアントID」と「リダイレクトURI」にさっきGoogle Developers Consoleで取得した情報と置き換えます。

```bash
https://accounts.google.com/o/oauth2/auth
?client_id=クライアントID
&redirect_uri=リダイレクトURI
&scope=https://www.googleapis.com/auth/drive
&response_type=code
```

私の場合だと以下のような感じになります。

```bash
https://accounts.google.com/o/oauth2/auth
?client_id=127036428910-2cihomq21p413jtu4ebmf4kvefi8v9p1.apps.googleusercontent.com
&redirect_uri=http://localhost
&scope=https://www.googleapis.com/auth/drive
&response_type=code
```

ブラウザを立ち上げて、上記のURLを貼り付けてエンターを押します。
![スクリーンショット 2015-02-03 20.06.46.png](https://qiita-image-store.s3.amazonaws.com/0/48912/c854643b-ee2f-f1f6-fbda-87085fc80336.png)

するとアカウントのログインを求められるので、アクセスしたいGoogle Driveのアカウントでログインします。
下のような画面になるので「承認する」をクリックします。
![スクリーンショット 2015-02-03 20.07.34.png](https://qiita-image-store.s3.amazonaws.com/0/48912/eff07198-7720-d888-2a8f-e97baec73b7d.png)

ページが開けないと出ます。
![スクリーンショット 2015-02-03 20.07.55.png](https://qiita-image-store.s3.amazonaws.com/0/48912/9ec8adf9-e0b2-453d-c7b0-b32aa35f8c45.png)

このページのアドレスバーからURLをコピーします。
![スクリーンショット 2015-02-03 20.08.07.png](https://qiita-image-store.s3.amazonaws.com/0/48912/68902e33-0f9c-458f-8f5e-d91028c7f4f0.png)

コピーしたURLはこんな感じです。
このURLの「4/oIZC2ivBC4zV5subNiN6bou8uowe0Ix9L9TB5jDKUKs.IgN5uoclywkaBrG_bnfDxpI4cUOelgI」の部分をこの先で使います。

```bash
http://localhost/?code=4/oIZC2ivBC4zV5subNiN6bou8uowe0Ix9L9TB5jDKUKs.IgN5uoclywkaBrG_bnfDxpI4cUOelgI
```

### 3. アクセストークンの取得

以下の[]で囲んだ部分を自分の情報に書き換えます。

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

私の場合だと以下のような感じになります。

```bash
curl -d client_id=127036428910-2cihomq21p413jtu4ebmf4kvefi8v9p1.apps.googleusercontent.com -d client_secret=2KR6kOI2hOs0QSKqqltrkyfi -d redirect_uri=http://localhost -d grant_type=authorization_code -d code=4/oIZC2ivBC4zV5subNiN6bou8uowe0Ix9L9TB5jDKUKs.IgN5uoclywkaBrG_bnfDxpI4cUOelgI https://accounts.google.com/o/oauth2/token
```

上記をターミナルで実行すると、以下の様なものが返ってきます。
一番下のがリフレッシュトークンです。

```bash
{
  "access_token" : "ya29.DwGisAjZTMSJH6biEjydYXIp6JaXRmYnh21CrW09XpSZzbyRtlg9xmONE1TD7tDDawQgpTjHgZD0kA",
  "token_type" : "Bearer",
  "expires_in" : 3600,
  "refresh_token" : "1/djoROZFMLKPHygvCqtREUAnF7ddeG-3mtXagaXwXAUg"
}
```

以下のようなのが出た場合はなにか指定が間違ってます。

```bash
{
  "error" : "invalid_grant"
}
```

以下のようなのが出た場合は2.のAuthorization Codeの取得のURLをもう一回ブラウザに貼り付けて認証してください。値が変わっているはずです。新しい値を取得してからcurlコマンドを書き換えてもう一回ターミナルで実行してください。

```bash
{
  "error" : "invalid_grant",
  "error_description" : "Code was already redeemed."
}
```

### 4. リフレッシュトークンからアクセストークンの再取得

アクセストークンには有効期限があるらしく、期限が切れた場合はリフレッシュトークンからアクセストークンの再取得が必要らしいです。

以下の[]の部分を自分の情報に書き換えます。

```bash
curl -d client_id=[クライアントID] -d client_secret=[クライアントシークレット] -d refresh_token=[リフレッシュトークン] -d grant_type=refresh_token https://accounts.google.com/o/oauth2/token
```

私の場合以下の様な感じになります。
これをまたターミナルで実行します。

```bash
curl -d client_id=127036428910-2cihomq21p413jtu4ebmf4kvefi8v9p1.apps.googleusercontent.com -d client_secret=2KR6kOI2hOs0QSKqqltrkyfi -d refresh_token=1/djoROZFMLKPHygvCqtREUAnF7ddeG-3mtXagaXwXAUg -d grant_type=refresh_token https://accounts.google.com/o/oauth2/token
```

するとこんなのが返ってきます。
これでやっとRuby側からGoogleDriveにアクセスできます。

```bash
{
  "access_token" : "ya29.DwHCrzGUsuzSUnFUKCHUugHXh3lTbYuBkn0fHk4lA33zxdGiFxT8palk5rvmR4PYlGqhlfFsRWzTBA",
  "token_type" : "Bearer",
  "expires_in" : 3600
}
```

### 5. RubyでGoogle Driveにアクセス

まず以下を実行してgemをインストールします。

```bash
$ gem install google_drive
```

以下の様なコードを書きます。

```rb:google-api-get-list.rb
require 'google/api_client'
require 'google_drive'

CLIENT_ID = "127036428910-2cihomq21p413jtu4ebmf4kvefi8v9p1.apps.googleusercontent.com"
CLIENT_SECRET = "2KR6kOI2hOs0QSKqqltrkyfi"
REFRESH_TOKEN = "ya29.DwHCrzGUsuzSUnFUKCHUugHXh3lTbYuBkn0fHk4lA33zxdGiFxT8palk5rvmR4PYlGqhlfFsRWzTBA"

client = OAuth2::Client.new(
	CLIENT_ID, CLIENT_SECRET,
	:site => "https://accounts.google.com",
	:token_url => "/o/oauth2/token",
	:authorize_url => "/o/oauth2/auth"
)

auth_token = OAuth2::AccessToken.from_hash(client, { :refresh_token => REFRESH_TOKEN, :expires_at => 3600 })
auth_token = auth_token.refresh!

session = GoogleDrive.login_with_oauth(auth_token.token)

for file in session.files
	puts file.title
end
```

ターミナルで実行してみると、こんなかんじにGoogle Driveにあるファイルのリストが出ます。

```bash
$ ruby google-api-get-list.rb
IMG_0456.JPG
IMG_0454.JPG
IMG_0455.JPG
IMG_0451.JPG
(省略)
```

以下の部分を

```rb:google-api-get-list.rb
for file in session.files
	puts file.title
end
```

こんな風に書き換えて実行すると、Google Driveに作ったファイルがアップロードされます。

```rb:google-api-get-list.rb
file_name = "Test" + Time.now.strftime('%Y-%m-%d_%H:%M:%S') + ".txt"
file = File.open(file_name, 'w')
file.puts("Test Upload!!")
file.close

session.upload_from_file(file_name, file_name, :convert => false)
```

# まとめ

このような感じで、RubyでGoogle Driveにアクセスできるようになりました。
現状「やったー動いたー！」な状態なため、細かい部分は調べれてないです。
これから調べます。

＊説明で使っているクライアントIDなどは削除済みです。

# 参考サイト

* [*RubyでGoogleDrive APIを使用するためにアクセストークンを取得する*](http://tagamidaiki.com/ruby-google-drive-api-accesstoken/)
* [*gimite/google-drive-ruby*](https://github.com/gimite/google-drive-ruby)
* [*Using OAuth 2.0 to Access Google APIs*](https://developers.google.com/accounts/docs/OAuth2?hl=ja#serviceaccount)