I <3 Steve McConnell*
Coding Horror
programming and human factors
by Jeff Atwood

Apr 21, 2010

So You'd Like to Send Some Email (Through Code)

I have what I would charitably describe as a hate-hate relationship with email. I desperately try to avoid sending email, not just for myself, but also in the code I write.

Despite my misgivings, email is the cockroach of communication mediums: you just can't kill it. Email is the one method of online contact that almost everyone -- at least for that subset of "everyone" which includes people who can bear to touch a computer at all -- is guaranteed to have, and use. Yes, you can make a fairly compelling case that email is for old stupid people, but let's table that discussion for now.

So, reluctantly, we come to the issue of sending email through code. It's easy! Let's send some email through oh, I don't know, let's say ... Ruby, courtesy of some sample code I found while browsing the Ruby tag on Stack Overflow.

require 'net/smtp'

def send_email(to, subject = "", body = "")
    from = "my@email.com"
    body= "From: #{from}\r\nTo: #{to}\r\nSubject: #{subject}\r\n\r\n#{body}\r\n"

    Net::SMTP.start('192.168.10.213', 25, '192.168.0.218') do |smtp|
        smtp.send_message body, from, to
    end
end

send_email "foo@example.com", "title", "body goes here"

There's a bug in this code, though. Do you see it?

Just because you send an email doesn't mean it will arrive. Not by a long shot. Bear in mind this is email we're talking about. It was never designed to survive a bitter onslaught of criminals and spam, not to mention the explosive, exponential growth it has seen over the last twenty years. Email is a well that has been truly and thoroughly poisoned -- the digital equivalent of a superfund cleanup site. The ecosystem around email is a dank miasma of half-implemented, incompletely supported anti-spam hacks and workarounds.

Which means the odds of that random email your code just sent getting to its specific destination is .. spotty. At best.

If you want email your code sends to actually arrive in someone's AOL mailbox, to the dulcet tones of "You've Got Mail!", there are a few things you must do first. And most of them are only peripherally related to writing code.

1. Make sure the computer sending the email has a Reverse PTR record

What's a reverse PTR record? It's something your ISP has to configure for you -- a way of verifying that the email you send from a particular IP address actually belongs to the domain it is purportedly from.

Not every IP address has a corresponding PTR record. In fact, if you took a random sampling of addresses your firewall blocked because they were up to no good, you'd probably find most have no PTR record - a dig -x gets you no information. That's also apt to be true for mail spammers, or their PTR doesn't match up: if you do a dig -x on their IP you get a result, but if you look up that result you might not get the same IP you started with.

That's why PTR records have become important. Originally, PTR records were just intended as a convenience, and perhaps as a way to be neat and complete. There still are no requirements that you have a PTR record or that it be accurate, but because of the abuse of the internet by spammers, certain conventions have grown up. For example, you may not be able to send email to some sites if you don't have a valid PTR record, or if your pointer is "generic".

How do you get a PTR record? You might think that this is done by your domain registrar - after all, they point your domain to an IP address. Or you might think whoever handles your DNS would do this. But the PTR record isn't up to them, it's up to the ISP that "owns" the IP block it came from. They are the ones who need to create the PTR record.

A reverse PTR record is critical. How critical? Don't even bother reading any further until you've verified that your ISP has correctly configured the reverse PTR record for the server that will be sending email. It is absolutely the most common check done by mail servers these days. Fail the reverse PTR check, and I guarantee that a huge percentage of the emails you send will end up in the great bit bucket in the sky -- and not in the email inboxes you intended.

2. Configure DomainKeys Identified Mail in your DNS and code

What's DomainKeys Identified Mail? With DKIM, you "sign" every email you send with your private key, a key only you could possibly know. And this can be verified by attempting to decrypt the email using the public key stored in your public DNS records. It's really quite clever!

The first thing you need to do is generate some public-private key pairs (one for every domain you want to send email from) via OpenSSL. I used a win32 version I found. Issue these commands to produce the keys in the below files:

$ openssl genrsa -out rsa.private 1024
$ openssl rsa -in rsa.private -out rsa.public -pubout -outform PEM

These public and private keys are just big ol' Base64 encoded strings, so plop them in your code as configuration string resources that you can retrieve later.

Next, add some DNS records. You'll need two new TXT records.

  1. _domainkey.example.com
    "o=~\; r=contact@example.com"
  2. selector._domainkey.example.com
    "k=rsa\; p={public-key-base64-string-here}"

The first TXT DNS record is the global DomainKeys policy and contact email.

The second TXT DNS record is the public base64 key you generated earlier, as one giant unbroken string. Note that the "selector" part of this record can be anything you want; it's basically just a disambiguating string.

