ScalaでGoogle Spreadsheetに書き込んでみたメモです。
概要
先日Asanaからデータを取り出してCSVを生成するツールを書いた。
CSVにできたのでこれを今度はGoogle Spreadsheetに自動転記したいと思い、試行錯誤していたところ、Java SDKを使って任意のシートの任意のRangeを書き換えられたのでメモ。
とその前に、設定ファイルまわりちゃんとしておく
外部アプリケーションとの連携ではトークンやら設定やらが沢山登場する。でも、ハードコードはしたくないので、HOCONで設定できるようにした。
めちゃくちゃ簡単に使えるので、とにかくこれでいいやという感じ。
例によってsbtに依存性を書き込む。
libraryDependencies += "com.typesafe" % "config" % "1.4.1"
アプリケーションから呼び出すためのインターフェイスを用意しておく。
package exporter import com.typesafe.config.ConfigFactory object Config { lazy val config = ConfigFactory.load() }
あとはimport Config.config
しておけばいつでもconfig.getString("hoge")
みたいなことができる。
SDKをインストールする
ありがたいことにGoogle SpreadsheetはJavaから操作できるインターフェイスを備えている。ScalaのSDKは存在していないようなので、これを操作することにした。
sbtに依存関係を書き込み、インストールする。
lazy val googleApiClient = "com.google.api-client" % "google-api-client" % "1.30.4" lazy val googleOAuthClient = "com.google.oauth-client" % "google-oauth-client-jetty" % "1.30.6" lazy val googleSpreadSheetApi = "com.google.apis" % "google-api-services-sheets" % "v4-rev581-1.25.0" // ... libraryDependencies ++= Seq(googleApiClient, googleOAuthClient, googleSpreadSheetApi)
GCPのコンソールでアプリと認証情報を作る
あらかじめGCPのコンソールでアプリを作成し、OAuthの準備をする。といっても、アプリ作成後に行うのは次の2つ。
- OAuth認証情報を作成する
- OAuth認証画面を設定する
この2つを設定すればよい。デスクトップアプリケーションという体裁で設定を行った。アプリケーション自体の作成方法は、ここでは割愛。
デスクトップアプリケーションという体裁なので、初回利用時にはブラウザが開いてOAuth認証画面が許可を求めてくる。完全ヘッドレスだとちょっと難しいのではないかと思う。 完全ヘッドレスにしたければAPIキーみたいなものを作成することになるのだろうか。今回はブラウザで我慢することにした。
このリンクを参考にクレデンシャルをダウンロードして、プロジェクトの好きな箇所にcredentials.json
という名前で保存しておく。たぶんリポジトリにチェックインしてはいけないファイルだと思う。
コーディング
やることは簡単。まずクレデンシャル情報を取得し、OAuth認証を突破してトークンを獲得し、そのトークンを使ってAPIを操作するのだ。
クレデンシャルの取得 && OAuth実行
クレデンシャル取得まわりはここにまとめた。getCredential
を呼ぶとOAuth認証が開始され、ユーザはブラウザに飛ばされて認証を要求される。
Spreadsheet APIを叩く
実際にシートにデータを入力する箇所はシンプル。元がJavaのAPIなのでBuilderパターンがたくさん出現するが、まあ我慢するしかない。
これで、 writeRange("....", "sheet!A1:p100", Seq(Seq(...)...))
というふうに呼べば、好きなシートの範囲を更新できるようになる。
最上位
App.scala
は、基本的にSpreadsheetのIDなどを設定ファイルから読み出して渡すだけ。
import Config.config // ... implicit val credential = spreadsheet.CredentialFactory .getCredential( config.getString("google.credentialsPath"), config.getString("google.tokenPath") ) .get // ... spreadsheet.SpreadSheet.writeRange( config.getString("google.spreadsheetId"), config.getString("google.spreadsheetRange"), rows // Seq[Seq[String]] )
reference.conf
/ application.conf
reference.conf
は以下のようになっている。
// ... google { tokenPath = "token" credentialsPath = "credentials.json" spreadsheetId = "" spreadsheetRange = "" }
ここで歯抜けになっている箇所をapplication.conf
で設定する(割愛)。これまでは環境変数でいちいち設定していたのだが、これでファイルに押し込むことができた。ちなみに環境変数を書くこともできるはず。
実行
普通に走らせるだけ。
% sbt run
するとブラウザが開いておなじみの承認画面が登場する。許可するとSpreadsheetにデータが書き込まれるはずだ。
感想
実行してみると、前回の記事で作成したデータを無事Spreadsheetに転記することができたので嬉しい。データの取得と書き込みが自動化できたので、バーンアップチャートを定時更新したりできるようになった。application.conf
の秘匿性の問題や、OAuth2のトークン情報をどうするかといった問題があるものの、もうひと頑張りすればクラウド環境にのっけて自動実行できるようになりそうだなと思った。
Spreadsheetへの書き込みは汎用性が高い技術なので、うまく活かしたい。