英文:
How to get seen/unseen status of IMAP message
问题
我已经阅读了go的文档以及一般的imap文档,但似乎找不到获取特定消息状态(已读或未读)的正确方法。
以下是我目前的代码:
//
//设置'c'和'cmd'的代码...
//
for cmd.InProgress() {
//等待下一个响应(无超时)
c.Recv(-1)
//处理命令数据
for _, rsp = range cmd.Data {
if err != nil {
fmt.Println(err)
}
header := imap.AsBytes(rsp.MessageInfo().Attrs["RFC822.HEADER"]) // 包含主题和发件人数据
uid := imap.AsNumber(rsp.MessageInfo().Attrs["UID"]) // 消息唯一标识符
body := imap.AsBytes(rsp.MessageInfo().Attrs["RFC822.TEXT"]) // 消息正文
//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>
英文:
I've read over the go documentation as well as the general imap documentation but can't seem to find the correct way to get the status of a particular message - to know if it is marked as read or unread.
Here's what I've got so far:
//
//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
For output I get:
FETCH
<nil>
LAOYU10 STATUS "INBOX" (Þ) <nil>
The documentation that I've cited has led me to believe that at least one of my methods should be printing if the message is marked as unseen. What am I missing?
EDIT:
I am testing against an inbox (gmail) with four messages. The first two are read and second two are unread. Here is the output for all four messages.
FETCH
<nil>
SIHLB7 STATUS "INBOX" (Û) <nil>
FETCH
<nil>
SIHLB8 STATUS "INBOX" (Ü) <nil>
FETCH
<nil>
SIHLB9 STATUS "INBOX" (Ý) <nil>
FETCH
<nil>
SIHLB10 STATUS "INBOX" (Þ) <nil>
答案1
得分: 2
请注意,确保在您的 IMAP 请求中实际请求了 flags 字段。如果您发出的是 fetch 命令,则需要将 "FLAGS"
作为参数传递给 Fetch
,另外,Attrs
中的 flags 属性是区分大小写的,所以您需要使用 rsp.MessageInfo().Attrs["FLAGS"]
。以下是在 Gmail 中使用 go-imap 库使用 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 not been read!\n", imap.AsNumber(rsp.MessageInfo().Attrs["UID"]))
}
}
}
希望对您有所帮助!
英文:
A Couple things to note, make sure you're actually requesting the flags field in your imap request. If you're issuing a fetch, then you'll have to pass in "FLAGS"
as an argument to Fetch
, additionally, the flags attribute in Attrs
is case sensitive, so you'll need rsp.MessageInfo().Attrs["FLAGS"]
. Below is a working example of using imap in Gmail with the go-imap library, run it with 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"]))
}
}
}
答案2
得分: 1
这会打印出<nil>
,因为没有设置任何标志,这意味着该消息是“未读”的。
英文:
fmt.Println(rsp.MessageInfo().Attrs["Flags"])
That prints <nil>
for you because no flags are set, which means the message is "unseen".
答案3
得分: 1
每个消息在IMAP中都有一个标志列表,其中之一被称为\seen(大小写不敏感,IMAP中的大多数内容都是如此)。如果标志列表不包含该标志,则该消息是未读的。
@jstedfast的答案解释了如何获取标志列表。其余的工作是在空格处进行拆分,并检查列表中的任何单词是否等于\seen。
英文:
Each message has a list of flags in IMAP, one of which is called \seen (case insensitive, as are most things in IMAP). If the flags list does not contain that flag, the message is unseen.
The answer from @jstedfast explains how to get the flags list. The rest is a matter of splitting at whitespace and checking whether any word in the list equals \seen.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论