Almost done. One last thing -- we need to sign our emails before sending them. In any rational world this would be handled by an email library of some kind. We use Mailbee.NET which makes this fairly painless:

smtp.Message = dk.Sign(smtp.Message, 
               null, AppSettings.Email.DomainKeyPrivate, false, "selector");

3. Set up a SenderID record in your DNS

To be honest, SenderID is a bit of a "nice to have" compared to the above two. But if you've gone this far, you might as well go the distance. SenderID, while a little antiquated and kind of.. Microsoft/Hotmail centric.. doesn't take much additional effort.

SenderID isn't complicated. It's another TXT DNS record at the root of, say, example.com, which contains a specially formatted string documenting all the allowed IP addresses that mail can be expected to come from. Here's an example:

"v=spf1 a mx ip4:10.0.0.1 ip4:10.0.0.2 ~all"

You can use the Sender ID SPF Record Wizard to generate one of these for each domain you send email from.

That sucked. How do I know all this junk is working?

I agree, it sucked. Email sucks; what did you expect? I used two methods to verify that all the above was working:

  1. Test emails sent to a GMail account.

    Use the "show original" menu on the arriving email to see the raw message content as seen by the email server. You want to verify that the headers definitely contain the following:

    Received-SPF: pass
    Authentication-Results: ... spf=pass ... dkim=pass
    

    If you see that, then the Reverse PTR and DKIM signing you set up is working. Google provides excellent diagnostic feedback in their email server headers, so if something isn't working, you can usually discover enough of a hint there to figure out why.

  2. Test emails sent to the Port25 email verifier

    Port25 offers a really nifty public service -- you can send email to check-auth@verifier.port25.com and it will reply to the from: address with an extensive diagnostic! Here's an example summary result from a test email I just sent to it:

    SPF check:          pass
    DomainKeys check:   fail
    DKIM check:         pass
    Sender-ID check:    pass
    SpamAssassin check: ham
    

    You want to pass SPF, DKIM, and Sender-ID. Don't worry about the DomainKeys failure, as I believe it is spurious -- DKIM is the "newer" version of that same protocol.

Yes, the above three steps are quite a bit of work just to send a lousy email. But I don't send email lightly. By the time I've reached the point where I am forced to write code to send out email, I really, really want those damn emails to arrive. By any means necessary.

And for those who are the unfortunate recipients of these emails: my condolences.

[advertisement] JIRA Studio - SVN hosting, issue tracking, CI and Google Apps integration. Free trial »

Posted by Jeff Atwood    View blog reactions
« Three Monitors For Every User
What's Wrong With CSS »
Comments

Or just use an app that's done most of that for you - http://postmarkapp.com

Jasoncartwright on April 21, 2010 3:54 AM

"p={private-key-base64-string-here}"

Public key here?

Regards,
Dejan

www.vesic.org on April 21, 2010 4:31 AM

You should check out some of the cloud based email providers. They manage this headache for you. A good one is http://www.socketlabs.com

Nick Berardi on April 21, 2010 4:46 AM

+1 to both comments above. 3rd party SaaS is the way to go. Then, if pricing appears to be an issue, then you're probably sending too many emails anyway.

Joannes Vermorel - Lokad Sales Forecasting on April 21, 2010 4:56 AM

The most important thing: make sure the SMTP server is not listed in one of the many DNS-based blacklists.

http://www.mxtoolbox.com/blacklists.aspx

Also, you should have your SMTP server do the DKIM stuff. That way *every* email message (not just the ones sent by your application) will be signed.

Ovidiu on April 21, 2010 5:03 AM

That doesn't seem that onerous.

Sure email is crap but all you are saying here is "oh noes I have to follow the standards involved". At least there _are_ fairly universal standards.

idno, maybe I'm missing something

Fowl2 on April 21, 2010 5:33 AM

I just configure exim on the server to use GMail as a smart host. Using my Google apps account I'm able to keep my domain on there, instead of gmail.com. I trust Google to do all the wacky SMTP stuff properly. It seems to work, because everyone gets the e-mails my apps send out.

Why go through all this complicated mess, which I'll probably screw up, when I can just have someone else do it for me?

Apreche on April 21, 2010 5:37 AM

Also be sure not to use anything that could even resemble the language used in spam, down to the name of your company. http://news.bbc.co.uk/2/hi/technology/8528672.stm - "After 90 years, one of Canada's oldest magazines, The Beaver, is changing its name."

Another nightmare is the state of HTML rendering of mails. http://litmusapp.com/ can help you to check out how your mails looks in most of clients in use.

On a completely different note I wish there will be a more high level mail implementation included in the stdlib for Ruby in the future.

require 'mail' # http://github.com/mikel/mail

