Example #1
0
// NewGMail returns a new GMail object which is authorized to send email.
func NewGMail(clientId, clientSecret, tokenCacheFile string) (*GMail, error) {
	client, err := auth.NewClientFromIdAndSecret(clientId, clientSecret, tokenCacheFile, gmail.GmailComposeScope)
	if err != nil {
		return nil, err
	}
	service, err := gmail.New(client)
	if err != nil {
		return nil, err
	}
	return &GMail{
		service: service,
	}, nil
}
Example #2
0
func getGmailService(tokens oauth2.Tokens) (*gmail.Service, error) {
	config := goauth2.Config{
		ClientID:     *CLIENT_ID,
		ClientSecret: *SECRET,
		Endpoint:     google.Endpoint,
		Scopes:       []string{gmail.MailGoogleComScope},
		RedirectURL:  "http://localhost:8080/auth",
	}

	ctx := context.Background()
	tok := (goauth2.Token)(tokens.Get())
	client := config.Client(ctx, &tok)

	return gmail.New(client)
}
Example #3
0
func getNewService() (*gmail.Service, error) {
	b, err := ioutil.ReadFile("client_secret.json")
	if err != nil {
		log.Fatalf("Unable to read client secret file: %v", err)
	}

	config, err := google.ConfigFromJSON(b, gmail.MailGoogleComScope)
	if err != nil {
		log.Fatalf("Unable to parse client secret file to config: %v", err)
	}
	client := getClient(context.Background(), config)

	srv, err := gmail.New(client)
	return srv, err
}
Example #4
0
func NewClient(cfg Config) (*Client, error) {
	authConfig := auth.Config{
		SecretFile: cfg.SecretFile,
		Scope:      gmail.MailGoogleComScope,
	}
	httpClient, err := auth.NewClient(authConfig)
	if err != nil {
		return nil, err
	}
	svc, err := gmail.New(httpClient)
	if err != nil {
		return nil, err
	}
	return &Client{svc.Users.Messages}, nil
}
Example #5
0
// NewGMail returns a new GMail object which is authorized to send email.
func NewGMail(clientId, clientSecret, tokenCacheFile string) (*GMail, error) {
	config := oauth.Config{
		ClientId:     clientId,
		ClientSecret: clientSecret,
		Scope:        gmail.GmailComposeScope,
		AuthURL:      "https://accounts.google.com/o/oauth2/auth",
		TokenURL:     "https://accounts.google.com/o/oauth2/token",
		TokenCache:   oauth.CacheFile(tokenCacheFile),
		RedirectURL:  "urn:ietf:wg:oauth:2.0:oob",
		AccessType:   "offline",
	}
	client, err := auth.RunFlow(&config)
	if err != nil {
		return nil, err
	}
	service, err := gmail.New(client)
	if err != nil {
		return nil, err
	}
	return &GMail{
		service: service,
	}, nil
}
Example #6
0
func main() {
	const OOB = "urn:ietf:wg:oauth:2.0:oob"
	conf := &oauth2.Config{
		ClientID: "881077086782-039l7vctubc7vrvjmubv6a7v0eg96sqg.apps.googleusercontent.com", // proj: inbox-fewer

		// https://developers.google.com/identity/protocols/OAuth2InstalledApp
		// says: "The client ID and client secret obtained
		// from the Developers Console are embedded in the
		// source code of your application. In this context,
		// the client secret is obviously not treated as a
		// secret."
		ClientSecret: "y9Rj5-KheyZSFyjCH1dCBXWs",

		Endpoint:    google.Endpoint,
		RedirectURL: OOB,
		Scopes:      []string{gmail.MailGoogleComScope},
	}

	cacheDir := filepath.Join(userCacheDir(), "inboxfewer")
	gmailTokenFile := filepath.Join(cacheDir, "gmail.token")

	slurp, err := ioutil.ReadFile(gmailTokenFile)
	var ts oauth2.TokenSource
	if err == nil {
		f := strings.Fields(strings.TrimSpace(string(slurp)))
		if len(f) == 2 {
			ts = conf.TokenSource(context.Background(), &oauth2.Token{
				AccessToken:  f[0],
				TokenType:    "Bearer",
				RefreshToken: f[1],
				Expiry:       time.Unix(1, 0),
			})
			if _, err := ts.Token(); err != nil {
				log.Printf("Cached token invalid: %v", err)
				ts = nil
			}
		}
	}

	if ts == nil {
		authCode := conf.AuthCodeURL("state")
		log.Printf("Go to %v", authCode)
		io.WriteString(os.Stdout, "Enter code> ")

		bs := bufio.NewScanner(os.Stdin)
		if !bs.Scan() {
			os.Exit(1)
		}
		code := strings.TrimSpace(bs.Text())
		t, err := conf.Exchange(context.Background(), code)
		if err != nil {
			log.Fatal(err)
		}
		os.MkdirAll(cacheDir, 0700)
		ioutil.WriteFile(gmailTokenFile, []byte(t.AccessToken+" "+t.RefreshToken), 0600)
		ts = conf.TokenSource(context.Background(), t)
	}

	client := oauth2.NewClient(context.Background(), ts)
	svc, err := gmail.New(client)
	if err != nil {
		log.Fatal(err)
	}

	readGithubConfig()

	fc := &FewerClient{
		svc: svc.Users,
	}
	n := 0
	if err := fc.ForeachThread("in:inbox", func(t *gmail.Thread) error {
		if err := fc.PopulateThread(t); err != nil {
			return err
		}
		topic := fc.ClassifyThread(t)
		n++
		log.Printf("Thread %d (%v) = %T %v", n, t.Id, topic, topic)
		if topic == nil {
			return nil
		}
		if stale, err := topic.IsStale(); err != nil {
			return err
		} else if stale {
			log.Printf("  ... archiving")
			return fc.ArchiveThread(t.Id)
		}
		return nil
	}); err != nil {
		log.Fatal(err)
	}
}
Example #7
0
// gmailMain is an example that demonstrates calling the Gmail API.
// It iterates over all messages of a user that are larger
// than 5MB, sorts them by size, and then interactively asks the user to
// choose either to Delete, Skip, or Quit for each message.
//
// Example usage:
//   go build -o go-api-demo *.go
//   go-api-demo -clientid="my-clientid" -secret="my-secret" gmail
func gmailMain(client *http.Client, argv []string) {
	if len(argv) != 0 {
		fmt.Fprintln(os.Stderr, "Usage: gmail")
		return
	}

	svc, err := gmail.New(client)
	if err != nil {
		log.Fatalf("Unable to create Gmail service: %v", err)
	}

	var total int64
	msgs := []message{}
	pageToken := ""
	for {
		req := svc.Users.Messages.List("me").Q("larger:5M")
		if pageToken != "" {
			req.PageToken(pageToken)
		}
		r, err := req.Do()
		if err != nil {
			log.Fatalf("Unable to retrieve messages: %v", err)
		}

		log.Printf("Processing %v messages...\n", len(r.Messages))
		for _, m := range r.Messages {
			msg, err := svc.Users.Messages.Get("me", m.Id).Do()
			if err != nil {
				log.Fatalf("Unable to retrieve message %v: %v", m.Id, err)
			}
			total += msg.SizeEstimate
			date := ""
			for _, h := range msg.Payload.Headers {
				if h.Name == "Date" {
					date = h.Value
					break
				}
			}
			msgs = append(msgs, message{
				size:    msg.SizeEstimate,
				gmailID: msg.Id,
				date:    date,
				snippet: msg.Snippet,
			})
		}

		if r.NextPageToken == "" {
			break
		}
		pageToken = r.NextPageToken
	}
	log.Printf("total: %v\n", total)

	sortBySize(msgs)
	reader := bufio.NewReader(os.Stdin)
	count, deleted := 0, 0
	for _, m := range msgs {
		count++
		fmt.Printf("\nMessage URL: https://mail.google.com/mail/u/0/#all/%v\n", m.gmailID)
		fmt.Printf("Size: %v, Date: %v, Snippet: %q\n", m.size, m.date, m.snippet)
		fmt.Printf("Options: (d)elete, (s)kip, (q)uit: [s] ")
		val := ""
		if val, err = reader.ReadString('\n'); err != nil {
			log.Fatalf("unable to scan input: %v", err)
		}
		val = strings.TrimSpace(val)
		switch val {
		case "d": // delete message
			if err := svc.Users.Messages.Delete("me", m.gmailID).Do(); err != nil {
				log.Fatalf("unable to delete message %v: %v", m.gmailID, err)
			}
			log.Printf("Deleted message %v.\n", m.gmailID)
			deleted++
		case "q": // quit
			log.Printf("Done.  %v messages processed, %v deleted\n", count, deleted)
			os.Exit(0)
		default:
		}
	}
}