O'Reilly

You Know How I Know You Read My Email?

By on  

I've probably mentioned this before, but I've designed and coded numerous HTML email templates for my customers. Though I currently use an email service that tracks click-throughs, bounces, and opens, it wasn't always that way. I had to rely on my own methods of tracking click-throughs and opens. Here's how you do it.

Tracking Click-Throughs: The Email HTML

<a href="http://mydomain.com/landing.php?e=[email protected]">Click here</a> for more information!

Tracking Click-Throughs: The PHP

// (inside "landing.php")

if(isset($_GET['e']))
{
	//validate and record click-through here
}

Tracking click-throughs was the easy part. All you do is attach a $_GET variable to the link and listen for that variable on the website. Simple!

Tracking Opens: The HTML

<img src="http://mydomain.com/emails/record.php?e=[email protected]" alt="Tracker" />

Tracking Opens: The PHP

// (inside "record.php")
header('Content-Type: image/gif');

if(isset($_GET['e']))
{
	//validate and record click-through here
}
	
//push out image
if(ini_get('zlib.output_compression')) { ini_set('zlib.output_compression', 'Off');	}
header('Pragma: public'); 	// required
header('Expires: 0');		// no cache
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private',false);
header('Content-Disposition: attachment; filename="blank.gif"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.filesize('blank.gif'));	// provide file size
readfile('blank.gif');		// push it out
exit();

This involves a bit more. You need to first tell the PHP file that it should be served as an image. Then, you read the $_GET variable value and record that the user had requested the file. Lastly, you push out the actual image.

Of course, this isn't the best method of email tracking. You miss bounce reports, forwards, and a host of other important stats. You do, however, get the most important information: who viewed your email?

Track.js Error Reporting

Recent Features

  • Write Better JavaScript with Promises

    You've probably heard the talk around the water cooler about how promises are the future. All of the cool kids are using them, but you don't see what makes them so special. Can't you just use a callback? What's the big deal? In this article, we'll...

  • Introducing MooTools Templated

    One major problem with creating UI components with the MooTools JavaScript framework is that there isn't a great way of allowing customization of template and ease of node creation. As of today, there are two ways of creating: new Element Madness The first way to create UI-driven...

Incredible Demos

  • Animated Progress Bars Using MooTools: dwProgressBar

    I love progress bars. It's important that I know roughly what percentage of a task is complete. I've created a highly customizable MooTools progress bar class that animates to the desired percentage. The Moo-Generated XHTML This DIV structure is extremely simple and can be controlled...

  • Sexy Opacity Animation with MooTools or jQuery

    A big part of the sexiness that is Apple software is Apple's use of opacity. Like seemingly every other Apple user interface technique, it needs to be ported to the web (</fanboy>). I've put together an example of a sexy opacity animation technique...

Discussion

  1. Jon

    Doesn’t this only work if I allow HTML content in my email program?

  2. @Jon: Correct. Text-only email doesn’t allow for this. Most clients are set up to allow HTML by default.

  3. Gmail also blocks all images by default.

  4. You set the Content-Type header twice, once for jpeg at the top and then again for gif.

  5. @Dan: Thank you for pointing that out. Fixed!

  6. Sebastian Otaegui

    So that is why you need to disable html in your email reader. To avoid email harvesting.

    ’nuff said.

  7. dan

    I am having problems with this script. Instead of blank image, the browser will display the broken image icon. When I look at the source I can see that IMG SRC still shows link to php tracker file.

    What am I missing? Thanks for yor help

  8. @Dan: You do have a “blank.gif” file, correct?

  9. Einer Iriarte

    Greetings and as is the “record.php” not much php, but if I want I could explain how it is please?

  10. antonio

    Hello,

    I´ve included the html code in my newsletter, and create the record.php. I can see the blank.gif but i dont know where the emails are stored and how should i do to get them.

    Regards,
    Antonio.

  11. Nice trick !
    I think on line 2 image type should be image/gif if the image is blank.gif (instead of image/jpeg) ?

    Thanks
    Sylvin

  12. Good catch Sylvin — updated.

  13. have tried eveyrthing but cannot get my to work–use a cable provide– with my old computor worked just fine–new comp s dell

  14. isa

    how comes it can be that you cant view your images on ypur email addres after more than 3 mopnths let me say that its becauyse of the HTML .So how should I go aboutthis let me call it aproblem?

  15. Didier

    Hi, the script is ok and works fine indead, but only if the client doesn’t block is images in his mail program.
    Is this correct??

  16. nabil

    hi, this post is just awesome. a Big thank you David.
    any idea about how to detect forwarded emails ? :p

  17. Martin
     I I'm a dummy in PHP and web stuff. could clarify some point, where the gif image should be placed, (same directory, another one, ?) and could give me an example of script to get the email address and store it a txt file? that would help a lot thank 
  18. Martin
    one more thing, what should the right for the record file? (604, 755n 777n ... ) 
  19. Raham

    Hi David Walsh!
    First of all if the user does not click on the link then…???
    Now secondly,what if the user has already disable the images in his/her mail then…???

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!

Recently on David Walsh Blog

  • OSCON Portland:  Conference  Discount!

    O'Reilly puts on the best web industry conferences in the world.  These conferences include Fluent Conference, Velocity Conference, and the upcoming OSCON in Portland, Oregon from July 20-24.  Open Source Convention (OSCON) is a conference that focuses specifically on open source developers and the tools and possibilities...

  • Follow Redirects with cURL

    I love playing around with cURL. There's something about loading websites via command line that makes me feel like some type of smug hacker, just like tweeting from command line does. I recently cURL'd the Google homepage and saw the following: I found it weird that Google...

  • Developers Have WordPress, Amateurs Have Squarespace, Professional Designers Have the NEW Webydo!

    Web design platforms have traditionally come in one of two varieties. There are the solutions like WordPress and Drupal that are incredibly powerful, but an understanding of web development and coding is required to be able to use those platforms effectively. On the other side of the...

  • Chris Coyierâs Favorite CodePen Demos II

    Hey everyone! Before we get started, I just want to say it’s damn hard to pick this few favorites on CodePen. Not because, as a co-founder of CodePen, I feel like a dad picking which kid he likes best (RUDE). But because there is just so...

  • GSAP + SVG For Power Users: Motion Along A Path

    Now that the GreenSock API is picking up steam, there are many tutorials and Getting Started guides out there to provide good introductions to the library, not to mention GreenSock’s own Forum and Documentation. This article isn’t intended for beginners, but rather a...