Mail.deliver do
from 'j@plea.se'
to 'j@codinghorror.com'
subject 'Send Some Email'
body 'Thanks for a great post!'
end
end


Jonas Elfström on April 21, 2010 5:39 AM

Email is great, it is the best communication tool nowadays. It is also used as the primary way to log on to your blog so we can post comments ;-)

Ricardo D Sanchez on April 21, 2010 5:57 AM

@Dejan, yes, you should put your public key there. See my post:
How to setup DKIM and DomainKeys with SmarterMail

Magnus

InsomniacGeek on April 21, 2010 5:58 AM

Ironically, my e-mail server rejected port25's automated e-mail because it was not sent from a valid address:

sender verify fail for :
  response to "RCPT TO:" from
  verifier.port25.com [207.36.201.235] was:
  550 5.1.1 no such local recipient
Alex on April 21, 2010 6:06 AM

Hmm, as Ovidiu suggests having your local SMTP server do this stuff for you... I'm pretty sure most individual email clients don't have personalized DNS records with public/private keys. (But I'd love to see S/MIME get mainstream!)

I'd be more curious about how to get through authentication mechanisms on the SMTP server, and then let it do the heavy lifting. For my organization, it looks like that's just a matter of piping everything through an SSL connection with a username and password.

Ethan Tira-Thompson on April 21, 2010 6:23 AM

Wow, is that you're only beef with sending email? You didn't touch on the nightmare of the various authentication methods, using SSL or setting up SMTP relay hubs. There's the minor annoyance of attaching "HTML" email bits to a message, but that's a minor barb.

Hell, even if you do this dance right, the mail will often get stuck in a spam trap or not get to the addressee for a long time due the way ISPs batch SMTP traffic.

And what if your ISP gets on some stupid spammer black list? You may not have done anything wrong, but some idiot on your domain did once and now you get to pay the price.

Seriously, I cringe every time I'm asked to add "email notification" to an app. It's a disaster.

Blog on April 21, 2010 6:34 AM

Ha, you're a mind-reader Jeff - we were fighting with this very issue just this morning. Thanks for the post, it was just what we needed.

One thing I would add: if you're sending significant amounts of important emails, make sure to check bounce-backs, because there are also issues of customers having mis-configured mail servers, bad email addresses, etc etc - there's no substitute for a human checking these issues (sadly).

Keith Williams on April 21, 2010 6:34 AM

Jeff,

It's good to see someone talking about this. This is one of the points I wanted to get around to once I got my blog set up.

Another few things that are important:

1) Either VERPs or Queue ID headers so you know who you sent the email to when it bounces (and they /will/ bounce.) VERPs and Queue ID headers make life very simple for knocking out bouncing email.

2) Sign up for feedback loops with the main providers (at least AOL, Hotmail and Yahoo).

3) Add a list-unsubscribe header that has an email address that also routes through to your feedback loop email.

By the way, as a long time reader and first time commenter, thank you so much for all the work you put into your blog. I know from my own experience trying to maintain one that the motivation can be difficult. Hopefully I'll get there soon.

PoweredByJAM on April 21, 2010 6:51 AM

Those are serious headaches. But I've always been mystified by your hatred for email. Can you propose a better system? It has to meet the following requirements

1) Your address can be public, so anybody can send to you without having an explicit prior relationship. This opens the door for spammers, but also job applicants, customers, etc.
2) A message can be private - readable only by recipients
3) A message can have multiple, explicit recipients - not 'whoever happens to read it'
4) Receivers are notified when they receive messages and can respond to the sender, other recipients, etc
5) Receivers are able to archive and search their sent and received messages
6) Message storage can be in the cloud or on a local machine, whichever suits your purposes

I'm sure there are other advantages of email.

Yes, young people are using text messages and whatnot. But what's good for 'hey whos brylie dating today lol' isn't necessarily good for serious communications. And I bet those same kids use email when they start their careers.

Email encryption on both ends would help with identification and privacy. And I'm not that familiar with Google Wave; maybe it's a better system. But your suggestions like "use Twitter instead!" are just not practical for many use cases.

So here's a post I'd love to see: Jeff's detailed proposal to replace email with something better.

Nathan Long on April 21, 2010 7:01 AM

That's ruby code? It looks like Pascal. :)

Jeff Davis on April 21, 2010 7:15 AM

And that's just the beginning! To really improve your deliverability you have to do bounce processing right. Which is a total pain. I therefore would strongly encourage folks to check out providers. I particularly like http://sendgrid.com

Albertwenger on April 21, 2010 7:33 AM

I have to say that I share your feelings about e-mail, but what are the alternatives?

I suppose there are a few situations where emails are sent *that you actually care about*:

1. Someone else performs some action that you want to know about, so you can respond - posts an answer, turn, whatever.

