Collect visitor stats using any image with the Piwik Tracking API

Piwik is an open source web analytics system in PHP and a great alternative to Google Analytics.

It offers simplified tracking via an image tracking code:

<!-- Piwik Image Tracker -->
<img src="http://example.org/piwik/piwik.php?idsite=1&rec=1" style="border:0" alt="" />
<!-- End Piwik -->

In some scenarios, you might not want to expose that you are using Piwik analytics, or would like to avoid loading unnecessary resources.

Let’s use the Piwik Tracking API to turn any image into a tracker. This is useful for websites, newsletter stats and email signatures alike.

Prequisites

You need to have a Piwik install running with administrative access. Apache is required to get a “nice” image url.

Step 1 – Setup Piwik

Create a new website in Piwik, which will contain your stats for the image. Make note of the new site ID (Visible in Settings > Websites)

Create a new user and give that user admin rights to the website. Make note of the token_auth for that user. (Under Settings > Users)

Step 2 – Get the PiwikTracker.php Tracking API

You can obtain this file by going to the following URL (Replace example.org with your piwik install path)

http://example.org/piwik/index.php?module=SitesManager&action=downloadPiwikTracker&idSite={$IDSITE}&piwikUrl=http://example.org/piwik/

You can also find a copy of the file here.

Step 3 – Build the tracking code
Pick an image you’d like to use, name it stats.png and put it in a folder on your web server. I am going to use this “thumbs up” clipart. Also put PiwikTracker.php in this folder.

Now, create the file stats_t.php. (Base code below) Change line 3 and 4  to your own site id and the token_auth of the user you created in step 2. Also set your Piwik URL at line 10. If you want to distinguish between multiple tracking images, you can change line 22 to have a different message. That means you can track any number of images using one site in Piwik.

<?php
    //Set the id of your piwik site here
    $idSite = 1;
    $token_auth = 'your user token here';

    //Load Piwik Tracker
    require_once 'PiwikTracker.php';

    //Set the URL path to your Piwik Installation
    $t = new PiwikTracker($idSite,'http://example.org/piwik');

    //Auth to allow for more API functions
    $t->setTokenAuth($token_auth);

    //Set correct IP (Should be users, not the web server issuing the request)
    $t->setIp($_SERVER['REMOTE_ADDR']);

    //Set referrer (if applicable)
    if(isset($_SERVER['HTTP_REFERER']))
       $t->setUrl($_SERVER['HTTP_REFERER']);

    $t->doTrackPageView('Image viewed');

    $im = imagecreatefrompng("stats.png");

    //For transparency (Alpha blending)
    imagealphablending($im, true);
    imagesavealpha($im, true);

    //Set header
    header('Content-Type: image/png');
    //Output image
    imagepng($im);
    //Unload image
    imagedestroy($im);
?>

You can set many more visitor details, refer to the reference.

Create a .htaccess file in the same folder. We will use this to rewrite the URL so that we can still use a .png extension for the file. When stats_t.png is called, Apache will instead load stats_t.php , which will run the tracking code.

RewriteEngine On
RewriteRule stats_t.png stats_t.php

Your folder structure should now look like this:

Verify that your image is displayed properly in a web browser by navigating to stats_t.png

Verify that Piwik recorded the visit correctly. If it did not, make sure you have entered $token_auth and $idSite correctly.

Step 4 – Display your new tracking image anywhere

Now you can include your image anywhere, like this:

<img src="http://khromov.se/email2/stats_t.png" alt="thumbs up" />

If you would like more information please see the official documentation of the Tracking API.

Let me know if this helped you out or if you have any suggestions or improvements!

Update: Now includes referrer tracking. If the image is used on a page, you will see what page it is used on. (See line 19 and 20 of stats_t.php)

Advertisement
Explore posts in the same categories: Computers, Programming, Technical solutions

Tags: , , , , ,

You can comment below, or link to this permanent URL from your own site.

