1// Copyright 2014 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package main 6 7import ( 8 "bufio" 9 "fmt" 10 "log" 11 "net/http" 12 "os" 13 "sort" 14 "strings" 15 16 gmail "google.golang.org/api/gmail/v1" 17) 18 19func init() { 20 registerDemo("gmail", gmail.MailGoogleComScope, gmailMain) 21} 22 23type message struct { 24 size int64 25 gmailID string 26 date string // retrieved from message header 27 snippet string 28} 29 30// gmailMain is an example that demonstrates calling the Gmail API. 31// It iterates over all messages of a user that are larger 32// than 5MB, sorts them by size, and then interactively asks the user to 33// choose either to Delete, Skip, or Quit for each message. 34// 35// Example usage: 36// go build -o go-api-demo *.go 37// go-api-demo -clientid="my-clientid" -secret="my-secret" gmail 38func gmailMain(client *http.Client, argv []string) { 39 if len(argv) != 0 { 40 fmt.Fprintln(os.Stderr, "Usage: gmail") 41 return 42 } 43 44 svc, err := gmail.New(client) 45 if err != nil { 46 log.Fatalf("Unable to create Gmail service: %v", err) 47 } 48 49 var total int64 50 msgs := []message{} 51 pageToken := "" 52 for { 53 req := svc.Users.Messages.List("me").Q("larger:5M") 54 if pageToken != "" { 55 req.PageToken(pageToken) 56 } 57 r, err := req.Do() 58 if err != nil { 59 log.Fatalf("Unable to retrieve messages: %v", err) 60 } 61 62 log.Printf("Processing %v messages...\n", len(r.Messages)) 63 for _, m := range r.Messages { 64 msg, err := svc.Users.Messages.Get("me", m.Id).Do() 65 if err != nil { 66 log.Fatalf("Unable to retrieve message %v: %v", m.Id, err) 67 } 68 total += msg.SizeEstimate 69 date := "" 70 for _, h := range msg.Payload.Headers { 71 if h.Name == "Date" { 72 date = h.Value 73 break 74 } 75 } 76 msgs = append(msgs, message{ 77 size: msg.SizeEstimate, 78 gmailID: msg.Id, 79 date: date, 80 snippet: msg.Snippet, 81 }) 82 } 83 84 if r.NextPageToken == "" { 85 break 86 } 87 pageToken = r.NextPageToken 88 } 89 log.Printf("total: %v\n", total) 90 91 sortBySize(msgs) 92 reader := bufio.NewReader(os.Stdin) 93 count, deleted := 0, 0 94 for _, m := range msgs { 95 count++ 96 fmt.Printf("\nMessage URL: https://mail.google.com/mail/u/0/#all/%v\n", m.gmailID) 97 fmt.Printf("Size: %v, Date: %v, Snippet: %q\n", m.size, m.date, m.snippet) 98 fmt.Printf("Options: (d)elete, (s)kip, (q)uit: [s] ") 99 val := "" 100 if val, err = reader.ReadString('\n'); err != nil { 101 log.Fatalf("unable to scan input: %v", err) 102 } 103 val = strings.TrimSpace(val) 104 switch val { 105 case "d": // delete message 106 if err := svc.Users.Messages.Delete("me", m.gmailID).Do(); err != nil { 107 log.Fatalf("unable to delete message %v: %v", m.gmailID, err) 108 } 109 log.Printf("Deleted message %v.\n", m.gmailID) 110 deleted++ 111 case "q": // quit 112 log.Printf("Done. %v messages processed, %v deleted\n", count, deleted) 113 os.Exit(0) 114 default: 115 } 116 } 117} 118 119type messageSorter struct { 120 msg []message 121 less func(i, j message) bool 122} 123 124func sortBySize(msg []message) { 125 sort.Sort(messageSorter{msg, func(i, j message) bool { 126 return i.size > j.size 127 }}) 128} 129 130func (s messageSorter) Len() int { 131 return len(s.msg) 132} 133 134func (s messageSorter) Swap(i, j int) { 135 s.msg[i], s.msg[j] = s.msg[j], s.msg[i] 136} 137 138func (s messageSorter) Less(i, j int) bool { 139 return s.less(s.msg[i], s.msg[j]) 140} 141