Tut: How to add embedded images in CDO mail

Discussion in 'Microsoft Development' started by antic, Jun 13, 2006.

  1. antic

    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 = "you@yourdomain.com"
    objCDO.From = "you@yourdomain.com"
    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.
  2. liming

    liming Perch

    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.
  3. antic

    antic Perch

    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.
  4. snooper

    snooper Perch

    This is great Antic, thanks. i have been wanting to look into this for a while
  5. vinki

    vinki Guppy

    How can I do this in asp.net. either VB.net or C#.

    Any help will be greatly appreciated
  6. antic

    antic Perch

    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 = "you@yourdomain.com"
    objCDO.From = "you@yourdomain.com"
    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.
  7. vinki

    vinki Guppy

    Hi Antic,

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

    Thanks.
  8. vinki

    vinki Guppy

    Hi Antic,

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

    Thanks.
  9. khadem1386

    khadem1386 Guppy

    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?
  10. antic

    antic Perch

    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.
  11. khadem1386

    khadem1386 Guppy

    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
  12. antic

    antic Perch

    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.
  13. jmichaelt

    jmichaelt Guest

    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
  14. antic

    antic Perch

    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.
  15. Stephen

    Stephen US Operations Staff Member

    There has been an issue since upgrading the vB to 3.6 series, will have a look at it later this week.
  16. antic

    antic Perch

    Thanks Stephen.
  17. khadem1386

    khadem1386 Guppy

    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
  18. antic

    antic Perch

    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. :)
  19. dalin

    dalin Guppy

    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! :)
  20. antic

    antic Perch

    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]

Share This Page

JodoHost - 26,000 hosting end-users in 100 countries
Plesk Web Hosting
VPS Hosting
H-Sphere Web Hosting
Other Services