[Python]Почему вложения электронной почты в формате PDF не отображаются в Outlook/Thunderbird, хотя они отображаются в Gmail? (Отправлено из среды Python)

Я только что присоединился к проекту и пытаюсь понять, почему некоторые электронные письма отображаются в Gmail должным образом, но когда я открываю их с помощью клиента, такого как Thunderbird или Outlook, теперь отображаются прикрепленные PDF-файлы. В качестве дополнительной детали, если я перешлю почту из Thunderbird/Tutlook в учетную запись Gmail, появится прикрепленный PDF-файл, и если я отправлю его обратно в подключенную учетную запись Thunderbird/Outlook, он снова появится, поэтому Gmail исправляет что-то не так в коде. .

Это мой второй раз, когда я имею дело с электронными письмами, первый из которых в основном копировал некоторый код, чтобы посмотреть, работает ли он, поэтому, если вы готовы объяснить мне это в дополнение к тому, чтобы помочь мне исправить это, я был бы очень признателен. Я опубликую код здесь, а затем добавлю дополнительную информацию о том, что я пробовал ниже, чтобы сделать это немного чище. Итак, вот код:

from email.message import EmailMessage
from email import encoders
from email.mime.base import MIMEBase
import smtplib



msg = EmailMessage()
msg['Subject'] = subject
msg['From'] = "someaddress"
msg['To'] = user_email
msg.set_content('Certification')
msg.add_alternative("""<!DOCTYPE html>
        <html>
            <body>
                Stuff...
            </body>
        </html>
        """, subtype='html')

filename = 'somefilename'
pdf_filename = 'certificate.pdf'
with open(filename, "rb") as attachment:
    part = MIMEBase("application", "octet-stream")
    part.set_payload(attachment.read())

encoders.encode_base64(part)
part.add_header(
    "Content-Disposition",
    "attachment", filename=pdf_filename
)
try:
    msg.attach(part)
    with smtplib.SMTP('someIP', port) as smtp:
        smtp.send_message(msg)

Я видел некоторые похожие проблемы (или фактически ту же проблему) раньше, и некоторые решения предлагали использовать объект сообщения MIMEMultipart-mixed вместо сообщения электронной почты, например: msg=MIMEMultipart('mixed') вместо msg = EmailMessage(), но поскольку add_alternative не является методом MIMEMultipart, я не могу сделать это без изменения этой части. (Вышеупомянутое было предложено на этот пост - точно такая же проблема, как у меня, но, к сожалению, я не смог использовать то же исправление)

То, что я пытался сделать, это вызвать msg.make_mixed() ниже msg=Email.Message() в надежде, что смешанный тип (я еще не понимаю типы электронной почты) решит проблему, но когда я попытался отправить электронное письмо таким образом, я получил статус = 4, не удалось отправить файл , ошибка.

Я также был бы очень признателен, если бы вы предложили какой-либо ресурс, чтобы узнать больше об отправке и получении электронных писем (с точки зрения Python).

Благодарю вас!


person Basil    schedule 09.03.2021    source источник
comment
Некоторые почтовые клиенты предпочитают более конкретный тип mime для вложения, установите подобно этому   -  person snakecharmerb    schedule 09.03.2021
comment
Благодарю вас за информацию!   -  person Basil    schedule 09.03.2021


Ответы (1)


Проблема здесь в том, что вы напрямую прикрепили предварительно созданную часть MIME к составному/альтернативному сообщению. Он заканчивается некорректным сообщением, которое может быть плохо обработано почтовыми программами.

В интерфейсе email.message следует использовать метод add_attachement. Он будет обрабатывать кодировку base64 и изменит сообщение на составное/смешанное:

with open(filename, "rb") as attachment:
    msg.add_attachment(attachment.read(), maintype='application',
           subtype='octet-stream', filename=pdf_filename)

try:
    with smtplib.SMTP('someIP', port) as smtp:
        smtp.send_message(msg)
person Serge Ballesta    schedule 09.03.2021
comment
Спасибо большое за ответ и объяснение! - person Basil; 09.03.2021