From e83092a0031874aac3dc74b3b74e60953310258c Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Tue, 10 Nov 2020 14:12:39 +0100 Subject: [PATCH] Sheets API: Simplify quickstart code by using option.WithCredentialsFile(). --- sheets/quickstart/quickstart.go | 87 +++++---------------------------- 1 file changed, 13 insertions(+), 74 deletions(-) diff --git a/sheets/quickstart/quickstart.go b/sheets/quickstart/quickstart.go index 59d161e..7a7f24f 100644 --- a/sheets/quickstart/quickstart.go +++ b/sheets/quickstart/quickstart.go @@ -18,88 +18,27 @@ package main import ( - "encoding/json" + "context" "fmt" - "io/ioutil" "log" - "net/http" - "os" - "golang.org/x/net/context" - "golang.org/x/oauth2" - "golang.org/x/oauth2/google" + "google.golang.org/api/option" "google.golang.org/api/sheets/v4" ) -// Retrieve a token, saves the token, then returns the generated client. -func getClient(config *oauth2.Config) *http.Client { - // The file token.json stores the user's access and refresh tokens, and is - // created automatically when the authorization flow completes for the first - // time. - tokFile := "token.json" - tok, err := tokenFromFile(tokFile) - if err != nil { - tok = getTokenFromWeb(config) - saveToken(tokFile, tok) - } - return config.Client(context.Background(), tok) -} - -// Request a token from the web, then returns the retrieved token. -func getTokenFromWeb(config *oauth2.Config) *oauth2.Token { - authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline) - fmt.Printf("Go to the following link in your browser then type the "+ - "authorization code: \n%v\n", authURL) - - var authCode string - if _, err := fmt.Scan(&authCode); err != nil { - log.Fatalf("Unable to read authorization code: %v", err) - } - - tok, err := config.Exchange(context.TODO(), authCode) - if err != nil { - log.Fatalf("Unable to retrieve token from web: %v", err) - } - return tok -} - -// Retrieves a token from a local file. -func tokenFromFile(file string) (*oauth2.Token, error) { - f, err := os.Open(file) - if err != nil { - return nil, err - } - defer f.Close() - tok := &oauth2.Token{} - err = json.NewDecoder(f).Decode(tok) - return tok, err -} - -// Saves a token to a file path. -func saveToken(path string, token *oauth2.Token) { - fmt.Printf("Saving credential file to: %s\n", path) - f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) - if err != nil { - log.Fatalf("Unable to cache oauth token: %v", err) - } - defer f.Close() - json.NewEncoder(f).Encode(token) -} - func main() { - b, err := ioutil.ReadFile("credentials.json") - if err != nil { - log.Fatalf("Unable to read client secret file: %v", err) - } + ctx := context.Background() - // If modifying these scopes, delete your previously saved token.json. - config, err := google.ConfigFromJSON(b, "https://www.googleapis.com/auth/spreadsheets.readonly") - if err != nil { - log.Fatalf("Unable to parse client secret file to config: %v", err) - } - client := getClient(config) + srv, err := sheets.NewService(ctx, + // Authenticate with a service account or refresh token JSON credentials file. + // Remove this option to authenticate via Application Default Credentials. + option.WithCredentialsFile("credentials.json"), - srv, err := sheets.New(client) + // Be default, the sheets package requests all scopes that it could + // potentially need. This passes the read-only scope explicitly to + // limit the requested scopes to what is actually needed. + option.WithScopes(sheets.SpreadsheetsReadonlyScope), + ) if err != nil { log.Fatalf("Unable to retrieve Sheets client: %v", err) } @@ -108,7 +47,7 @@ func main() { // https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit spreadsheetId := "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms" readRange := "Class Data!A2:E" - resp, err := srv.Spreadsheets.Values.Get(spreadsheetId, readRange).Do() + resp, err := srv.Spreadsheets.Values.Get(spreadsheetId, readRange).Context(ctx).Do() if err != nil { log.Fatalf("Unable to retrieve data from sheet: %v", err) }