Python IMAP:无法标记邮件为已读

3 投票
2 回答
5152 浏览
提问于 2025-04-17 18:32

我正在尝试使用Python的IMAP库将一封邮件标记为已读。就像这个例子中提到的那样:Python, IMAP和GMail. 将邮件标记为已读

我选择了GMail账户的“所有邮件”文件夹,然后通过搜索命令获取了一封特定邮件的UID。接着,我用这个UID尝试将邮件标记为已读,但没有成功。

    result, data = mail.uid('fetch', email_uid, '(FLAGS)')

    print "RESULT: ",result,data

    mail.select(folder_name, readonly=False)
    result, data = mail.store(email_uid, '+FLAGS', '\\Seen')

    print "RESULT OF OPERATION FOR UID",email_uid,result,data

无论我运行这段代码多少次,我得到的标志中总是没有\Seen这个标志。

这是一个执行示例(可以忽略Django的打印输出):

FINAL QUERY: (SENTSINCE 07-Mar-2013 SENTBEFORE 11-Mar-2013 LARGER 7508 SMALLER 7510)
RESULT:  OK ['31424 (UID 54264 FLAGS (NotJunk $NotJunk))']
RESULT OF OPERATION FOR UID 54264 OK [None]

[09/Mar/2013 17:30:37] "GET /api/mark_as_read/320/?token=8e3c057b841b75c864685786b2a9657aadf17e3bfb991b103b7c4b3ffdd2a753&refresh_mode=all&folder_mode=inbox HTTP/1.1" 200 144
FINAL QUERY: (SENTSINCE 07-Mar-2013 SENTBEFORE 11-Mar-2013 LARGER 7508 SMALLER 7510)
RESULT:  OK ['31424 (UID 54264 FLAGS (NotJunk $NotJunk))']
RESULT OF OPERATION FOR UID 54264 OK [None]

[09/Mar/2013 17:30:44] "GET /api/mark_as_read/320/?token=8e3c057b841b75c864685786b2a9657aadf17e3bfb991b103b7c4b3ffdd2a753&refresh_mode=all&folder_mode=inbox HTTP/1.1" 200 144
FINAL QUERY: (SENTSINCE 07-Mar-2013 SENTBEFORE 11-Mar-2013 LARGER 7508 SMALLER 7510)
RESULT:  OK ['31424 (UID 54264 FLAGS (NotJunk $NotJunk \\Seen))']
RESULT OF OPERATION FOR UID 54264 OK [None]

我尝试了多种变体。我试着设置标志为\Seen、Seen、\Seen、SEEN,有括号和没有括号,但我不知道除了这些我还能尝试什么。

我怀疑这里可能有一些非常具体的细节——也许GMail的“所有邮件”文件夹不允许将邮件标记为已读?

我也不确定在mail.store命令返回的(result, data)元组中,data变量是否应该在正常执行时包含"[None]",还是说这意味着有问题。

如果我尝试设置一个错误的标志,比如\\Seen,mail.store命令会抛出错误。所以设置\Seen标志是一个有效的IMAP标志。

我不知道接下来该尝试什么。

任何帮助都将非常感谢。

2 个回答

0

你可以使用我的这个工具包:https://pypi.org/project/imap-tools/

with MailBox('imap.mail.com').login('test@mail.com', 'pwd', 'INBOX') as mailbox:

    # SEEN: mark all messages sent at 05.03.2007 in current folder as unseen, *in bulk
    mailbox.seen(mailbox.uids("SENTON 05-Mar-2007"), False)
    
0

IMAP协议中关于STORE命令的规范并没有提供通过UID来设置标志的选项。你只能通过message set来设置标志,就像你提到的例子那样。
之所以有时候能成功,是因为你的UID和message set的序列号相对接近(比如3142454264)。

RESULT:  OK ['31424 (UID 54264 FLAGS (NotJunk $NotJunk))']

实际上,你并不是通过UID来设置标志,而是通过message set来设置的……这有时会对应到一个UID


不过,你是可以通过UID来设置标志的,只是不能用STORE命令。你可以使用一个UID命令,第一个参数是store,来设置标志:

result, data = mail.uid('store', '542648', '+FLAGS', '(\\Seen)')  

如果成功,服务器会返回与你使用的UID对应的message set,例如(用你的例子):

OK ['31424 (FLAGS (\\Seen))']

撰写回答