golang gmail API
doyle
posted @ 2014年10月23日 10:30
in golang
with tags
go, gmail, google-api
, 2603 阅读
Loading
package main import ( "flag" "fmt" "log" "net/http" "strings" "code.google.com/p/goauth2/oauth" gmail "code.google.com/p/google-api-go-client/gmail/v1" ) var ( code = flag.String("code", "", "Authorization Code") cachefile = flag.String("cache", "cache.json", "Token cache file") ) const usageMsg = ` To obtain a request token you must specify both -id and -secret. To obtain Client ID and Secret, see the "OAuth 2 Credentials" section under the "API Access" tab on this page: https://console.developers.google.com/ Once you have completed the OAuth flow, the credentials should be stored inside the file specified by -cache and you may run without the -id and -secret flags. ` func main() { flag.Parse() var config = &oauth.Config{ ClientId: "",// https://console.developers.google.com/ 新建一个project 后,申请一个oauth 的clientId ClientSecret: "",// 和ClientSecret Scope: gmail.MailGoogleComScope, RedirectURL: "urn:ietf:wg:oauth:2.0:oob", AuthURL: "https://accounts.google.com/o/oauth2/auth", TokenURL: "https://accounts.google.com/o/oauth2/token", TokenCache: oauth.CacheFile(*cachefile), } client, err := GetOauthClient(config) if err != nil { return } svc, err := gmail.New(client) labelId := GetLabelId(svc, "LabelName") // LabelName 替换为gmail 中的label ScanMessage(svc, labelId) } // chan 的设置仍然大了点,超过了google 的api rate limit…… var ch_pages = make(chan string, 5) // NextPageToken的chan var ch_messageIds = make(chan string, 5) // MessageId的chan var done = make(chan int) // 未正确使用…… func ScanMessage(svc *gmail.Service, labelId string) { resp, err := svc.Users.Messages.List("me").LabelIds(labelId).Do() if err != nil { log.Fatal(err) } if len(resp.NextPageToken) > 0 { ch_pages <- resp.NextPageToken } go func(svc *gmail.Service) { for { select { case resp := <-ch_pages: go GetPages(svc, resp, labelId) case msgId := <-ch_messageIds: go CheckMailMessage(svc, msgId) } } }(svc) for _, message := range resp.Messages { ch_messageIds <- message.Id } <-done log.Println("all mail chceked!") } // 请求下一页 func GetPages(svc *gmail.Service, pageToken string, labelId string) { log.Println("PageToken:", pageToken) resp, err := svc.Users.Messages.List("me").LabelIds(labelId).PageToken(pageToken).Do() if err != nil { log.Fatal(err) } for _, message := range resp.Messages { ch_messageIds <- message.Id } if len(resp.NextPageToken) > 0 { ch_pages <- resp.NextPageToken } else { done <- 1 } } // 请求具体的Message,这里只获取一下From 和Subject 作为判断依据 func CheckMailMessage(svc *gmail.Service, msgId string) { log.Println("Message.Id:", msgId) msg, err := svc.Users.Messages.Get("me", msgId).Do() if err != nil { log.Fatal(err) } var from, subject string for _, h := range msg.Payload.Headers { if h.Name == "From" { lIdx := strings.Index(h.Value, "<") rIdx := strings.Index(h.Value, ">") if lIdx > 0 && rIdx < len(h.Value) { from = strings.TrimSpace(h.Value[lIdx+1 : rIdx]) } } if h.Name == "Subject" { tmp := strings.Split(h.Value, " ") subject = tmp[len(tmp)-1] } } log.Println(subject, from) trash := Check(from, subject) if trash { log.Println(subject, from, trash) svc.Users.Messages.Trash("me", msg.Id).Do() } } // 具体的判断规则 func Check(from, subject string) bool { if from == "xxx@gmail.com" { return true } return false } // 根据labelName 获得LabelId func GetLabelId(svc *gmail.Service, label string) (labelId string) { list, err := svc.Users.Labels.List("me").Do() if err != nil { log.Fatal(err) } for _, lbl := range list.Labels { // 可以修改这里,看看你gmail 中所有label 对应的label id if lbl.Name == label { labelId = lbl.Id break } } return } // 抄来的oauth 登陆部分 func GetOauthClient(config *oauth.Config) (*http.Client, error) { transport := &oauth.Transport{Config: config} // Try to pull the token from the cache; if this fails, we need to get one. token, err := config.TokenCache.Token() if err != nil { if *code == "" { // Get an authorization code from the data provider. // ("Please ask the user if I can access this resource.") url := config.AuthCodeURL("") fmt.Print("Visit this URL to get a code, then run again with -code=YOUR_CODE\n\n") fmt.Println(url) return nil, err } // Exchange the authorization code for an access token. // ("Here's the code you gave the user, now give me a token!") token, err = transport.Exchange(*code) if err != nil { log.Fatal("Exchange:", err) } // (The Exchange method will automatically cache the token.) fmt.Printf("Token is cached in %v\n", config.TokenCache) } // Make the actual request using the cached token to authenticate. // ("Here's the token, let me in!") transport.Token = token // Make the request. return transport.Client(), nil }