如何查看/看不到IMAP消息的状态

时间:2015-09-23 20:09:34

标签: go imap

我已经阅读了go documentation以及一般的imap documentation,但似乎无法找到获取特定消息状态的正确方法 - 知道它是否是标记为已读或未读。

这是我到目前为止所得到的:

// 
//Code that set up 'c' and 'cmd' ...
//
for cmd.InProgress() {
    // Wait for the next response (no timeout)
    c.Recv(-1)

    // Process command data
    for _, rsp = range cmd.Data {
        if err != nil {
            fmt.Println(err)
        }
        header := imap.AsBytes(rsp.MessageInfo().Attrs["RFC822.HEADER"])  // Contains subject, from data
        uid := imap.AsNumber(rsp.MessageInfo().Attrs["UID"])  // Message unique id
        body := imap.AsBytes(rsp.MessageInfo().Attrs["RFC822.TEXT"])  // Message body
        //seenState := imap.AsBytes(rsp.MessageInfo().Attrs["Flags"])
        if msg, err := mail.ReadMessage(bytes.NewReader(header)); msg != nil {
            if err != nil {
                fmt.Println(err)
            }
            //START CUSTOM
            if strings.Contains(msg.Header.Get("Subject"), genUUID()){
                fmt.Println(rsp.Label)
                fmt.Println(rsp.MessageInfo().Attrs["Flags"])
                fmt.Println(c.Status("INBOX", string(uid)))
            }
            //END CUSTOM

对于输出我得到:

FETCH
<nil>
LAOYU10 STATUS "INBOX" (Þ) <nil>

我引用的文档让我相信,如果邮件标记为看不见,至少应该打印一种方法。我错过了什么?

编辑: 我正在测试带有四条消息的收件箱(gmail)。前两个是读取的,后两个是未读的。这是所有四条消息的输出。

FETCH
<nil>
SIHLB7 STATUS "INBOX" (Û) <nil>
FETCH
<nil>
SIHLB8 STATUS "INBOX" (Ü) <nil>
FETCH
<nil>
SIHLB9 STATUS "INBOX" (Ý) <nil>
FETCH
<nil>
SIHLB10 STATUS "INBOX" (Þ) <nil>

3 个答案:

答案 0 :(得分:2)

有几点要注意,请确保您实际上是在请求imap请求中的flags字段。如果您要发送提取,那么您必须将"FLAGS"作为参数传递给Fetch,此外,Attrs中的flags属性区分大小写,因此您将需要rsp.MessageInfo().Attrs["FLAGS"]。以下是使用go-imap库在Gmail中使用imap的一个工作示例,使用GMAIL_EMAIL=email.address GMAIL_PASSWD=mypassword go run go_file.go

运行它
package main

import (
    "code.google.com/p/go-imap/go1/imap"
    "crypto/rand"
    "crypto/tls"
    "fmt"
    "os"
    "time"
)

func main() {
    label := "INBOX"
    email := os.Getenv("GMAIL_EMAIL")
    passwd := os.Getenv("GMAIL_PASSWD")

    conf := &tls.Config{
        Rand: rand.Reader,
    }

    c, err := imap.DialTLS("imap.gmail.com:993", conf)
    if err != nil {
        panic("Failed to connect")
    }

    defer c.Logout(30 * time.Second)

    c.Data = nil

    if c.Caps["STARTTLS"] {
        c.StartTLS(nil)
    }

    // Authenticate
    if c.State() == imap.Login {
        c.Login(email, passwd)
    }

    if c.State() != imap.Auth {
        panic("Authentication error")
    }

    c.Select(label, true)

    set, _ := imap.NewSeqSet("*")

    cmd, err := c.Fetch(set, "FLAGS", "UID")
    if err != nil {
        panic("Bad fetch command")
    }
    _, err = cmd.Result(imap.OK)
    if err != nil {
        panic("Bad fetch response")
    }
    for _, rsp := range cmd.Data {
        seen := false
        for _, flag := range imap.AsList(rsp.MessageInfo().Attrs["FLAGS"]) {
            if flag == "\\Seen" {
                seen = true
            }
        }

        if seen {
            fmt.Printf("Message %d has been read!\n", imap.AsNumber(rsp.MessageInfo().Attrs["UID"]))
        } else {
            fmt.Printf("Message %d has been not been read!\n", imap.AsNumber(rsp.MessageInfo().Attrs["UID"]))
        }
    }
}

答案 1 :(得分:1)

fmt.Println(rsp.MessageInfo().Attrs["Flags"])

为您打印<nil>因为没有设置标记,这意味着消息是&#34;看不见&#34;。

答案 2 :(得分:1)

每条消息都有一个IMAP中的标志列表,其中一个被称为\ see(不区分大小写,与IMAP中的大多数内容一样)。如果标志列表不包含该标志,则该消息是看不见的。

@jstedfast的答案解释了如何获取标志列表。剩下的就是在空格中分裂并检查列表中的任何单词是否等于\ see。