Python:如何通过IMAP将带BCC收件人的草稿邮件存储到Exchange服务器?

6 投票
3 回答
5360 浏览
提问于 2025-04-15 11:11

我尝试通过IMAP把草稿邮件存储到运行在MS Exchange上的一个文件夹里。一切都很好,除了Bcc收件人在服务器上存储的草稿邮件中没有显示出来。如果我用MS Outlook发送邮件,Bcc收件人也收不到邮件。不过,如果我用Python读取存储在服务器上的邮件草稿,我可以看到Bcc的内容。

以下的Python代码可以复现这个问题:

import imaplib 
import time 
from email.MIMEMultipart import MIMEMultipart 
from email.MIMEText import MIMEText 

message = MIMEMultipart() 
message['Subject'] = 'Test Draft' 
message['From'] = 'test@test.net' 
message['to'] = 'test@test.com' 
message['cc'] = 'testcc@test.com' 
message['bcc'] = 'testbcc@test.com' 
message.attach(MIMEText('This is a test.\n')) 

server= imaplib.IMAP4('the.ser.ver.ip') 
server.login('test', 'test') 
server.append("Drafts" 
              ,'\Draft' 
              ,imaplib.Time2Internaldate(time.time()) 
              ,str(message)) 
server.logout() 

当我运行这段代码时,草稿会被存储到Exchange服务器上的Draft文件夹里。但是如果我用MS Outlook查看这个草稿,里面并没有包含bcc收件人(message['bcc'] = 'testbcc@test.com')。Messagetofromcc都正常,没有错误。

如果我从Exchange文件夹下载已经包含Bcc的草稿,我也能看到Bcc。只有上传的时候对我来说不行。

任何帮助都非常感谢。谢谢。顺便说一下,MAPI不是一个选项。

更新X-Receiver对我没有用。关于在Outlook中玩弄IMAP文件夹,我得到了一个有趣的结果。如果我通过Outlook中的IMAP文件夹访问草稿,我能看到Bcc。但是如果我通过MAPI文件夹访问,就看不到了。我会再多试试这个。

结论:实际上,这段代码运行得很好。下面是我找到的答案。

3 个回答

1

试着设置这个不同版本的BCC头:

X-Receiver: someguy@gmail.com

特别是在Exchange中,当你发送时,它会把这个当作BCC处理。不过我敢打赌,当你通过IMAP写的时候,它不会把它去掉。你可以通过重复这一行来添加多个BCC收件人。

这显然是一个完全的临时解决办法。

1

这可能是设计上的原因。毕竟,bcc(密件抄送)的主要目的就是让收件人之间互相看不到对方。

我明白你并不是在发送邮件,只是在存储它。但我猜当邮件通过IMAP.append添加到文件夹时,Exchange的内部规则就会生效,从而把bcc字段去掉。

显然,当使用Outlook将邮件保存到文件夹时,bcc字段是不会被去掉的。不过,我猜Outlook是通过某种内部机制(比如MAPI)与Exchange进行沟通的。

以上只是我的猜测。

你可以尝试一些有趣的事情:

  • 在一个空的Outlook/MAPI配置中,创建一个IMAP账户。设置它在Exchange服务器上存储草稿和已发送邮件。
  • 看看Outlook使用IMAP时,能否正确保存草稿的bcc字段。

我用Evolution邮件客户端通过IMAP连接到Exchange尝试了上述操作。然后我用正常方式连接的Outlook查看了草稿和已发送邮件,发现这两个地方的bcc字段都缺失了。

我相信这支持了我的理论。

6

其实,这段代码运行得很好。它能正确创建邮件,并包含所有正确的头信息,包括密件抄送(bcc)。

邮件客户端是怎么显示bcc的?

邮件客户端(比如我用的Python或MS Outlook通过IMAP或MAPI)决定是否以及如何显示bcc头信息。例如,Outlook在IMAP文件夹中不会显示bcc头信息。这是为了让bcc的收件人之间互相看不到对方的地址,除非在邮件发送之前就已经把这些信息去掉了。标准并没有明确说明一个bcc收件人是否可以看到其他所有的bcc收件人,具体可以参考维基百科

发送邮件时,谁来处理bcc?

假设我们在邮件客户端中草拟了一封邮件,并将其存储在IMAP或MAPI文件夹中。提供IMAP/MAPI文件夹的服务器不会改变草稿邮件。发送邮件时,bcc头信息的处理方式取决于具体的实现,可能与邮件客户端和邮件传输代理(比如我用的MS Exchange Server)有关。简单来说,大家对是邮件客户端负责去掉bcc头信息,还是邮件传输代理负责这一点并没有统一的看法。不过,大多数开发者认为应该是邮件客户端来处理,而邮件传输代理不应该去动邮件(例如MS Exchange、MS SMTP、Exim、OpenWave)。在这种情况下,邮件传输代理会根据SMTP通信中的RCPT TO:将邮件发送给收件人,其他部分保持不变。不过,也有一些邮件传输代理会从邮件中去掉bcc头信息(例如sendmail、Lotus Notes)。关于这个问题的详细讨论可以在Exim邮件列表中找到,链接在这里

在MS Outlook和MS Exchange的情况下,MS Outlook从不发送bcc(而是为每个bcc收件人发送单独的邮件),而MS Exchange则不会修改邮件头,而是将完整的邮件(可能包括bcc收件人)发送给RCPT TO:中定义的收件人。

总结

我之前没有意识到bcc的处理没有保证的行为,通常是由客户端来处理bcc。我会重写我的Python代码,针对每个bcc收件人生成一封邮件。

撰写回答