diff --git a/.gitignore b/.gitignore index 9dd0b1b..8af25e4 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ **/credentials.json +**/token.json diff --git a/main.go b/main.go index e69de29..0fe105a 100644 --- a/main.go +++ b/main.go @@ -0,0 +1,96 @@ +package main + +import ( + "context" + "encoding/json" + "fmt" + "log" + "net/http" + "os" + + "golang.org/x/oauth2" + "golang.org/x/oauth2/google" + "google.golang.org/api/gmail/v1" + "google.golang.org/api/option" +) + +func getClient(config *oauth2.Config) *http.Client { + token_file := "token.json" + token, err := tokenFromFile(token_file) + if err != nil { + token = getTokenFromWeb(config) + saveToken(token_file, token) + } + return config.Client(context.Background(), token) +} + +func getTokenFromWeb(config *oauth2.Config) *oauth2.Token { + auth_url := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline) + fmt.Printf("Go to the following link in your browser, then type the " + + "authorization code: \n%v\n", auth_url) + + var auth_code string + if _, err := fmt.Scan(&auth_code) ; err != nil { + log.Fatalf("Unable to read authorization code: %v", err) + } + + token, err := config.Exchange(context.TODO(), auth_code) + if err != nil { + log.Fatalf("Unable to retrieve token from web: %v", err) + } + return token +} + +func tokenFromFile(file string) (*oauth2.Token, error) { + f, err := os.Open(file) + if err != nil { + return nil, err + } + defer f.Close() + token := &oauth2.Token{} + err = json.NewDecoder(f).Decode(token) + return token, err +} + +func saveToken(path string, token *oauth2.Token) { + fmt.Printf("Saving credential file to: %s\n", path) + file, 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 file.Close() + json.NewEncoder(file).Encode(token) +} + +func main() { + ctx := context.Background() + creds_b, err := os.ReadFile("credentials.json") + if err != nil { + log.Fatalf("Unable to read client secret file: %v", err) + } + + config, err := google.ConfigFromJSON(creds_b, gmail.GmailReadonlyScope) + if err != nil { + log.Fatalf("Unable to parse client secret file to config: %v", err) + } + client := getClient(config) + + service, err := gmail.NewService(ctx, option.WithHTTPClient(client)) + if err != nil { + log.Fatalf("Unable to retrieve Gmail client: %v", err) + } + + user := "me" + r, err := service.Users.Labels.List(user).Do() + if err != nil { + log.Fatalf("Unable to retrieve labels: %v", err) + } + if len(r.Labels) == 0 { + fmt.Println("No labels found") + return + } + fmt.Println("Labels:") + for _, label := range r.Labels { + fmt.Printf("- %s\n", label.Name) + } +} diff --git a/token.json.example b/token.json.example new file mode 100644 index 0000000..ece5912 --- /dev/null +++ b/token.json.example @@ -0,0 +1,6 @@ +{ + "access_token": "ACCESS_TOKEN", + "token_type": "Bearer", + "refresh_token": "REFRESH_TOKEN", + "expiry": "EXPIRY_TIMESTAMP" +}