package google import ( "GoSungrow/Only" "context" "errors" "fmt" "golang.org/x/oauth2" "golang.org/x/oauth2/google" "google.golang.org/api/googleapi" "google.golang.org/api/option" "google.golang.org/api/sheets/v4" "net/http" "os" "path/filepath" ) const DefaultId = "SUPERSECRETKEY" type Sheet struct { Id string SheetName string Range string Credentials []byte TokenFile string token *oauth2.Token oAuthConfig *oauth2.Config Data SheetData } type SheetData [][]interface{} func (s *Sheet) Set(cfg Sheet) { for range Only.Once { s.Id = cfg.Id s.SheetName = cfg.SheetName s.Range = cfg.Range s.Credentials = cfg.Credentials s.TokenFile = cfg.TokenFile s.token = cfg.token s.Verify() } } func (s *Sheet) Verify() bool { var ok bool for range Only.Once { if s.Id == "" { s.Id = DefaultId } if s.SheetName == "" { s.SheetName = "" } if s.Range == "" { s.Range = "A1" } if len(s.Credentials) == 0 { s.Credentials = []byte(DefaultGoogleCredentials) } // token *oauth2.token // oAuthConfig *oauth2.Config if s.oAuthConfig == nil { s.oAuthConfig = &oauth2.Config{} } if s.token == nil { s.token = &oauth2.Token{} } if len(s.TokenFile) == 0 { var err error s.TokenFile, err = os.UserHomeDir() if err != nil { s.TokenFile = "" break } s.TokenFile = filepath.Join(s.TokenFile, ".GoSungrow", DefaultAuthTokenFile) } ok = true } return ok } func (s *Sheet) ReadSheet() (SheetData, error) { var err error var csv SheetData for range Only.Once { if !s.Verify() { break } // If modifying these scopes, delete your previously saved token.json. s.oAuthConfig, err = google.ConfigFromJSON(s.Credentials, sheets.SpreadsheetsReadonlyScope) if err != nil { err = errors.New(fmt.Sprintf("Unable to parse client secret file to config: %v", err)) break } var client *http.Client client, err = s.getClient() ctx := context.Background() var srv *sheets.Service srv, err = sheets.NewService(ctx, option.WithHTTPClient(client)) if err != nil { err = errors.New(fmt.Sprintf("Unable to retrieve Sheets client: %v", err)) break } readRange := fmt.Sprintf("%s!%s", s.SheetName, s.Range) var resp *sheets.ValueRange resp, err = srv.Spreadsheets.Values.Get(s.Id, readRange).Do() if err != nil { err = errors.New(fmt.Sprintf("Unable to retrieve data from sheet: %v", err)) break } if len(resp.Values) == 0 { fmt.Println("No data found.") break } for _, row := range resp.Values { // Print columns A and E, which correspond to indices 0 and 4. fmt.Printf("%v\n", row) } } return csv, err } func (s *Sheet) WriteSheet() error { var err error for range Only.Once { if !s.Verify() { break } // If modifying these scopes, delete your previously saved token.json. s.oAuthConfig, err = google.ConfigFromJSON(s.Credentials, sheets.SpreadsheetsScope) if err != nil { err = errors.New(fmt.Sprintf("Unable to parse client secret file to config: %v", err)) break } var client *http.Client client, err = s.getClient() //client = getClient(s.oAuthConfig) ctx := context.Background() var srv *sheets.Service srv, err = sheets.NewService(ctx, option.WithHTTPClient(client)) if err != nil { err = errors.New(fmt.Sprintf("Unable to retrieve Sheets client: %v", err)) break } //var itt = srv.Spreadsheets.getSheetByName('_EmailList'); //if (!itt) { // ss.insertSheet('_EmailList'); //} vr := sheets.ValueRange{ MajorDimension: "", Range: s.SheetName + "!" + s.Range, Values: s.Data, ServerResponse: googleapi.ServerResponse{}, ForceSendFields: nil, NullFields: nil, } writeRange := fmt.Sprintf("%s!%s", s.SheetName, s.Range) fmt.Printf("Updating Google sheet '%s'.\n\tWorksheet: %s\n\tStarting from: %s\n", s.Id, s.SheetName, s.Range, ) _, err = srv.Spreadsheets.Values.Update(s.Id, writeRange, &vr).ValueInputOption("USER_ENTERED").Do() // or "RAW" if err != nil { err = errors.New(fmt.Sprintf("Unable to retrieve data from sheet. %v", err)) break } } return err }