Go言語で、Google Spreadsheet上のデータを取得する

Googleが公開している`google.golang.org/api/sheets`パッケージを使うと、Go言語からSpreadsheetの内容の読み込みや書き込みを行うことができます。ただし、自分で素直に認証からデータの読み書きまでを一通り書こうとすると、何かと長い実装になってしまうので、ラッパーライブラリ[herschel](https://github.com/yokoe/herschel)を使って、もっと手軽にSpreadsheetの読み書きを可能にする方法を紹介します。まずは、データの読み取りから。

# 前準備
## サービスアカウントの準備
API経由でスプレッドシートにアクセスするには、ユーザアカウントかサービスアカウントを使った認証が必要です。どちらを使って認証するべきかは、ケースによりますが、ここではサービスアカウントを使って認証する場合について記述します。

参考
[Using OAuth 2.0 for Server to Server Applications](https://developers.google.com/identity/protocols/OAuth2ServiceAccount)

### サービスアカウントの作成
[サービスアカウント](https://console.developers.google.com/iam-admin/serviceaccounts)のページを開きます。プロジェクトを選択するように求められるので、プロジェクトを選択します。プロジェクトが存在しない場合は、新しいプロジェクトを作成します。

「サービスアカウントの作成」画面を開き、サービスアカウントを作成します。

<img width="536" alt="Screen Shot 2018-12-02 at 0.47.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/14097/af207f5d-5454-db49-5166-a07ce86d21cb.png">

このサービスアカウントIDは、後ほどスプレッドシートの共有設定で使用します。

オプションの権限の設定は不要なので次に進みます。

<img width="536" alt="Screen Shot 2018-12-02 at 0.49.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/14097/2b97725b-eb70-06ae-47f8-da9768191e28.png">

キーの作成のところで新しいキー(JSON)を作成します。キーを作成するとJSONファイルがダウンロードされます。このJSONファイルは後ほど使用するので、`credentials.json`のようなわかりやすい名前で保存しておいてください。


## テスト用のスプレッドシートの準備
<img width="597" alt="Screen Shot 2018-12-01 at 23.46.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/14097/72966a66-65bd-6e1e-5e69-0d4e6f2b02a9.png">

### 共有設定
上で作成したサービスアカウントが、このスプレッドシートにアクセスできるようにします。
共有設定から、上で作成したサービスアカウントのサービスアカウントIDを追加します。

<img width="597" alt="Screen Shot 2018-12-02 at 0.54.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/14097/824ac449-7663-e311-c5a0-01113d43655f.png">

なお、細かい部分ですが、その際「通知」のチェックを入れた状態で登録をすると、メールを送信できなかった旨のエラーが届くので、外しておきましょう。


### スプレッドシートIDの確認
<img width="746" alt="Screen Shot 2018-12-01 at 23.48.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/14097/0f292250-ef73-18a7-0f7e-6b0760f79684.png">

スプレッドシートのIDは、URLから確認できます。`spreadsheets/d/`から次のスラッシュ(`/`)までの間がスプレッドシートのIDです。

後ほど、ここで確認したIDをコード上に記述します。

# herschelのインストール
```
go get github.com/yokoe/herschel
```

herschelをインストールすると、動作に必要な他のパッケージ(`google.golang.org/api/sheets`など)も自動的にインストールされます。

# データの読み込み

```go:main.go
package main

import (
	"fmt"
	"log"

	"github.com/yokoe/herschel"
	"github.com/yokoe/herschel/option"
)

func main() {
	// サービスアカウントの認証情報を使って、スプレッドシートにアクセスするためのClientを用意します
	client, err := herschel.NewClient(option.WithServiceAccountCredentials("credentials.json"))
	if err != nil {
		log.Fatalf("invalid config or token %s", err)
	}

	// ID「12345678...」のスプレッドシートから「シート1」の内容を読み込みます
	table, err := client.ReadTable("12345678...", "シート1")
	if err != nil {
		log.Fatalf("read error %s", err)
	}

	// 読み込んだ「シート1」のセル(0, 1) (0, 2) (0, 3)の中身を表示します。
	fmt.Println(table.GetStringValue(0, 0))
	fmt.Println(table.GetStringValue(0, 1))
	fmt.Println(table.GetIntValue(0, 2))
}
```

先ほど作成したサービスアカウントの認証情報が含まれるJSONファイルを`credentials.json`としてプログラムから参照できる場所に置いておきます。

```go
client, err := herschel.NewClient(option.WithServiceAccountCredentials("credentials.json"))
```

そのクライアントを使って、スプレッドシート(ID: 12345678...)の「シート1」の中身を読み込みます。

```go
table, err := client.ReadTable("12345678...", "シート1")
```

シートの中身は`Table`という構造体に格納され、`GetStringValue`メソッドを使って値を取り出すことができます。

```go 
table.GetStringValue(0, 0) // 0行目、0列目のセルの中身をStringとして取得する => "Hello"
```

文字列以外のフォーマットで取得したい場合は`GetValue`、`GetIntValue`、`GetInt64Value`などが使えます。

# トラブルシューティング
## Error 403: The caller does not have permission, forbidden が出る
スプレッドシートにサービスアカウントからアクセスできない可能性があります。共有設定で、サービスアカウントが追加されているか確認しましょう。


# まとめ

以上、Herschelを使ってGoからSpreadsheetの中身を読み込む方法を紹介しました。次は書き込みについても紹介しようと思います。


# リンク
* [yokoe/herschel](https://github.com/yokoe/herschel)