3

I'm using the emails library to send mail, but I also need to save it as .msg file. I've done some research and also read the msg format specification and stumbled upon this SO answer that shows how to send mail to the file system in C# and I was wondering if it was possible in Python as well.

Community
  • 1
  • 1
DeepSpace
  • 78,697
  • 11
  • 109
  • 154

6 Answers6

8

It is possible and easy. Let's assume that msg is a previously composed message with all headers and content, and that you want to write it to the file object out. You just need:

gen = email.generator.Generator(out)  # create a generator
gen.flatten(msg)   # write the message to the file object

Full example:

import email

# create a simple message
msg = email.mime.text.MIMEText('''This is a simple message.
And a very simple one.''')
msg['Subject'] = 'Simple message'
msg['From'] = 'sender@sending.domain'
msg['To'] = 'rcpt@receiver.domain'

# open a file and save mail to it
with open('filename.elm', 'w') as out:
    gen = email.generator.Generator(out)
    gen.flatten(msg)

The content of filename.elm is:

Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: Simple message
From: sender@sending.domain
To: rcpt@receiver.domain

This is a simple message.
And a very simple one.
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • Thanks. I created an `email` instance from my `emails` instance and it worked, but is there a way to save it as `msg` instead of `eml`? I've tried to change `with open('filename.elm', 'w')` to `with open('filename.msg', 'w')` but (as expected) outlook couldn't open that file. – DeepSpace Oct 20 '15 at 12:36
  • @DeepSpace The msg format is a binary proprietary format . The only reasonable way to use it is through outlook automation. Searching for `[python] outlook msg file` in SO gave [this question](http://stackoverflow.com/q/18066180/) that could give you some hints. I cannot help you further because I haven't been using outlook for decades. – Serge Ballesta Oct 20 '15 at 13:32
1

it is doable in Python, I tried the following code which saves outlook messages as .msg in a folder. Note:make sure that outlook has write access to the destination folder, by default the destination folder is the location of Python script

from win32com.client import Dispatch

outlook = Dispatch("Outlook.Application").GetNamespace("MAPI") 
inbox = outlook.GetDefaultFolder(6)
messages = inbox.items
for msg in messages:
  name = msg.subject
  name = str(name)
  name = name + ".msg"
  msg.saveas(name)
creimers
  • 4,975
  • 4
  • 33
  • 55
1

Yes it's possible. There are modules for these purposes and it is called MSG PY. For example:

from independentsoft.msg import Message
from independentsoft.msg import Recipient
from independentsoft.msg import ObjectType
from independentsoft.msg import DisplayType
from independentsoft.msg import RecipientType
from independentsoft.msg import MessageFlag
from independentsoft.msg import StoreSupportMask

message = Message()

recipient1 = Recipient()
recipient1.address_type = "SMTP"
recipient1.display_type = DisplayType.MAIL_USER
recipient1.object_type = ObjectType.MAIL_USER
recipient1.display_name = "John Smith"
recipient1.email_address = "John@domain.com"
recipient1.recipient_type = RecipientType.TO

recipient2 = Recipient()
recipient2.address_type = "SMTP"
recipient2.display_type = DisplayType.MAIL_USER
recipient2.object_type = ObjectType.MAIL_USER
recipient2.display_name = "Mary Smith"
recipient2.email_address = "Mary@domain.com"
recipient2.recipient_type = RecipientType.CC

message.subject = "Test"
message.body = "Body text"
message.display_to = "John Smith"
message.display_cc = "Mary Smith"
message.recipients.append(recipient1)
message.recipients.append(recipient2)
message.message_flags.append(MessageFlag.UNSENT)
message.store_support_masks.append(StoreSupportMask.CREATE)

message.save("e:\\message.msg")
Arne S
  • 1,004
  • 14
  • 41
Uros
  • 29
  • 1
  • 1
    Note as per the module creator's website (https://www.independentsoft.de/msgpy/index.html) this isn't free software. Installing via PIP gives you an 'evaluation version' with a 30 day expiry. – TastySlowCooker Feb 03 '21 at 06:26
1

As per python's official examples - https://docs.python.org/3/library/email.examples.html it is possible to save an email as a .msg file, and then later on load it.

from email.message import EmailMessage
from email.parser import BytesParser
from email import policy

# Create the base text message.
msg = EmailMessage()
msg['Subject'] = "Ayons asperges pour le déjeuner"
msg['From'] = Address("Pepé Le Pew", "pepe", "example.com")
msg['To'] = (Address("Penelope Pussycat", "penelope", "example.com"),
             Address("Fabrette Pussycat", "fabrette", "example.com"))
msg.set_content("""\
Salut!

Cela ressemble à un excellent recipie[1] déjeuner.

[1] http://www.yummly.com/recipe/Roasted-Asparagus-Epicurious-203718

--Pepé
""")

# Make a local copy of what we are going to send.
with open('outgoing.msg', 'wb') as f:
    f.write(bytes(msg))

# Load local copy of email
with open('outgoing.msg', 'rb') as fp:
    loaded_msg = BytesParser(policy=policy.default).parse(fp)
Irena
  • 13
  • 5
Sneha Tunga
  • 82
  • 1
  • 8
0

I think the answer to this (but the question is not very clear, and parts of it are in the comments) is:

 import email
 from email.message import EmailMessage

If msg is something created using msg = EmailMessage() and populated with appropriate calls (see https://docs.python.org/3/library/email.examples.html) then msg can be saved using

with open('mymessage.msg', 'wb') as f:
            f.write(bytes(msg))

and that file can be recovered using:

 with open('mymessage.msg', 'rb') as fp:
       msg = email.message_from_binary_file(fp)            
CPBL
  • 3,783
  • 4
  • 34
  • 44
0

I've managed to complete this using Win32Com...

import win32com.client

outlook = win32com.client.Dispatch("Outlook.Application")

mapi = outlook.GetNamespace("MAPI")

inbox = mapi.GetDefaultFolder(6)

messages = inbox.Items

message.SaveAs(os.path.join("output folder", (message.Subject + ".msg")))
Raphael Frei
  • 361
  • 1
  • 10