【发布时间】:2023-02-15 21:27:51
【问题描述】:
我正在尝试使用电子邮件模块从 python3 发送 DSN(传递状态通知,也称为未传递报告)。
DSN 是带有 Content-Type: multipart/report; report-type=delivery-status 的 MIME 消息
消息包含 2 个附件(和可选的第 3 个附件):
-
content-type: text/plain一份人类可读的报告 -
content-type: message/delivery-status一份机器可读的报告 -
content-type: message/rfc822可选的原始消息# # Get data from msg # headers = Parser(policy=default).parsestr(msg) recipient = headers['to'].addresses[0].addr_spec domain = headers['to'].addresses[0].domain date = email.utils.formatdate(localtime=True) # # Create a new email message # dsn = EmailMessage() dsn.policy = policy.SMTP # <-- this didn't help dsn.make_mixed() dsn['From'] = headers['to'] dsn['Date'] = email.utils.localtime(dt=None) dsn['Message-Id'] = email.utils.make_msgid(idstring=None, domain=None) dsn['Subject'] = 'Returned Mail: Refused' dsn['To'] = headers['return-path'] # # The human readable part # dsn.add_attachment("""\ ----- The following address had delivery problems ----- <{}> (unrecoverable error: Refused) """.format(recipient).encode(), maintype="text", subtype="plain", cte=None) # # The machine readable part # dsn.add_attachment("""\ Reporting-MTA: dns; {} Original-Recipient: rfc822;{} Final-Recipient: rfc822;{} Action: failed Status: 5.7.1 Diagnostic-Code: smtp; 571 Delivery not authorized, message returned Last-Attempt-Date: {} """.format(domain, recipient, recipient, date).encode('us-ascii'), maintype="message", # <--- these 2 lines cause subtype="delivery-status", # <--- the issue cte=None) # # The original message # dsn.add_attachment(msg.encode(), maintype="message", subtype="rfc822", cte=None) # # Set the Content-Type header in the message headers # dsn.replace_header('Content-Type', 'multipart/report') dsn.set_param('report-type', 'delivery-status') print(dsn) # <--- Dies in here打印 DSN 时,我收到以下回溯:
Traceback (most recent call last): File "./send-dsn.py", line 97, in <module> print(dsn) File "/usr/lib/python3.9/email/message.py", line 971, in __str__ return self.as_string(policy=self.policy.clone(utf8=True)) File "/usr/lib/python3.9/email/message.py", line 968, in as_string return super().as_string(unixfrom, maxheaderlen, policy) File "/usr/lib/python3.9/email/message.py", line 158, in as_string g.flatten(self, unixfrom=unixfrom) File "/usr/lib/python3.9/email/generator.py", line 116, in flatten self._write(msg) File "/usr/lib/python3.9/email/generator.py", line 181, in _write self._dispatch(msg) File "/usr/lib/python3.9/email/generator.py", line 218, in _dispatch meth(msg) File "/usr/lib/python3.9/email/generator.py", line 276, in _handle_multipart g.flatten(part, unixfrom=False, linesep=self._NL) File "/usr/lib/python3.9/email/generator.py", line 116, in flatten self._write(msg) File "/usr/lib/python3.9/email/generator.py", line 181, in _write self._dispatch(msg) File "/usr/lib/python3.9/email/generator.py", line 218, in _dispatch meth(msg) File "/usr/lib/python3.9/email/generator.py", line 335, in _handle_message_delivery_status g.flatten(part, unixfrom=False, linesep=self._NL) File "/usr/lib/python3.9/email/generator.py", line 107, in flatten old_msg_policy = msg.policy AttributeError: 'str' object has no attribute 'policy'问题似乎是第二个附件的主要类型和子类型,
content-type: message/delivery-status附件。如果我将其更改为text/plain,则 DSN 会打印出第二个附件的内容类型错误。- 这是使用此模块构建 DSN 的正确方法吗?
- 如何修复此策略属性问题?
【问题讨论】:
-
我试着玩弄这段代码,但我真的弄不明白。您似乎在附件代码中发现了错误。也许您只需要生成
msg.as_string()然后用内容类型替换其中的传递报告,尽管这是一个糟糕的解决方法。
标签: python python-3.x email