Tut: How to add embedded images in CDO mail

antic

Perch
You know that Eureka moment, when you've been trying to work out how to achieve something, and all you find are crumbs on the web, but eventually you try a few things, nut it out and find a solution that suddenly works?

Well, if anyone has ever wanted to *embed* images in their HTML emails (i.e. as opposed to using IMG tags linked to external images, which sometimes don't show in browsers like Thunderbird due to security settings) then read on.

I'll be brief, because it's 3am here, as it always is when these things happen. :) So here's the code:
Code:
Const CdoReferenceTypeName = 1
Dim objCDO, objBP
Set objCDO = Server.CreateObject("CDO.Message")
objCDO.MimeFormatted = True
objCDO.To = "[email protected]"
objCDO.From = "[email protected]"
objCDO.Subject = "Embedded image demo"
objCDO.HTMLBody = "<html>Check this out: <img src=""cid:myimage.gif""></html>"

' Here's the good part, thanks to some little-known members.
' This is a BodyPart object, which represents a new part of the multipart MIME-formatted message.
' Note you can provide an image of ANY name as the source, and the second parameter essentially
' renames it to anything you want.  Great for giving sensible names to dynamically-generated images.
Set objBP = objCDO.AddRelatedBodyPart(Server.MapPath("/images/myimage.gif"), "myimage.gif", CdoReferenceTypeName)

' Now assign a MIME Content ID to the image body part.
' This is the key that was so hard to find, which makes it 
' work in mail readers like Yahoo webmail & others that don't
' recognise the default way Microsoft adds it's part id's,
' leading to "broken" images in those readers.  Note the
' < and > surrounding the arbitrary id string.  This is what
' lets you have SRC="cid:myimage.gif" in the IMG tag.
objBP.Fields.Item("urn:schemas:mailheader:Content-ID") = "<myimage.gif>"
objBP.Fields.Update

objCDO.Send
That's how you embed images in HTML emails using CDO in ASP. The equivalent will work in ASP.NET of course. Hope that helps someone wanting to do the same thing.
 
Antic,

That is a great solution. Here is a kicker.. is there anyway to have the embeded image to notifiy my server that it has been loaded?

Trying to spy on my clients and see if they have read my freaking mails.
 
Nope, the purpose of this is to embed, not link. If you want to do the tracking thing, just add another image as a link.
 
It seems the mail object in .NET doesn't support embedding, but if you add a reference in your .NET project to the COM object "Microsoft CDO Object" (c:\windows\system32\cdosys.dll) then you get all the functionality of normal CDOSYS as the CDO object.

So you start with:
Code:
Dim objCDO As New CDO.Message
Dim objBP As CDO.IBodyPart

objCDO.MimeFormatted = True
objCDO.To = "[email protected]"
objCDO.From = "[email protected]"
objCDO.Subject = "Embedded image demo"
objCDO.HTMLBody = "<html>Check this out: <img src=""cid:myimage.gif""></html>"

' Note: if "cdoRefTypeLocation" doesn't work, try "cdoRefTypeId"
objBP = objCDO.AddRelatedBodyPart(Server.MapPath("/images/myimage.gif"), "myimage.gif", CDO.CdoReferenceType.cdoRefTypeLocation)

objBP.Fields.Item("urn:schemas:mailheader:Content-ID").Value = "<myimage.gif>"
objBP.Fields.Update()
objCDO.Send()

Please let me know if that works or not.
 
Hi Antic,

I am still getting a cross instead of a image. I am not sure what am I doing wrong.

Thanks.
 
Hi Antic,

I am still getting a cross instead of a image. I am not sure what am I doing wrong.

Thanks.
 
Hi
I use your cod but it reture this error:


Microsoft VBScript runtime error '800a01a8'

Object required: ''

this is my a part code:

fle2=Server.Mappath ("Myimage.GIF")
Set objBP = objCDO.AddRelatedBodyPart(fle2, "Myimage.gif", CdoReferenceTypeName)

where is problem?
 
Make sure your path to "myimage.gif" is correct. It might not be finding your image like that. Try using a literal path to make sure. The code works, both in vbscript and .net.
 
thanks

I change my path and many thing.

but it say Object required: ''


I thing Cotation " is more than or less.


may is this wrong?
CdoReferenceTypeName

you sample is very good.
can you show me another

thank you
 
Here's the code. Can't make it any easier than this. :)

Extract into a folder of your choice. Load it up in VB.NET and change the variables at the start to reflect your email address and mail server.

Make sure you include the CDO COM library into the project.

Run it and it should send you an email with the provided image embedded in it.

If you change the file type, remember to change the "content type" variable. For GIFs it's "image/gif", for PDFs it's "application/pdf", etc.

Keep in mind that many email programs won't display anything but images embedded. Other file types may appear simply attached but not embedded in the body of the email. You may have luck embedding with Outlook with regards to embedding Word, WMV, and other MS formats, but it will most likely be limited to Outlook. Other email clients will just show it as a normal attachment.
 
Thanx so much for such a quick reply !:]
However, whether I 'save' or 'run' the zip file, i keep getting the error message: ' file is invalid or corrupt '.
Can you try attaching it again, please ? Thanks again - Mike
 
hmm, I've tried it a few times and it's ok on my machine but corrupts when uploaded. I'll PM Stephen to see if something on the forum is amiss.
 
There has been an issue since upgrading the vB to 3.6 series, will have a look at it later this week.
 
Hi
I use this code But this return.

CDO.Message.1 error '80040220'

The "SendUsing" configuration value is invalid.

how can I config send using?



thank you
 
Hi
I use this code But this return.
CDO.Message.1 error '80040220'
The "SendUsing" configuration value is invalid.
how can I config send using?
thank you

My sample didn't use SendUsing. I can't support all ASP errors you get, you understand. :) Google CDO reference for your answer. If you want to use a specific SMTP server, SendUsing must be 2. See here for examples:
VBScript To Send Email Using CDO
I just googled "cdo sendusing". Hint hint. :)
 
just wanted to express my gratitude for your work Antic...

implemented your code, and it worked like a charm right out of the gate.. ;)

one question though... (or a few i suppose)... what would be the reason behind one mail provider (Yahoo) receiving the message, and another (Outlook) not?

its not that Outlook got the message, and failed to load the embedded images, its that Outlook didnt even RECEIVE the message... very odd..

second, couldnt this approach be used to do some malicious things with images? does the process of embedding images help circumvent some email security measures?

im just curious... for me, i need this code in order to send "properly" formatted receipts to my customers (company logo, background images for receipts, etc.)

at any rate, thanks again for the excellent code! :)
 
Embedded images aren't for all situations... some anti-spam systems (e.g. in Yahoo) may interpret your email as spam if you embed a GIF, as many spammers do exactly that. If Outlook didn't receive the message and you're sure it's set up ok, investigate Outlooks spam settings and those of whatever spam software is running on your pop mail server.

I'd advise always using linked images (img tags in the email html) instead of embedded unless you really need to embed them for some reason.

[edited - initially thought you had linked Outlook to your Yahoo account]
 
Back
Top