2. You have forgotten your password and need a new one.

And actually, that's about it. #2 can be circumvented by using a system like OpenID - essentially "make it someone else's problem".

#1 is nebulous and difficult - you could argue that RSS feeds are a solution, but to take a system like Stack Overflow as an example, I don't want to have to subscribe to a feed for every question I ask/answer to get updates for it. Maybe you could have a 'personal' feed that updates only things relevant for me. Actually, I quite like that as a solution, not something I've seen (noticed?) implemented. Not quite so useful in situations where you might use a service once or twice though.

My Inbox is almost exclusively used as a notification area - things happen on one of the various websites I use, my iPhone beeps to tell me I have an email. I respond when I have a moment - all the while being reminded by my unread count that I have some action to take at some point. Often though, an email arrives that is just some boring marketing thing or a spam that got through or a chain letter from my mum, resulting in a false-positive beep from my iPhone.

RSS doesn't quite cut this mustard - although some of that may be down to the way most RSS clients are implemented. It also doesn't help for the idiots and old people who *only* have e-mail, but maybe we should start treating them like IE 6 users - just pretend they don't exist and hope they go away?

Mike Watts on April 21, 2010 7:36 AM

> Sure email is crap but all you are saying here is "oh noes I have to follow the standards involved". At least there _are_ fairly universal standards.

Easy to say that when Jeff’s just laid them out for us. I suspect many, many hours of painful trial and error went into this blog post.

> Can you propose a better system? It has to meet the following requirements

> 1) Your address can be public, so anybody can send to you without having an explicit prior relationship. This opens the door for spammers, but also job applicants, customers, etc.

Does your address have to be public? Everyone I know who isn’t into computers like we are (which, remember, is likely 95–99% of the people in the world, and is therefore the kind of person that matters) uses Facebook instead of e-mail. There’s no real concept of a public address for messages there. You have to explicitly allow people to send you messages by becoming their friend.

www.pauldwaite.co.uk on April 21, 2010 8:57 AM

Oh, and here’s what I meant to say: vintage Coding Horror right here. A smart, useful article, with smart, useful comments and discussion.

www.pauldwaite.co.uk on April 21, 2010 8:59 AM

Are these mitigated if you just send the email through your email provider (such as Google Apps for Domains)? Granted, if you're sending a lot of messages you'll want to go with a provider, but for all of my little projects I've just passed all the heavy lifting to Google.

Mr_rcollins on April 21, 2010 9:07 AM

@Nathan. Well said. I keep hearing these "I hate email" and "Email is dead" messages but they are bogus, because as far as I know, there is no alternative that has the characteristics that email has.

What are we going to do? Post messages on forums, twitters, blogs and hope that somebody reads it? How will you be notified though? Wouldn't that be exactly the same as email? Instead of one source of communication and distraction we will have a dozen? How about not ignoring the fact that email is much more than communication, it is also legal proof, used as a todo, planning and scheduling application (when combined with a calendar). Some even use it as their main document management system.

There are major issues in email I admit. Spam is one and is solved mostly. Misuse and overuse is one but you will keep that in every tool, because it is about culture, not technology.

Fchristant on April 21, 2010 9:35 AM

@paul: "Does your address have to be public? Everyone I know who isn’t into computers like we are (which, remember, is likely 95–99% of the people in the world, and is therefore the kind of person that matters) uses Facebook instead of e-mail. There’s no real concept of a public address for messages there. You have to explicitly allow people to send you messages by becoming their friend."

Well, that is your context. Here in the Netherlands, those people do use email, MSN and this local social network called Hyves. Your context is not universal. Guess what your group and mine have in common? Email.

The other part about context is that you are talking about the consumer space. Friending people before you can send them anything will obviously not work in an enterprise.

I can understand that Jeff and people of a similar background who use email as a consumer, not in an enterprise context, see email as annoying and outdated, but now put yourself in my shoes:

I'm currently working on 4 projects at the same time. In total it concerns a group of nearly a 100 people that I need to report to or instruct. I also need to manage and structure tasks associated with it. I need to handover stuff to newcomers. I need to archive documents. I need to be able to search through all this crap and find things fast. I need to be able to discuss things electronically and I need a record of proof for new assignments. I work with people both old and young, from various backgrounds. As far as I know, only a rich email client can do all of this.

The situation I am painting is much different from three developers in the same room working on a consumer product. Email is imperfect but often a neccessity. The alternatives are much worse.

Fchristant on April 21, 2010 9:46 AM

Nice article spoiled by the 'aren't I so alternative/idiosyncratic/eccentric by declaring my hate for email' attention seeking.

Makes as much sense as me declaring my dislike for light switches, return-keys and cups with bottoms to keep the drink from falling out.

I really don't see what the problem is with email. 99% of the time it just works.

How about proposing alternatives?

Kev on April 21, 2010 9:50 AM

Hey, I'm 16, and I want to learn a programming language. I'm already somewhat familiar with autoit(its basically a simpler version of visual basic, so I'm not very advanced lol) but I'd learn to learn something more mainstream and more powerful. I was thinking between C++ or Java.

People say Java is easier, but I don't want to spoil myself with it and not be able to learn complex languages. On the other hand, I want to be able to understand the concepts of programming and not have it so complicated to where I just memorize a bunch of commands and not really understand it.

Is there a book or a website you can recommend for a first programming language? Thanks!

BTW, I also enjoy reading your blog, even though most of it is over my head.

Daniel Brewer on April 21, 2010 10:08 AM

Daniel, check out Carl H's programming lessons on Reddit.

http://www.reddit.com/r/carlhprogramming/

Start at lesson 1!

Matt Stith on April 21, 2010 10:54 AM

The biggest bug in the code is that you insert to and subject into the mail header without any filtering. This is a source for many spam abuses, when spammers manage to control e.g. the subject and insert a newline into it, thus allowing them to insert own header lines and change the body.

Kju on April 21, 2010 11:08 AM

If you use squirrelmail, you can send messages with wget. This avoids many anti-spam and configuration issues.

wget --save-cookies cookies.txt --keep-session-cookies --post-data 'login_username=username&secretkey=password' http://webmail.server.com/src/redirect.php

wget --load-cookies cookies.txt --post-data 'body=body here&send_to=recipient%40wherever.com&subject=subject here&send=1' http://webmail.server.com/src/compose.php

For a bit more, see:

http://mikemccabe.wordpress.com/2007/08/07/sending-email-with-squirrelmail-via-wget/

Michael McCabe on April 21, 2010 11:41 AM

Hmmm, seems to me that e-mail as a concept is still a good idea, it's just e-mail as an implementation is broken.

I feel something more akin to Google Wave is the way forward - we need to be able to easily move between slower e-mail based communication to faster chat based communication and improve sharing of documents and other resources.

Amouat on April 21, 2010 12:14 PM

Thoughts on using sendgrid.com for transactional email? I've used them for a few projects and love how much they do (spam, tracking, truncation).

Andrew Hyde on April 21, 2010 1:38 PM

Good article if you're only sending a single email to a single recipient. If you're going to send email to a bunch of people, e.g. if the exam they signed up for on your website had to be canceled, you have to think about issues like rate-limiting per domain and other such headaches...

Bjorn Pettersen on April 21, 2010 2:04 PM

I believe, if you move your emails to google app, you are good!

Also, as someone already pointed out here, if we need to mass email marketing, then we need professional email software support anyways because of throttling etc.

Ruchitgarg on April 21, 2010 3:36 PM

Hi jeff why not outsource this to any one of a number of providers? They address deliverability issues which as you wrote about are the biggest hassle in the process. CPM costs are so low nowadays too. Curious why you'd want to (or have to) manage all this complexity yourself?

Howie Camp on April 21, 2010 4:06 PM

This post basically boils down to "If you're going to programatically plug into a global message sending service, there are some hoops you have to jump through to ensure that you're not sending a torrent of sewage." But this isn't a coding problem. This is an infrastructure problem. And like most such problems, you push it off to someone else. 4/5 times your upstream ISP will have a mechanism for your network to push mail to theirs (without all these hoops) so that they become responsible for all the extra work involved in sending email. In that 5th case where they don't, there are some pretty cheap providers who will allow you to send mail to them for a small annual fee. Then your infrastructure barrier reduces to learning to set up postfix or sendmail or whatever to use a smarthost for all outbound email.

Brad Davis on April 21, 2010 5:38 PM
Don't even bother reading any further until you've verified that your ISP has correctly configured the reverse PTR record for the server that will be sending email.
Do mail servers configured to check PTR records actually black hole email, or do they just refuse to accept it? In my opinion an MTA either accepts an email and then does its best to deliver it, or it doesn't accept the email and produces an error message. Anything less is heinously out of spec. Brad Davis on April 21, 2010 5:41 PM

Below is an enlightening video about internet communication in general.

"How the internet enables intimacy"
http://www.ted.com/talks/stefana_broadbent_how_the_internet_enables_intimacy.html

Ape Inago on April 21, 2010 7:21 PM

I may just be thick, but I don't understand how a PTR relates to SPF. And the Googling I've done, let alone the reading of articles linked from here, hasn't made it any more clear. Anyone have a pointer to something which (relatively) clearly explains them and their relation to each other?

Meyerweb on April 21, 2010 8:02 PM

So, the error in the "code", is the lack of a queuing mechanism. Perhaps Ruby's Net::SMTP does this, but somehow I doubt it. The proper way to do this is to submit the message to a local queue on the machine. That machine then relays the message through a smart host, which has the proper configurations outlined by Jeff.

Jeff Macdonald on April 21, 2010 8:03 PM

We send hundreds of thousands to millions of emails per day, depending on the day. You left out one important/annoying bit. You also have to contact all the major email providers ONE BY ONE to make your emails get through. Microsoft, Yahoo!, and AOL all had specific methods of getting massive amounts of e-mailing to work. Luckily they all included links in the error messages, if you read your SMTP logs.

Then you have to make sure your include all the CAN SPAM stuff (send from an address that can be replied to, double opt-in, include an unsubscribe link, etc) and also constantly monitor the common black lists. After all that, you have a decent chance of getting your emails through... It sucks.

JD Conley on April 21, 2010 9:40 PM

@ruchitgarg

Using a google apps account with your domain doesnt mean it will pass. google does not sign your emails. more likely to end up in spam because google will use its own mx.google smtp servers to send emails for yourdomain.com unless ofcourse you send to people with a google address i guess.

I ran a verification by emailing check-auth@verifier.port25.com from my google apps account and got this:


The Port25 Solutions, Inc. team

==========================================================
Summary of Results
==========================================================
SPF check: neutral
DomainKeys check: neutral
DKIM check: neutral
Sender-ID check: neutral
SpamAssassin check: ham


----
"neutral"
the authentication method completed without errors, but was unable
to reach either a positive or a negative result about the message.

Jaskirat on April 22, 2010 12:01 AM

You harp on about Twitter and you criticize email for being a poor communication modality? Give me a break, Jeff.

Martin Doms on April 22, 2010 3:05 AM

This is my first post on this blog, and I hate to start off sounding like a hater, but I get the sense that Jeff Atwood doesn't appreciate email because he doesn't have what some people call a "real job." He spends his days sitting around at home with his cats and blogging (to be fair, it appears he did have a "real job" for three years, so I guess he has a little experience). Right now, in Jeff's world, it makes sense to get rid of email. But we don't all live in that world. In railing against email, he is definitely not putting himself in the shoes of us "working folks."

Here's what's in my inbox:
- a message to me from a visual designer (i.e. artist) telling me where the jpgs are (I need to know this so I can put them on the site).

Okay, so obviously the designer is not going to twitter or FB this. So why don't they IM me? Well, for one thing, once I close the IM window the information is gone, so I have to dig through some IM logs to find it. Here's another reason: if I'm logged off, she CAN'T send it, so what is she supposed to do, wait around and not move on to other tasks until I return to my desk? She (understandably) wants to fire off a message and forget about it. Finally, here's another reason (probably the most important one). Follow along with this: I put the wrong assets on the site, I push the site live, the client yells at us or fires us for putting the wrong assets up, and then I blame the designer for not sending me the right info (I personally wouldn't do this, but many would). If she's not logging that IM conversation, then it's my word against hers. But if she has an email that she can point to, then I get in trouble, not her. And since we use Exchange, our emails are archived on a server that only IT has access to, so even if she has a tech-savvy friend outside the company, if she didn't send it then there's no way she can fake an email.

