Я создал образец функции для проверки отправки электронных писем с приложенным html-файлом, который я намерен использовать для составления отчетов об автоматических тестовых прогонах в будущем (заменив существующий внешний скрипт powershell).Обратите внимание, что я прикрепляю html-файл, а не использую html в качестве встроенного текста в теле.Я использую службу учетной записи mailgun smtp нашей компании для отправки электронной почты.
У меня, похоже, проблема с Outlook 365 (размещен в Интернете - используется домен outlook.office.com), который либо отклоняет, либо блокирует отправленную электронную почту., но интересно то же самое письмо получено и принято моим личным адресом горячей почты (домен outlook.live.com).Я обнаружил блоки Outlook 365 или не принимает электронную почту, когда я пытаюсь назвать файл в объекте сообщения электронной почты.Но если я не назову его, он пройдет (с именем по умолчанию "ATT00001.htm").
Мой код для этого ниже, но ключевая строка, кажется,
msg.add_attachment(open_file.read(), maintype='text', subtype='html', filename=filename)
Если я опускаю ключ имени файла, он работает (но с назначенным по умолчанию именем файла), например,
msg.add_attachment(open_file.read(), maintype='text', subtype='html')
У меня есть подозрение, что-то взаголовок вложения или расположение содержимого, с которым Outlook 365 не согласен, но я не уверен, что это такое или как обойти.
Я использую следующее (Python 3.6.5, наМашина Windows 10, smtplib и email.message, кажется, встроены)
Вот код:
import smtplib
from email.message import EmailMessage
import os
def send_mail():
MAILGUN_SMTP_LOGIN = "<my company's mailgun login>"
MAILGUN_SMTP_PASSWORD = "<my company's mailgun password>"
fromaddr = "muppet@sharklasers.com" # the from address seems to be inconsequential
toaddr = ['me@mycompanysdomainusingoffice365.com.au', 'me@hotmail.com']
msg = EmailMessage()
msg.preamble = 'This is preamble. Not sure where it should show in the email'
msg['From'] = fromaddr
msg['To'] = ', '.join(toaddr)
msg['Subject'] = 'Testing attached html results send'
msg.set_content(""" This is a test of attached html """)
filename = 'api_automatedtests_20180903_1341.html'
filepath = os.path.abspath('D:/work/temp/api_automatedtests_20180903_1341.html')
open_file = open(filepath, "rb")
# msg.make_mixed()
msg.add_attachment(open_file.read(), maintype='text', subtype='html', filename=filename)
# msg.add_attachment(open_file.read(), maintype='text', subtype='html')
server = smtplib.SMTP(host="smtp.mailgun.org", port=587)
server.ehlo()
server.starttls()
server.login(MAILGUN_SMTP_LOGIN, MAILGUN_SMTP_PASSWORD)
server.set_debuglevel(1)
server.send_message(msg)
server.quit()
if __name__ == "__main__":
send_mail()
Что я пробовал
Пробная отправка с тем же кодом с использованием текстового файла (с соответствующими типами).например,
msg.add_attachment(open_file.read(), maintype='text', subtype='plain', filename=filename)
Результат: Это работает как ожидалось (приходит с заданным именем - имя файла является строковой переменной, например, testfile.txt)
с добавлением сообщения.make_mixed (), чтобы убедиться, что оно идентифицируется как составное сообщение.Результат: без эффекта
Включение отладки smtp 1-го уровня, Результат: Mailgun говорит, что все работает нормально (и сообщения отображаются в моей учетной записи hotmail, как и ожидалось)
Не используется ключ имени файла в вызове msg.add_attachment.Результат: это работает, вложение приходит на ATT00001.htm Интересно, что имя по умолчанию - * .htm, а имя файла, которое я пытаюсь использовать, - * .html
. Пробовал использовать имя файла с * .htm и подтипом 'htm' (вместо html). Результат: То же, что и для html (получено в hotmail, но не в outlook 365)
Попытка с использованием универсальных типов maintype = '' application ', subtype =' octet-stream '.
например, msg.add_attachment(open_file.read(), maintype='application', subtype='octet-stream', filename=filename)
Результат: То же, что и для html (получено в hotmail, но не в outlook 365)
Пробовал с помощью mimetypes.guess, как показано в этой ссылке
https://docs.python.org/3.6/library/email.examples.html
ctype, encoding = mimetypes.guess_type (path), если ctype равен None или кодировка не равна None: # Невозможно угадать, или файл закодирован (сжат), поэтому # используйте общий тип bag-of-bit.ctype = 'application / octet-stream' maintype, subtype = ctype.split ('/', 1) с открытым (path, 'rb') в виде fp: msg.add_attachment (fp.read (), maintype = maintype, subtype= подтип, имя файла = имя файла)
Результат: определяется как maintype = 'text', subtype = 'html', и я получаю тот же результат, что и с моим исходным кодом (то есть приходит в hotmail, но блокируется 365).
Проверка моих папок спама и беспорядка - там не было
Есть какие-либо предложения о том, почему использование имени файла будет нарушать его?
Обновление После отправки на другие адреса электронной почты различных поставщиков я обнаружил:
1) muppet@sharklasers.com не был доверенным отправителем (может изменить это)
2) Я обнаружил, что вложение помечено как небезопасное. Html-файл взят из html-отчета pytest с опцией «один файл». Он содержит JavaScript для расширителей строк. Gmail предупреждает, что вложение может быть небезопасным (Office 365 просто блокирует электронную почту вообще).
Не уверен, как обойти 2). Я могу отправить один и тот же файл себе между outlook 365 и gmail, и наоборот, и файл не будет заблокирован. Он блокируется только тогда, когда я использую вышеуказанный скрипт с использованием библиотек python и Mailgun SMTP. Я подозреваю, что мне нужно что-то изменить в заголовке письма, чтобы обойти это. Но я не знаю что.
Кажется, существует некоторая связь между попыткой добавить имя файла и вложение, помеченное как небезопасное