duanke0178 2018-06-14 17:27
浏览 95
已采纳

Golang Gmail imap搜索被冻结

I am trying to do a search for specific sender or specific flag. When I select Inbox and do a search on specific string the search api freezes. I am not sure what am I doing wrong. I am not able to find much examples too.

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条回答 默认 最新

  • dpf25323 2018-06-15 14:46
    关注

    When your search can return more than one message, you need to make sure to read everything from the messages channel, otherwise the program will hang. So instead of:

    msg := <-messages
    

    loop over the channel like so:

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

    Here's my working sample, which pulls connection details from the environment. It's a modified version of the example from 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
    ", msg)
            } else {
                log.Println("no messages matched criteria")
            }
        }
        if err := <-done; err != nil {
            log.Fatal(err)
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机
  • ¥20 程序进入HardFault_Handler
  • ¥15 关于#python#的问题:自动化测试