I am trying to loop through email messages in Outlook using python and get all the attachments in each email, extract them and send them to a different person if it meets a certain criteria. Currently I am saving the attachment and re-attaching it while sending an email. Is there any way where I can do this dynamically and not save the file in the first place
Here is what I have:
import os
import win32com.client
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6)
messages = inbox.Items
messages.Sort("[ReceivedTime]", True)
first_msg = messages.GetFirst()
attachments = first_msg.Attachments
attachment = attachments[0]
attachment.SaveAsFile(os.getcwd() '\\' attachment.filename)
Outlook = win32com.client.Dispatch("Outlook.Application")
mail = Outlook.CreateItem(0)
mail.To = '[email protected]'
mail.Subject = 'This is a sample'
attachment = mail.Attachments.Add(myfolder/file.pdf)
mail.Body = 'Sending an attachment through email using python'
mail.Send()
Is there a method where I can bypass saving the file and send the attached file directly?
CodePudding user response:
The Outlook object model doesn't provide any method or property for dealing with attachments on the fly (without saving them to a disk). The Attachment.SaveAsFile method which saves the attachment to the specified path is exactly what you need.
On the other side you may consider a low-level API on which Outlook is built on - Extended MAPI. It allows opening getting property values with streams without saving them to the disk. The PR_ATTACH_DATA_BIN
property holds the attachment when the value of the PR_ATTACH_METHOD
property is ATTACH_BY_VALUE
, which is the usual attachment method and the only one required to be supported. PR_ATTACH_DATA_BIN
also holds an OLE 1.0 OLESTREAM attachment when the value of PR_ATTACH_METHOD
is ATTACH_OLE. See Opening an attachment for more information.
CodePudding user response:
Not in the Outlook Object Model - saving the attachment as file (if it is a regular olByValue
attachment) and reattaching it is your only option. You can attach the whole original message as an attachment though by passing a MailItem
object as an argument to Attachments.Add
: that will create an embedded message attachment.
As Eugene suggested, you can use Extended MAPI (C or Delphi), but it is not accessible in Python. If using Redemption is an option (I am its author), it allows to pass one attachment (RDOAttachment
) as an argument to RDOMail.Attachments.Add
without saving as file first. That will work for all types of attachments (olByValue
, olOLE
, olEmbeddedItem
, etc.)