如何用exchangelib转发带附件的Outlook新邮件且保留原邮件?
解决exchangelib邮件转发失败的问题
我来帮你搞定这个邮件转发的问题!你的代码里转发逻辑存在几个关键错误,我帮你修正并解释清楚:
核心问题分析
- 你错误地从已发送文件夹(
a.sent)中查找邮件来操作,这完全没必要——我们要转发的就是刚收到的那封邮件item本身。 - 使用
reply()方法是回复原邮件发件人,不是转发到指定地址,转发应该用forward()方法。 send()方法的参数不正确,exchangelib中转发对象调用send()不需要传id参数,直接调用即可。
修正后的完整代码
s = a.inbox.unread_count # 未读邮件数量 if s > 0: print(f'{s} 收到新邮件') # 遍历未读邮件(改用filter筛选未读更准确,避免包含已读邮件) for item in a.inbox.filter(is_read=False).order_by('-datetime_received'): print( item.subject, # 邮件主题 item.sender.name, # 更准确的发件人名称(替换原last_modified_name) item.display_cc, # 抄送 item.text_body, # 文本内容 item.message_id, ) # 标记邮件为已读并保存,原邮件会保留在收件箱中 item.is_read = True item.save() # 正确的转发逻辑 # 创建转发邮件对象,指定目标收件人 forward_item = item.forward( to_recipients=['eagl69@mail.ru'], # 可选:添加自定义转发说明 # body='这是自动转发的邮件,请查收' ) # 发送转发邮件 forward_item.send() # 保存附件到本地(优化异常处理逻辑) for attachment in item.attachments: # 跳过无文件名的无效附件 if not hasattr(attachment, 'name') or not attachment.name: print('跳过无文件名的附件') continue try: with open(attachment.name, 'wb') as f: f.write(attachment.content) print(f'附件 {attachment.name} 保存成功') except Exception as e: print(f'保存附件失败:{str(e)}') else: print('无新邮件')
额外优化点说明
- 未读邮件筛选更可靠:原代码用
my_folder.all()[:s]可能会混入已读邮件,改用a.inbox.filter(is_read=False)直接定位未读邮件更准确。 - 发件人字段修正:
item.last_modified_name不一定代表发件人,item.sender.name能精准获取发件人名称。 - 附件处理更健壮:增加了对无文件名附件的判断,同时捕获具体异常信息,方便排查保存失败的原因。
- 转发自定义内容:如果需要在转发时添加自己的说明,直接在
forward()方法中传入body参数即可。
这样修改后,就能正确将新收到的带附件邮件转发到指定地址,同时原邮件会保留在收件箱中(仅标记为已读,不会被删除或移动)。
内容的提问来源于stack exchange,提问作者Юрий Пикин