Oh, and another thing -- the people CCed on this email are carefully selected to be the exact people that need to know this info. Me, two producers, the QA person, technical project manager, another designer. Account managers not CCed -- they don't deal with this stuff, ever. Random other programmers and team members not working on this project are not CCed. If she sent an IM, two producers and the tech project manager and maybe QA are all going to be going to her desk or IMming her and saying "Hey, did you send that image to Jason?" And she's going to be saying "yes" like 3 or 4 times. And again, more importantly, when the producer forgets to tell the client that the image is live, and then later comes to the visual designer and says "you never told me it was ready", this designer can point to the email and say "Yes I did, here it is -- I CCed you." Believe me, this happens all the time, even on the less backstabbing accounts.

Anyway I could go on but the TL/DR is that it's really about accountability. Email is used nowadays in much the same way that good-old on-paper MAIL used to be used. If somebody wants to send you an official communication, they send you an email. It's no accident that when you register for "e-billing" by your utility company, there's no option to register for "facebook billing" or IM billing or twitter billing. Email is for official business. I guess Jeff must not have much official business to conduct, which makes sense, since from what I understand he's mostly about blogging -- which is fine, that's what you do, but don't make the mistake of assuming everyone's life is just like yours.

eeeeaaii on April 22, 2010 8:19 AM

Great tutorial but I have found that moving all my email functionality to something like gmail proves to be a simpler solution.

TheSpotter on April 22, 2010 8:24 AM

The last phrase made it all! :))

Andrei Rinea on April 22, 2010 12:48 PM

