Skip to content

Instantly share code, notes, and snippets.

@IngCr3at1on
Created September 30, 2019 15:45
Show Gist options
  • Save IngCr3at1on/a8ac810c4fe994391a1f92a45b276426 to your computer and use it in GitHub Desktop.
Save IngCr3at1on/a8ac810c4fe994391a1f92a45b276426 to your computer and use it in GitHub Desktop.
Gmail delete by query
package internal
import (
"context"
"encoding/json"
"fmt"
"net/http"
"os"
"golang.org/x/oauth2"
)
// GetClient retrieve a token, saves the token, then returns the generated client.
func GetClient(ctx context.Context, config *oauth2.Config) (*http.Client, error) {
// 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.
// Don't leave in plain text for all to read...
tokFile := "token.json"
tok, err := tokenFromFile(tokFile)
if err != nil {
tok, err = getTokenFromWeb(ctx, config)
if err != nil {
return nil, err
}
if err = saveToken(tokFile, tok); err != nil {
return nil, err
}
}
return config.Client(ctx, tok), nil
}
// Request a token from the web, then returns the retrieved token.
func getTokenFromWeb(ctx context.Context, config *oauth2.Config) (*oauth2.Token, error) {
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 {
return nil, err
}
tok, err := config.Exchange(ctx, authCode)
if err != nil {
return nil, err
}
return tok, nil
}
// 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) error {
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 {
return err
}
defer f.Close()
return json.NewEncoder(f).Encode(token)
}
package main
import (
"fmt"
"io/ioutil"
"os"
"github.com/ingcr3at1on/scrubox/cmd/internal"
"github.com/ingcr3at1on/x/sigctx"
"golang.org/x/net/context"
"golang.org/x/oauth2/google"
"google.golang.org/api/gmail/v1"
)
func deleteMessagesByQuery(srv *gmail.Service, query string) error {
user := "me"
call := srv.Users.Messages.List(user).Q(query)
for {
r, err := call.Do()
if err != nil {
return err
}
var ids []string
for _, m := range r.Messages {
ids = append(ids, m.Id)
}
if err = srv.Users.Messages.BatchDelete(user, &gmail.BatchDeleteMessagesRequest{
Ids: ids,
}).Do(); err != nil {
return err
}
if r.NextPageToken == `` {
break
}
call.PageToken(r.NextPageToken)
}
return nil
}
func main() {
if len(os.Args) != 2 {
fmt.Printf("usage: %s <gmail query string>", os.Args[0])
os.Exit(1)
}
if err := sigctx.StartWith(func(ctx context.Context) error {
// FIXME: don't hardcode.
byt, err := ioutil.ReadFile("credentials.json")
if err != nil {
return err
}
// If modifying these scopes, delete your previously saved token.json.
config, err := google.ConfigFromJSON(byt, gmail.MailGoogleComScope)
if err != nil {
return err
}
client, err := internal.GetClient(ctx, config)
if err != nil {
return err
}
srv, err := gmail.New(client)
if err != nil {
return err
}
if err := deleteMessagesByQuery(srv, os.Args[1]); err != nil {
return err
}
return nil
}); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment