'Adding an image to an Outlook MailItem via Python
My goal is to add an image (from local .png file) to an Outlook MailItem using Python.
I have read answers to similar questions on SO (mostly using VBA), but the issue I have is that the mail looks fine (I can see the image) before I send it (and when I look in my Sent Items folder), but when it is received at the other end, the image is broken.
If I manually insert the image in a message (using Insert / Picture / From this Device from the Outlook menu) the email arrives fine, with the image displayed.
Here is the basic code I am using (based mostly on VBA examples):
import win32com.client as wc
def main():
outlook = wc.Dispatch("Outlook.Application")
#Create a new mail item
msg = outlook.CreateItem(0)
#Set some properties
msg.BodyFormat = 2
msg.Subject = 'Here is my chart'
msg.Recipients.Add('[email protected]')
#Add an attachment, with position 0
imageFile = 'C:\\Temp\\myplot.png'
ats = msg.Attachments
att = ats.Add(imageFile,1,0)
#Set the HTMLBody
msg.HTMLBody = '<img src="cid:{0:}" width=200 height=200>'.format(att.FileName)
#Send
msg.Send()
main()
This is what I see in my Sent Items folder:
The HTML in my sent item (using View Source) is this:
<img src="cid:myplot.png" width=200 height=200>
But this is what arrives:
The HTML in the body at the destination is this:
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
</head>
<body>
<img src="cid:[email protected]" width="200" height="200">
</body>
</html>
When I manually insert the image, the received HTML is much longer (so I won't include it all here), but the 'img' tag is here (and this matches what is in the Sent Items folder):
<img width="614" height="461" style="width:6.3958in;height:4.802in" id="Picture_x0020_1" src="cid:[email protected]" alt="Chart, line chart Description automatically generated">
I would appreciate any insights on this! (Sadly Outlook won't let me record a macro to see what the manual process is doing). I have seen one example (from C#) where the SetProperty() method is used on the MailItem to add other items that are not in the Outlook object model (schema, context id), together with a newly created Guid, but is this really necessary?
Using Microsoft 365, Outlook version 2105, Beta Channel
Solution 1:[1]
Create an attachment and set the PR_ATTACH_CONTENT_ID
property (DASL name "http://schemas.microsoft.com/mapi/proptag/0x3712001F"
) using Attachment.PropertyAccessor.SetProperty
.
Your HTML body (MailItem.HTMLBody
property) would then need to reference that image attachment through the cid:
img src="cid:xyz"
where xyz is the value of the PR_ATTACH_CONTENT_ID
property.
Look at an existing message with OutlookSpy (I am its author) - click IMessage button.
attachment = mailitem.Attachments.Add("c:\temp\MyPicture.jpg");
attachment.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x3712001F", "MyId1");
mailitem.HTMLBody = "<html><body>Test image <img src=""cid:MyId1""></body></html>";
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |