Save email as .eml file with python

1.4k Views Asked by At

I am trying to export an Email message obtained with aiosmtpd to an *.eml file that I can later open with any *.eml viewer or email client like Thunderbird or Mail.

    async def handle_DATA(self, server, session, envelope) -> str:
        msg: EmailMessage = message_from_bytes(envelope.content, policy=policy.SMTPUTF8)

        with open("test.eml", 'wb') as outfile:
            outfile.write(msg.as_bytes())

I've also tried to save the file with Generator with both unixfrom=False and unixfrom=False and same thing.

        with open("test.eml", 'w') as file:
            emlGenerator = generator.Generator(file)
            emlGenerator.flatten(msg, unixfrom=False)

The file gets created correctly but not all the eml files can be read correctly by Mail or Thunderbird.

Emails received from gmail.com are created correctly but emails received from protonmail.com are not. Eml files created from Protonmail emails can be opened but only from and to parameters of the email can be seen. I can't see the content neither the attachments in it.

I guess it does not have the format that eml parsers are expecting to see.

I've tried with different policies (like policy.SMTP, policy.default, ...).

What is the proper way to create eml files with python?

NOTE: The content of the EML file for Protonmail contains the following This is an OpenPGP/MIME signed message (RFC 4880 and 3156). Could this be related with the lack of correct parsing for Protonmail emails?

2

There are 2 best solutions below

5
Xavi Conde On

I had the same issue with the Email API. Although it can not always be opened directly as an .eml file, it is correctly opened if the message is sent to an SMTP server. I understand the Email API generates a string that represents the data sent to the SMTP server. That data is to be interpreted by an SMTP server, not a client. The SMTP server will interpret this data and store it as if finds more convenient (i.e. storing it in a db).

A client like Thunderbird will retrieve the message using POP3 or IMAP, but that doesn't mean that it is retrieving the same message that was sent to the SMTP server, since the server might store it in a different format.

0
wopr_xl On

NOTE: The content of the EML file for Protonmail contains the following This is an OpenPGP/MIME signed message (RFC 4880 and 3156). Could this be related with the lack of correct parsing for Protonmail emails?

Yes. Protonmail encrypts emails stored on their servers using PGP. So in order to view those encrypted emails opened in Thunderbird, the user would need to follow Protonmail's directions to download their public and private PGP keys, and then follow these directions to install those inside Thunderbird. For Apple Mail, it appears that users would need to install GPGTools.

Another option would be to roll your own PGP implementation using Python, to decrypt the text and attachments of the Protonmail emails as your app downloads and converts them to .eml. Here is a SO answer discussing one approach to that. However, that would only work if these emails are coming SOLELY from a Protonmail account that you (the developer) control. Otherwise, your users would have to send you their PGP keys -- which for obvious security reasons is not a viable solution.