スプレッドシートのデータを取得する
slack botでスプレッドシートからデータ取得する場面があったので調査して検証がてらgolangで実装してみた。
気をつける所とかメモ的に書いておく。
作ったのはスプレッドシートで重み付け抽選を行うアプリ。
認証
認証方法はAPIキー、OAuth、サービスアカウントの3つがある。
APIキー
公開されたスプレッドシートしか読み込めないようだったので今回はパス。
OAuthクライアントID
一度ユーザがブラウザを開いて認証する必要がある。
bot用には使えないなーと思ったのでパス。
サービスアカウント
新しくGoogleアカウントを発行するイメージ。
スプレッドシートに招待して使う。
招待してしまえばずっと使えるためbotには合っていると思い、今回はサービスアカウントを使用することにした。
使用方法
発行したjsonキーファイルの中から client_email
を取り出す。
$ cat /path/to/key.json | jq -r .client_email test@quickstart-1551059800000.iam.gserviceaccount.com
データを取得したいスプレッドシートに移動して右上の共有ボタンをクリック。
『他のユーザと共有』ダイアログを開き、先程取得した client_email
を追加する。
実装
実装側の認証には google.JWTConfigFromJSON
を使う。
キーjsonファイルの中身とスコープ(今回は取得なのでreadonly)を渡す。
conf, err := google.JWTConfigFromJSON( jsonKeyBytes, "https://www.googleapis.com/auth/spreadsheets.readonly" )
返ってきた conf
からhttpクライアントを取得し、 sheets.New
に渡して Service
を取得する。
srv, err := sheets.New(conf.Client(ctx))
あとは取得したサービスを使ってGetすればいい。
スプレッドシートIDと取得するデータのレンジ(下記の例では A2:B
)を指定する。
( A2:B
はA2セルからB列の最後のセルまでという意味)
resp, err := srv.Spreadsheets.Values.Get(spreadsheetID, "A2:B").Context(ctx).Do() var items []lotteryItem for _, row := range resp.Values { name := row[0].(string) weight, err := strconv.Atoi(row[1].(string)) items = append(items, lotteryItem{name: name, weight: weight}) }
※エラーハンドリングは省略してあります。
列方向への取得
デフォルトでは行方向の取得になるが、列方向に取得したい場合は MajorDimension
に COLUMNS
を指定すればよい。
resp, err := srv.Spreadsheets.Values.Get(spreadsheetID, "A2:B").Context(ctx).MajorDimension("COLUMNS").Do()