Warning: You probably will be lost if you haven't read the previous two tutorials on this.
Sending Pure HTML
So now that you know how to add attachments and all that fun stuff, I'm now going to teach you how to send HTML emails. It's rather simple if you're not embedding images and stuff like that. All you have to do is change the Content-Type header from text/plain to text/html. So a potential content type line would look like this:
(Of course, you'd put the appropriate character set for whatever it is that you're doing.)Code:Content-Type: text/html; charset=iso-8859-1
Now you can put HTML in your message body, and the mail client will probably handle it appropriately. To deal with situations where it won't, keep reading and I'll show you how to handle it.
Embedding Images and Other Files
But what if you have an image? Well, there are two ways of doing it. One is to provide a web URL for the image source:
This is called "lazy HTML." The problem with this is that most modern email clients, for security reasons, will block such images. Why? Well, let's say a spammer sends you an email with a picture linked from site X. Your browser, while rendering the email, sees that there's a picture in the body and asks the server for X to send it over. Now the spammer not only knows your email address, he/she has your IP address too. It's better to send the image as an attachment. We know how to send attachments...but how do we reference it in the HTML? Aha. Well, there's a slight modification we have to make to the attachment.Code:<img src="http://forum.codecall.net/images/misc/navbit.gif" />
Here are the headers as if we were just sending a GIF as a plain attachment:
And here are the headers for sending the same file in an HTML email:Code:Content-Type: image/gif Content-Disposition: attachment; filename="mygif.gif" Content-Transfer-Encoding: base64
Notice two things:Code:Content-Type: image/gif Content-Disposition: inline; filename="mygif.gif" Content-Id: <mygif> Content-Transfer-Encoding: base64
1) The Content-Disposition header changed from attachment to inline. This is necessary if we want the image to show up as part of the HTML body and not as just a regular attachment.
2) We added another header: Content-Id. This is what we're going to use to reference the image in the body of our HTML. Yes, the angle brackets are required. You can't have any spaces or weird characters like / and \. Just keep it to alphanumeric, underscores, and dashes, and you'll never go wrong.
To use the image in our HTML, we would do this:
cid, as you probably guessed, is short for Content Id. You can extend this to anything you reference in your HTML: Javascript files, CSS, other HTML files...basically anything in a regular website. Just remember that:Code:<img src="cid:mygif" />
1) Most systems restrict email sizes to about 20 megabytes.
2) Active content, i.e. Javascript, will probably be blocked by Outlook and other email clients. At the very least your recipient will get that little bar at the top saying "Explorer has blocked this page from displaying active content..." or something similar.
I've read that you can also do forms and use a mailto: link to submit it, but somehow I think that a lot of clients will also block this behavior, as it's a possible security hole. Don't count on it.
Catering To Everyone
This is not so much the case nowadays as ten years ago, but there are still people who don't like receiving HTML emails, or can't display them. How are we going to ensure that they get a nicely formatted email, instead of just seeing the raw HTML? Remember the multipart-mixed content type? Well, we're going to use it again. The first part of our email is going to be of type multipart/alternative; that part is further subdivided into two other parts, the HTML version first, and the plain text version second. (And yes, you need another unique boundary token.)
So we have to declare two boundary tokens now, with the same rules as before. Pretty straightforward.Code:...headers go here... Content-Type: multipart/mixed; boundary="FILEBOUNDARY" --FILEBOUNDARY Content-Type: multipart/alternative; boundary="MSGBOUNDARY" --MSGBOUNDARY Content-Type: text/html; charset=iso-8859-1 Content-Disposition: inline <html> <body> This is the HTML version of the email. Always put this first, because browsers will display the first part that they're capable of displaying and ignore the rest. </body> </html> --MSGBOUNDARY Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline This is the plain text email. Always put this second, otherwise browsers will show this first and not your HTML, even if they can display it. --MSGBOUNDARY-- --FILEBOUNDARY ...embedded images and other things here... --FILEBOUNDARY--
Putting It All Together
All right...let's send our friend Bob an email with HTML, a text version if for some reason he can't view the HTML, a picture, and a file attachment. (And we're going to CC a few friends for fun.)
Other Cool StuffCode:To: "Bob" <bob@yahoo.com> Cc: mary@hotmail.com; fulano@gmail.com; jane@austen.net From: "Me" <me@codecall.net> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="FILEBOUNDARY" --FILEBOUNDARY Content-Type: multipart/alternative; boundary="MSGBOUNDARY" --MSGBOUNDARY Content-Type: text/html; charset=iso-8859-1 Content-Disposition: inline <html> <body> Hello, World!<br/> <img src="cid:hello" alt="Hello Image"/> </body> </html> --MSGBOUNDARY Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Hello, World! [you're missing out on an image here] --MSGBOUNDARY-- --FILEBOUNDARY Content-Type: image/jpeg Content-Disposition: inline; filename="hello.jpg" Content-Transfer-Encoding: base64 Content-Id: <hello> j8SAoi9dxzDF+JIO3PoooASCODN ...you get the idea... --FILEBOUNDARY Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: attachment; filename="hello.c" #include <stdio.h> int main(void) { printf("Hello, World!\n"); return 0; } --FILEBOUNDARY--
This is for those of you that're really interested...here are some of the more common additional headers. There are a lot more specified in RFC 4021 that you can use, complete with explanations and guidelines on how to use them.
Redirecting Responses
When the recipient hits "Reply", this email address will be put in the To: field instead of whatever was in the From: field. Useful for redirecting responses to your boss. Note that this field can only take one email address.
Reply-To: youremail@host.com
Starting A Thread
You know how when someone responds to your email, your client will put it right next to your original email? It doesn't do it by looking at the subject line. Instead, it matches this field:
Message-Id: some-unique-string_09-03-2009-0000_gmt--5_rtp-lds-035_dargueta
Replying To A Thread
If you're fortunate enough to receive an email with the Message-Id field set, you can set this field to the Message Id to cause you recipient's client to treat your message as a reply, regardless of the subject line.
In-Reply-To: some-unique-string_09-03-2009-0000_gmt--5_rtp-lds-035_dargueta
Forwarding Emails
You can set this field if you want so that people replying to this forwarded email will be treated as replying to the original, not your forwarded message.
Original-Message-Id: some-unique-string_09-03-2009-0000_gmt--5_rtp-lds-035_dargueta
Setting The Date
When the message was sent.
Date: day-of-week, day month year time-of-day timezone
day-of-week = Mon | Tue | Wed | Thu | Fri | Sat | Sun
day = 1-31
month = Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec
year = yyyy
time-of-day = hh:mm(:ss) (seconds are optional)
timezone = e.g. -0500 for Eastern Standard Time, -0800 for Pacific Standard Time, etc.
Further Reading
RFC 2822 - Internet Message Format
MIME Types By File Extension (Note this is not a complete list)
Last edited by dargueta; 09-03-2009 at 11:15 AM.
sudo rm -rf /
Very well done! +rep
Nice job. I always send email as plain text, just in case. Some of my customers have VERY old systems. +rep
Hm...it appears that my Mary, **** and Jane example failed.
EDIT: And here it failed again.
sudo rm -rf /
You mean Richard?
Yes. The typical names used when teaching English grammar.
sudo rm -rf /
My middle name is Richard, ****.
There are currently 1 users browsing this thread. (0 members and 1 guests)
Bookmarks