Sorry Jeff but you got this one wrong.

None of this code belongs in your applications code. DKIM, rDNS, SFP, etc. should all be handled by your SMTP server, not your application. Your application is nothing more than an email client, like Outlook, Thunderbird, etc. Outlook isn't adding any DKIM info and individual users don't worry about DNS records, that is all taken care of by the SMTP server.

And I would say SPF (what you call Sender ID) is just as if not more important than DKIM. It is not Microsoft centric at all, almost all mail systems and spam filters check SPF records. DKIM is almost exclusively used/enforced by Yahoo.

TonyB on April 22, 2010 8:35 PM

I agree with TonyB. This is not a responsibility of your app. It just does not belong there. SMTP servers are build to handle such matters so you don't have to.

Every serious company has an own SMTP server and an admin that manages it. And you have a lot of choices online if you don't have you own SMTP.
What will you do if you mail gets greylisted, bounced etc... Will you mimic the mail server and try again later? Will you roll out your own mail server? Tha application should just pass the mail with basic info to the SMTP server. It is important however that you have a mean of processing the rejected or undeliverable mails. But this is commonly achieved by adding custom header entries so that the mail server is in a way aware of the sender.

Iztok Kacin on April 23, 2010 12:05 AM

Oh and about e-mail. It is by far the most reliable and wide spread medium of communication over the web. And It is not bad at all. I has one very big advantage. Everybody knows what it is and how to use it. Furthermore I can easily have my mails locally or on a server and have them archived.

Good luck archiving all other means of communication. And yes, to me it is very important that I can look back to see what my coworker wanted me to do one year back.

Iztok Kacin on April 23, 2010 12:09 AM

So email has it's flaws, I agree with that. (Calling it 'broken' is a little overstated, though).

But advocating Twitter as an alternative? Seriously! The only reason I won't call twitter 'broken' is that it was never whole to begin with.

Screwey on April 23, 2010 1:47 AM

That's interesting, if Google's App Engine (which has built-in mail API) provides all this stuff.

Alexander on April 23, 2010 7:36 AM

I have to concur with TonyB. Your application should be a mail client. One of the problems that most apps that send mail directly fail to deal with properly is greylisting. A real SMTP server knows how to handle the SMTP responses, many of the libraries do not.

Jim Butts on April 23, 2010 9:07 AM

/agree with all the people mentioning this all belongs on the smtp server, not the code level.

While the things you listed in your blog post are all good to do, they really are the minimum. Lots of people have mentioned more things to take into consideration.

One thing i haven't seen mentioned yet is proper use of mime in email messages. And this is something that you would control at the client level.

Basically if you are going to be sending HTML in your email, you need to provide a plain text version as well, don't just send the HTML.

If you browse the asp.net forums you will see hundreds of posts where people are suggesting to do something like MailMessage.IsBodyHtml = true;

That is incorrect, the body should be text/plain and the html version should be added as an alternate view.

When you do this, the recievers email client will automatically pick the right version, and the recievers email server will be less likely to reject your message to begin with.

@Meyerweb in regards to how ptr relates to spf records.

spf records are basically a listing of ip addresses that are authorized to send email from a domain. When you see the ptr token in the spf record it is basically a short cut for saying "the ip address indicated in the ptr record is allowed to send email for this domain"

Erick Stubbs on April 23, 2010 3:07 PM

@Erick Stubbs:

Including ptr in an SPF record doesn't seem like a good idea to me.

Simply put, if I have control over my own DNS, I can add a PTR record of 1.2.3.4 to mxa.mail.google.com (or whatever Google's first SMTP server is).

It's A records that are *generally* safe, as they map DNS names to IPs. The A record for mydomain.com is under my control, unless the root server for .com gets tricked or the receiver has had their DNS hacked (and then it's their problem, not mine).

Ross Bemrose on April 26, 2010 7:17 AM

I haven't tried this to send mail to external parties as I work on internal ERP (Accounting) systems, but primarily you really just have to change how you think about it.

On everything I design email is an "optional", "Under ideal circumstances" tool. For example we have an internal licensing application that we use to generate licenses for our customers. I could notify the licensing department using email - but what happens if it goes wrong? Instead I write to an actual table and have an application sit over it.

Lets face it - email is and will always probably be a crapshoot. It just wasn't designed to be terribly reliable and the problem with spam has only compounded that.

Morglum on April 26, 2010 1:04 PM

I just want to say, this blog post inspired me to add an email error-reporting feature to one of my tools my support department uses. Thank you for that.

John Moss on April 27, 2010 7:04 AM

I love the post but the whole sentiment about email being the cockroach of communications is one I hadn't considered!! Our business ( http://www.yreceipts.com ) depends on automated emails! We send email receipts from retail shops as an alternative to paper and I'd be very interested to hear of other options for doing this if people have any. Thanks.

