LoginSignup
5

More than 5 years have passed since last update.

Google Spreadsheetをマスターデータとして使い、curlでcsvとして取得する

Posted at

現在、GoogleのSpreadsheetをマスターデータの保存先として使用しています。diffを確認したいがために、git管理にしており、localに落としてから、コミットする必要があります。

その際に、公開されているSpreadsheetならURLで取得できるのですが、プライベートな場合、Access Tokenを使用する必要があります。

このAccess Tokenは1時間で切れてしまうので、そのAccess Tokenを再度取得するために、Refresh Tokenというものが必要になります。

この記事では、Refresh Tokenを取得してから、それを使って、Access Tokenを取得し、curlでSpreadsheetを取得する方法を説明します。

Refresh Tokenを取得する

以下がこれから行う手順になります

  1. Client IDとClient Secretを取得する
  2. ローカルでgoで書いたサーバを立ち上げる
  3. http://localhost:9090 にアクセスし、その後、Google認証を行う
  4. 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認証を行う

image.png

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_IDGIDは適当におきかえつつ以下を実行すれば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

参考

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5