Шифрование сообщений Office365 удаляет вложения электронной почты при отправке с Python - PullRequest
0 голосов
/ 16 мая 2018

У меня есть python3 def, который отправляет html-сообщение через учетную запись office 365. У нас есть требование, чтобы сообщение отправлялось с шифрованием сообщений Office365 (OME). Это дает пользователю html-вложение, заставляет его войти в систему через офис 365, прежде чем просматривать электронную почту в Интернете. Мы включили OME для всех сообщений, отправленных на учетную запись электронной почты, которая будет отправлять сообщение. Вот некоторые наблюдения:

  1. При отправке через python def через учетную запись с поддержкой OME вложения при просмотре зашифрованного сообщения отсутствуют.
  2. При отправке через python def через обычную учетную запись, вложение отображается в электронном письме, как и ожидалось
  3. При ручной отправке электронного письма через учетную запись с поддержкой OME с использованием веб-сайта office365 или Outlook, вложение отображается в электронном письме, как и ожидалось
  4. Код электронной почты включает в себя прикрепление изображений для HTML, и он отлично отображается как в обычных, так и в зашифрованных сообщениях.

Могу поспорить, что мне не хватает случайного заголовка или чего-то еще - кто-нибудь знает, что происходит? Вот код Python:

def sendHTMLEmail(
    emaillist,
    subject,
    body,
    altBody,
    logger,
    mailuser,
    mailpassword,
    fileAttachments=None,
    embeddedImages=None
):  
    """
    Send an html-enabled email to a number of recipients. This method includes the options of embedding images in the email,
    attaching files to the email, and providing alternative plain text in case of an error rendering the HTML. 

    # Arguments
        emaillist (list[string]): List of email addresses to send to
        subject (string): Subject line of the email
        body (string): Body of the email. This can be plain text or HTML, depending on the email. 
        altBody (string): Alternate body text of the email. This will be displayed if the HTML cannot be rendered.
        logger (JvpyLog): optional logger override parameter 
        mailuser (string): SMTP username to send the mail as
        mailpassword (string): login password of the SMTP user
        fileAttachments (list[string]): list of fully qualified filenames to attach to the email
        embeddedImages (list[dict]): list of embeddedImage dicts specifying images to be embedded in the HTML boddy of the email

    # Special Types
    ###### embeddedImages [dict]:
    ```python
    {
        filename (string): fully qualified filename of the image
        imageid (string): unique id for the image. This will be refrernced in the HTML body of the email and repaced by the actual image. 
    }
    ```
    """
    logger.info("Sending email to the following recipients: " + str(emaillist))

    # Define these once; use them twice!
    strFrom = mailuser
    strTo = ", ".join(emaillist)

    # Create the root message and fill in the from, to, and subject headers
    msgRoot = MIMEMultipart('related')
    msgRoot['Subject'] = subject
    msgRoot['From'] = strFrom
    msgRoot['To'] = strTo
    msgRoot.preamble = 'This is a multi-part message in MIME format.'

    # Encapsulate the plain and HTML versions of the message body in an
    # 'alternative' part, so message agents can decide which they want to display.
    msgAlternative = MIMEMultipart('alternative')
    msgRoot.attach(msgAlternative)

    msgText = MIMEText(altBody)
    msgAlternative.attach(msgText)

    # We reference the image in the IMG SRC attribute by the ID we give it below
    msgText = MIMEText(body, 'html')
    msgAlternative.attach(msgText)

    # embed images if populated
    if embeddedImages is not None:
        for image in embeddedImages:
            logger.info("Embedding Image: " + str(image['filename']) + " as content id: " + str(image['imageid']))
            fp = open(image['filename'], 'rb')
            msgImage = MIMEImage(fp.read())
            fp.close()

            # Define the image's ID as referenced above
            msgImage.add_header('Content-ID', image['imageid'])
            msgRoot.attach(msgImage)

    # add attachements if populated
    if fileAttachments is not None:
        for filename in fileAttachments:
            logger.info("Attaching File: " + str(filename))
            part = MIMEApplication(
                open(filename,"rb").read(),
                Name=os.path.basename(filename)
            )
            part['Content-Disposition'] = 'attachment; filename="{0}"'.format(os.path.basename(filename))
            ## add mimetype based on the file extension
            mimetype = mimetypes.types_map["." + os.path.basename(filename).lower().split(".")[1]]
            part['Content-Type'] = mimetype + '; name="{0}"'.format(os.path.basename(filename))
            msgRoot.attach(part)

    # Send the email (this example assumes SMTP authentication is required)
    server = smtplib.SMTP('smtp.office365.com', 587)
    server.ehlo()
    server.starttls()
    server.ehlo()
    server.login(mailuser, mailpassword)
    server.sendmail(strFrom, emaillist, msgRoot.as_string())
    server.quit()

    logger.info("email sent.")

1 Ответ

0 голосов
/ 17 мая 2018

Понял: я сравнивал исходные файлы электронной почты из ручной отправки и отправки с моим кодом Python и заметил, что заголовок Content-Type отличается.Код Python использовал 'multipart / related', в то время как отправка вручную использовала 'multipart / mixed'.Это оказалось проблемой.Я изменил msgRoot = MIMEMultipart('related') на msgRoot = MIMEMultipart(), и это решило проблему.

Странно то, что незашифрованные электронные письма, отправленные с помощью кода Python, по-прежнему правильно отображались с вложением - это были только безопасные электронные письма, которые плохо воспроизводились с типом контента «multipart / related».Я построил свой код на некотором примере кода, который использовал «multipart / related», поэтому я включил его в свой исходный код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...