18 Comments on “Collect visitor stats using any image with the Piwik Tracking API”

  1. matt Says:

    Great tutorial on how to track newsletters open rates with Piwik :) Would you mind also posting this on the forum.piwik.org ? I’m sure many people would enjoy this tip!

  2. Vivek Rp Says:

    Hello,
    I did same as you told but its not working… Its on evnts.in

    http://evnts.in/analytics/ is my piwik installation..

  3. Vivek Rp Says:

    //Set your tracker URL
    $t = new PiwikTracker($idSite,”);

    Which address to give here?? of Piwik folder or the new folder where we have stats.png??

    • khromov Says:

      Hi Vivek!

      The PiwikTracker takes the site id, and the full URL to your piwik installation. In your case, that would be:
      $t = new PiwikTracker($idSite,’http://evnts.in/analytics/‘);

      I have simplified the code example, hopefully it is more clear now.

  4. @metacowboy Says:

    Excellent post must test that right now a good way to track visibility in FB too if you add some random variable behind the image stats_png?1234

    • khromov Says:

      It’s very easy to append custom ID to image stat. Just do something like…
      stats_t.png?id=200

      Then in the PHP:
      $id = $_GET["id"];

      $t->doTrackPageView(‘Image viewed with ID: ‘ . $id);

      Cheers!

  5. Alva Says:

    For some reason the IP given in Piwik is my server IP, any thoughts?

    $t->setIp($_SERVER['REMOTE_ADDR']);

    • khromov Says:

      You need administrative permission for the web site to alter the IP this way.

      If you have administrative permission for the site with that user, can you try using your global token_auth (API link in Piwik top menu.) and see if that works?

    • Alva Says:

      I just figured it out. I had set my new user to admin rights, but I didn’t see there was a dropdown to select which website those rights belonged to.

      Basically I gave admin rights for the right user, to the wrong id_site.

      • khromov Says:

        The user access panel can be a bit unintuitive at first!

        Good luck with your project!

  6. Alva Says:

    Thank you for the very quick reply btw, and the excellent script!

  7. ellisgl Says:

    Here’s some re-written code that uses expiration headers

    setTokenAuth($token_auth);

    //Set correct IP (Should be users, not the web server issuing the request)
    $t->setIp($_SERVER['REMOTE_ADDR']);

    //Set referrer (if applicable)
    if(isset($_SERVER['HTTP_REFERER']))
    {
    $t->setUrl($_SERVER['HTTP_REFERER']);
    }

    $t->doTrackPageView('Strain Plumbing');

    if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == filemtime($file))
    {
    header('Last-modified: '.date(DATERFC_1123, filemtime($img)), true, 304);
    exit;
    }

    $im = imagecreatefrompng($img);

    //For transparency (Alpha blending)
    imagealphablending($im, true);
    imagesavealpha($im, true);

    //Set header
    header('Content-Type: image/png');
    header('Expires: '.date(DATE_RFC1123, time()+2592000));
    header('Last-modified: '.date(DATE_RFC1123, filemtime($img)));

    //Output image
    imagepng($im);

    //Unload image
    imagedestroy($im);

    • khromov Says:

      Could you explain the reasoning for this, specifically – why would it be beneficial to instruct the receiving browser to cache the image?

      Loading the image multiple times is already correctly labeled as a returning visit (a “pageview”) in Piwik.

  8. ellisgl Says:

    Because YSlow! and PageSpeed complain about images that are not cached. =) If you are using a larger image, why resend it and waste bandwidth each time. Also if you are just capturing the view, then why waste CPU resources rebuilding and outputting the image. of course it’s probably not using up that much CPU for a single instance, but if you have a site getting thousands of hits, it can add up.

  9. ellisgl Says:

    Of course thinking about it, you don’t don’t need to use the GD functions, you could do “echo file_get_contents($img);”


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s


Follow

Get every new post delivered to your Inbox.

Join 221 other followers