Golang Gmail imap搜索正在冻结

时间:2018-06-14 17:27:14

标签: go gmail imap

我正在尝试搜索特定的发件人或特定的标志。当我选择收件箱并对特定字符串进行搜索时,搜索API会冻结。我不确定我做错了什么。我也找不到太多的例子。

criteria := imap.NewSearchCriteria()
criteria.WithoutFlags = []string{"\\Seen"}
uids, err := c.Search(criteria)
if err != nil {
 log.Println(err)
}
seqset := new(imap.SeqSet)
seqset.AddNum(uids...)
section := &imap.BodySectionName{}
items := []imap.FetchItem{imap.FetchEnvelope, imap.FetchFlags, imap.FetchInternalDate, section.FetchItem()}
messages := make(chan *imap.Message)
go func() {
    done <- c.Fetch(seqset, items, messages)
}()
msg := <-messages //its getting stuck at this point. Nothing happens i dont get messages.

1 个答案:

答案 0 :(得分:2)

当您的搜索可以返回多条消息时,您需要确保从messages频道中读取所有内容,否则程序将挂起。所以而不是:

msg := <-messages

循环通道如下:

for msg := range messages {
  // process msg
}

这是我的工作示例,它从环境中提取连接详细信息。它是来自emersion's imap lib的示例的修改版本:

package main

import (
    "crypto/tls"
    "flag"
    "fmt"
    "log"
    "os"
    "time"

    "github.com/emersion/go-imap"
    "github.com/emersion/go-imap/client"
)

func main() {
    hours := flag.Int("hours", 24, "look this many hours in the past for messages")
    flag.Parse()
    if *hours > 0 {
        *hours = *hours * -1
    }

    host := os.Getenv("IMAP_HOST")
    port := os.Getenv("IMAP_PORT")
    user := os.Getenv("IMAP_USER")
    pass := os.Getenv("IMAP_PASS")
    tlsn := os.Getenv("IMAP_TLS_SERVERNAME")
    if port == "" {
        port = "993"
    }

    connStr := fmt.Sprintf("%s:%s", host, port)

    tlsc := &tls.Config{}
    if tlsn != "" {
        tlsc.ServerName = tlsn
    }

    c, err := client.DialTLS(connStr, tlsc)
    if err != nil {
        log.Fatal(err)
    }
    log.Println("Connected")
    defer c.Logout()

    if err := c.Login(user, pass); err != nil {
        log.Fatal(err)
    }
    log.Println("Authenticated")

    mbox, err := c.Select("INBOX", false)
    if err != nil {
        log.Fatal(err)
    }
    log.Println("Flags for INBOX:", mbox.Flags)

    criteria := imap.NewSearchCriteria()
    //criteria.WithFlags = []string{imap.SeenFlag}
    criteria.Since = time.Now().Add(time.Duration(*hours) * time.Hour)
    uids, err := c.Search(criteria)
    if err != nil {
        log.Println(err)
    }
    seqset := new(imap.SeqSet)
    seqset.AddNum(uids...)
    log.Printf("Search complete, found %d messages", len(uids))

    section := &imap.BodySectionName{}
    items := []imap.FetchItem{imap.FetchEnvelope, imap.FetchFlags, imap.FetchInternalDate, section.FetchItem()}
    messages := make(chan *imap.Message)
    done := make(chan error, 1)
    go func() {
        done <- c.Fetch(seqset, items, messages)
        log.Println("Fetch complete")
    }()
    for msg := range messages {
        if msg != nil {
            log.Printf("got message with address %p\n", msg)
        } else {
            log.Println("no messages matched criteria")
        }
    }
    if err := <-done; err != nil {
        log.Fatal(err)
    }
}