Richard Druce on April 27, 2010 6:23 PM

Of the items you listed...you missed the most basic one...and the one most frequently screwed up: include a Date header.

It's required by RFC2822, and it's absence is a key indicator of spam.

jasonjwwilliams on April 28, 2010 8:15 PM

I wrote up something similar with a hands on Ubuntu slant.

http://www.lowtek.ca/roo/2009/earning-trust-for-your-email-server/

Others in the comments have mentioned Yahoo, but that was a particularly problematic step for me. I did succeed - but it took some perseverance. Yahoo hosts Rogers email, meaning that many local people were having spam issues with my server.

Andrew Low on April 30, 2010 7:52 AM

It's a good article, except that in the Gmail section you incorrectly conflate "Reverse PTR" and "SPF" - these are two separate things. Gmail and port25.com aren't actually reporting on whether Reverse PTR checked out.

You're right to say that SPF is a nice-to-have these days, and DKIM is more important. Lots of other articles on the web say the reverse, primarily because a few years ago, SPF appeared to have taken the lead.

SPF is actually badly thought out - it's debatable as to whether it is even a good idea to use it. Certainly you should never reject any email that fails an SPF check, because there are just too many normal, legitimate situations in which it may report a failure.

SPF makes the false assumption that if the recipient server isn't getting the mail delivered directly from the sender's MTA with no hops in between, then the mail is illegitimate. It's not hard to see where this fails: if the recipient has set up his mail account to redirect mail to another, that adds an intermediate server that the sender has no control over. If the final receiving server does an SPF check, it sees that the mail has come from an unrecognised server, which doesn't match the sender's server. This happens even if the mail has not been altered in any way by that intermediate server. The sender has no way of anticipating or avoiding this fail condition, except either to a) not use SPF at all or b) use SPF with "?all" at the end, ensuring mails that fail the check are not penalised.

On the other hand, DKIM acknowledges that mail may pass through more than one server on its way to the destination, and even goes so far as to check that it hasn't been tampered with on its way. There's far fewer situations where DKIM is likely to give a false fail, though there are a couple of edge cases. One is where an intermediate server or proxy (such as a virus scanner) adds a footer to the bottom of mails. Another is where a mailing list server alters some of the headers of the mail before sending the mail out. In the first, you could argue that such tampering by intermediate servers /should/ cause a DKIM failure. In the second, there are other options for mailing lists: they could verify and remove the DKIM header, possibly even re-signing the message with its own DKIM header matching the new Sender address and headers.

thomasrutter on May 3, 2010 12:18 AM

Another point that could be made is that not all these measures are about getting past spam filters.

Having a reverse PTR that's not faked definitely will help you, and not just with email. That's the most basic thing you should get working.

DKIM and SPF can prove that you are the domain you claim to be, but they don't prove in their entirety that you're not a spammer. There's nothing that says a spammer can't have an IP address and domain name, and due to incompetant or criminal hosting companies they often do. In terms of beating spam filters, passing something like DKIM or SPF is going to be one of a number of factors that a filter may use in their decision, and content-based spam filters are certainly not becoming obsolete any time soon.

It's a simple point, but worth saying; there isn't a magic bullet to spam prevention not getting past spam filters.

What DKIM and SPF can do, however, is cut down on a particular type of spam, where a spammer falsely poses as some reputable company.

thomasrutter on May 3, 2010 12:46 AM

I had a major issue when I built my first website and had an email submission form with a major security vulnerability. Even though a good contact form is still the best way to go to avoid spam, you really need to know what you're doing.

Arthur Clyne on June 16, 2010 6:47 AM

I WANT TO SEND AN STORY ON HORROR NIGHATS DRAMA ON CHANNEL STAR ONE.

MOMO on June 29, 2010 6:17 AM

Then you can see more good movies about hotels at this link.

Bu sitede birçok filmi hd izleyebilirsiniz.

hd film izle

rdy_tr on July 21, 2010 9:13 AM

@Brad Davis:
I'm not an expert on this, but when I looked into it several years ago, some mail servers operated as black holes to avoid email address harvesting/verification for spams.

Tore Bostrup on August 5, 2010 7:25 AM

Verify your Comment

Previewing your Comment

This is only a preview. Your comment has not yet been posted.

Working...
Your comment could not be posted. Error type:
Your comment has been posted. Post another comment

The letters and numbers you entered did not match the image. Please try again.

As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

Having trouble reading this image? View an alternate.

Working...

Post a comment

Content (c) 2009 Jeff Atwood. Logo image used with permission of the author. (c) 1993 Steven C. McConnell. All Rights Reserved.