現在、GoogleのSpreadsheetをマスターデータの保存先として使用しています。diffを確認したいがために、git管理にしており、localに落としてから、コミットする必要があります。
その際に、公開されているSpreadsheetならURLで取得できるのですが、プライベートな場合、Access Tokenを使用する必要があります。
このAccess Tokenは1時間で切れてしまうので、そのAccess Tokenを再度取得するために、Refresh Tokenというものが必要になります。
この記事では、Refresh Tokenを取得してから、それを使って、Access Tokenを取得し、curlでSpreadsheetを取得する方法を説明します。
Refresh Tokenを取得する
以下がこれから行う手順になります
- Client IDとClient Secretを取得する
- ローカルでgoで書いたサーバを立ち上げる
- http://localhost:9090 にアクセスし、その後、Google認証を行う
- http://localhost:9090/auth にリダイレクトされ、そこでRefresh Tokenが取得できる
Client IDとClient Secretを取得する
上記らへんを参考にしつつあらかじめ取得しておきます
ローカルでgoで書いたサーバを立ち上げる
先程取得した、Client IDとClient ScretをそれぞれGOOGLE_CLIENT_IDとGOOGLE_CLIENT_SECRETの環境変数として設定しておきます。
以下を適当なGOPATH以下のmain.goファイルとしておき、go main.go
で実行します
package main
import (
"crypto/rand"
"encoding/base64"
"net/http"
"os"
"github.com/gin-gonic/gin"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
)
var conf *oauth2.Config
var state string
func randToken() string {
b := make([]byte, 32)
rand.Read(b)
return base64.StdEncoding.EncodeToString(b)
}
func init() {
conf = &oauth2.Config{
ClientID: os.Getenv("GOOGLE_CLIENT_ID"),
ClientSecret: os.Getenv("GOOGLE_CLIENT_SECRET"),
RedirectURL: "http://127.0.0.1:9090/auth",
Scopes: []string{
"https://www.googleapis.com/auth/drive",
},
Endpoint: google.Endpoint,
}
}
func getLoginURL(state string) string {
return conf.AuthCodeURL(state)
}
func authHandler(c *gin.Context) {
// Handle the exchange code to initiate a transport.
tok, err := conf.Exchange(oauth2.NoContext, c.Query("code"))
if err != nil {
c.AbortWithError(http.StatusBadRequest, err)
return
}
c.Writer.Write([]byte(tok.RefreshToken))
}
func loginHandler(c *gin.Context) {
state = randToken()
c.Writer.Write([]byte("<html><title>Golang Google</title> <body> <a href='" + getLoginURL(state) + "'><button>Login with Google!</button> </a> </body></html>"))
}
func main() {
router := gin.Default()
router.GET("/", loginHandler)
router.GET("/auth", authHandler)
router.Run("127.0.0.1:9090")
}
(上記は https://skarlso.github.io/2016/06/12/google-signin-with-go/ を参考にしました)
http://localhost:9090 にアクセスし、その後、Google認証を行う
http://localhost:9090/auth にリダイレクトされ、そこでRefresh Tokenが取得できる
認証後、自動でリダイレクトされ文字列が表示されるので、メモっておきます。
今回はREFRESH_TOKEN
という環境変数に入っていると仮定します
Refresh TokenからAccess Tokenを取得する
jq
コマンドはあらかじめいれておいてください。
以下を実行すると、Access Tokenが取得できます。取得したものはACCESS_TOKEN
という環境変数にはいっていると仮定します
curl --data "refresh_token=${REFRESH_TOKEN}" --data "client_id=${GOOGLE_CLIENT_ID}" --data "client_secret=${GOOGLE_CLIENT_SECRET}" --data "grant_type=refresh_token" https://www.googleapis.com/oauth2/v4/token| jq -r .access_token`
Access Tokenを使い、Spreadsheetをcsv形式で取得する
SHEET_ID
とGID
は適当におきかえつつ以下を実行すればdata.csvとしてSpreadsheetが取得できます
curl -H "Authorization: Bearer ${ACCESS_TOKEN}" "https://docs.google.com/spreadsheets/d/${SHEET_ID}/export?gid=${GID}&format=csv" -o data.csv