Search code examples
pythonoutlookpywin32

Python: Export Messages as .msg using pywin32.client


I am hitting a road block with exporting outlook messages as .msg files. I'm not sure on how to accomplish this task. I have a program that currently reads the email and exports the attachments and once it completes it moves the message to a processed folder so I can keep track of what has been completed. I need to add a function that exports the entire email itself to a folder on the local machine. Has anyone accomplished this using pywin32.client?

Here is the program as it stands now. (excuse the mess its still in progress)

import os
import win32com.client
import csv
import datetime
from random import randint

ATTACHMENTS_FOLDER = "C:\\EMAILS"
LOG_PATH = 'C:\\EMAILS\\log.csv'
COUNTER = 1
SUBFOLDER_LIST = ["TEST"]
UPLOAD_LIST = 'C:\\EMAILS\\logupload%d.csv' % randint(2,150000)


def ExportMessages (Folder, item):
    #No IDEA!
    pass

def process_attachment(sender, subject, attachment, messagedate):
  """
  :param sender:
  :param subject:
  :param attachment:
  :param messagedate:
  """
  global count
  count = 0
  try:
    filepath = os.path.join(ATTACHMENTS_FOLDER, "RAN-%dSEN-%sSUB-%s%s" % (randint(2,100000),str(sender), str(subject), attachment))
    count = count +1
    print "Trying", filepath
    open(filepath, "r")
    os.remove(filepath)
  except IOError:
    pass

  try:
    attachment.SaveAsFile(filepath)
    row = [messagedate, sender, subject, count]
    row2 = [messagedate, sender, subject, filepath]
    w = csv.writer(csv_file)
    w2 = csv.writer(csv_file2)
    w.writerow(row)
    w2.writerow(row2)
  except:
    pass

def move_message_fail(message, folder):
  """
  :param message:
  :param folder:
  """
  print "Moving:", message.Subject
  proc_folder = folder.Folders("Failed")
  message.Move(proc_folder)

def move_message(folder, message):
  """
  :param folder:
  :param message:
  """
  print "Moving:", message.Subject
  proc_folder = folder.Folders("Processed")
  message.Move(proc_folder)

def process_message(message, folder):
  """
  :param message:
  :param folder:
  """
  global vin_num
  vin_num = ''
  print "Message:", message.Subject
  vin = message.Subject
  sender = message.SenderName
  if folder == SUBFOLDER_LIST[0]:
    for i in vin.split(' '):
        if '-' in i:
            vin_num = i
    if vin_num:
        now = datetime.datetime.now()
        messagedate = now.strftime("%m-%d-%Y")
        attachments = message.Attachments
        for n_attachment in range(attachments.Count):
            attachment = attachments.Item(n_attachment + 1)
            #if attachment.Type == win32com.client.constants.CdoFileData:
            process_attachment(sender, vin_num, attachment, messagedate)
            #message.Update()
            move_message(folder, message, up_folder)
    else:
        move_message_fail(message, folder)
  else:
    vin_num = vin.split(' ')[1]
    now = datetime.datetime.now()
    messagedate = now.strftime("%m-%d-%Y")
    attachments = message.Attachments
    for n_attachment in range(attachments.Count):
        attachment = attachments.Item(n_attachment + 1)
        #if attachment.Type == win32com.client.constants.CdoFileData:
        process_attachment(sender, vin_num, attachment, messagedate)
        #message.Update()
        move_message(folder, message, up_folder)



if __name__ == '__main__':
  csv_file = open(LOG_PATH, "ab")
  csv_file2 = open(UPLOAD_LIST, "wb")
  for i in SUBFOLDER_LIST:
    outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
    one_folder = outlook.Folders(1)
    two_folder = one_folder.Folders("Inbox")
    three_folder = two_folder.Folders(i)
    messages = three_folder.Items
    message = messages.GetFirst()
    while message:
      process_message(message, i)
      ExportMessages(three_folder, message)
      message = messages.GetNext()

Solution

  • Call MailItem.SaveAs and pass olMsg or olMsgUnicode as the second (Format) parameter.