Most modern email client software includes a function whereby a user can send an email "return receipt requested." This is supposed to email the sender (you) to notify you when your email has been read by the recipient.
The problem is that depending on the email client software that your recipient is using, he or she will most likely be given the option to suppress that return-receipt from being sent back to you. This renders the return-receipt system almost completely unreliable as a means of detecting when someone has read your email.
If you have access to a web server that's running PHP, you can make your own return-receipt system that is (almost) guaranteed to work. What's more, you can even generate a mass email from PHP, with each email having its own uniquely-distinguishable return receipt, thereby allowing you to keep tabs on which recipients have read the email and which have not.
When it will work and when it won't
This method relies on only one thing: the recipient's mail client loading HTML images referenced by URL, as in:
<code><img src="" /></code>
Before you groan and say you've seen this type of "hack" before, bear with me, as what we're doing is much cooler and more useful than a simple image reference.
Note that some mail clients do block URL-based images for emails coming from an unrecognized address. Mozilla Thunderbird is among these--it allows the user to choose whether or not to load outside images referenced within the email body.
How to do it
What we'll be doing is sending an HTML email with an IMG tag within the body. Only, the IMG source will not point to an actual image, but instead it will point to a PHP page on your web server. Start with a new email, and insert the following HTML:
<code><img src="" /></code>
Assuming you'll be using this handy trick more than once for different recipients and/or different occasions, you can optionally add query data to the URL so that you can differentiate between the different notifications you recieve later. And yes, query data included this way will be passed through to the script. Try this:
<code><img src="" /></code>
This way you can use the same script for multiple emails and have them each generate unique return-receipts, so you'll know which particular emails were already opened and which were not. This is particularly useful if you have PHP code that generates mass-emails; simply replace the query string with a variable, so that each recipient will generate a unique return-receipt. If you don't know how to pick up query data in PHP, don't worry. Examples are coming.
You now have a PHP script that will be executed when the recipient opens your email, so you can handle this any way you like. Have the script add an entry to a database, or append an entry to a log file, or anything else you can dream up. The example I'll give is the one which I find most useful, which is instant email notification (that is, an automatic email to you, the sender, notifying you that your email has been opened by the recipient). You can even include environment variables in the email, to get things like the recipient's IP address and browser version. I won't get into how that could be useful, but use your imagination.
Put the following snippet into your PHP page. It will auto-generate an email notification and dispatch it to you. In this example I've included the query data from the example above:
$from_email = '';
$to = '';
$subject = "Email opened by ".$_GET['you'];

$headers = "From: ".$from_email."\r\nX-Mailer: php";
mail($to, $subject, $body, $headers);
You can edit the subject and body however you like. The $to variable will be the email address where the return-receipt gets sent, so in most cases this should be set to your own email address. The $from_email variable is the address that the notification will appear to come from, and you can set this to whatever you want (even a non-existing email address, in most cases). I've included the IP address and user-agent variables in the body, which you can leave in or remove as you see fit.
The rest is up to you. Here are a few things to keep in mind:
  1. All PHP code within the referenced page will be executed when the recipient opens your email. The sleep() function is interesting here in that it causes a delay in the recipient's email client. I myself don't see any use for it, but I do find it interesting.
  2. Code that would normally cause HTML output for viewing by a client browser, such as "echo" statements, will not actually output anything.
  3. Depending on the recipient's email client, the image reference may show up as a "broken image" icon, which the recipient may see as suspicious. To prevent this, you can have your PHP script output an actual image after it's done executing your code. Simply add this line to the end of your script:
<code>header('Location: image.gif');</code>
Replace "image.gif" with an actual image path/filename on your server. All the code that comes before that line will be executed, and then the image will be loaded by the recipient's email client. It will look to the recipient just as it would if the IMG reference pointed to an image file in the first place. I recommend always including this statement, even if it only points to a tiny white (or transparent) placeholder image.
Sending email with URL-based images in Mozilla Thunderbird
Sending the actual email is fairly simple, however sending the email manually in Mozilla Thunderbird presents a unique problem to this return-receipt gizmo.
Thunderbird automatically detects URL-based IMG tags in your outgoing messages and replaces them. It downloads the referenced image, attaches it to the email, and converts your IMG source to reference the attached file instead of the remote URL. Since the point of the IMG tag is to execute PHP code on your web server, this would completely break the return-receipt functionality. The good news is that this behavior can be prevented, although you have to do it for every image in every email individually as there is no global setting (at least none that I've been able to find).
Open Thunderbird and start a new email. Click in the body of the message and click the Insert menu, then choose Image. Type in your URL, then click "Advanced Edit." In the Attribute field, type "moz-do-not-send" (without quotes), and for Value type "true" (again without quotes). Click OK a couple of times. That's it. You just told Thunderbird not to convert your image references to attachments. Your IMG tag will now call your remote PHP script when the recipient opens your email.
That's about it. I hope you find this as useful as I have.