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)

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.

46 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);”

  10. Sam Chan Says:

    Hi khromov,
    Is it possible use GIF animation?
    I try it before and not working. Just display a freeze image.
    Thanks!

  11. Bob Says:

    i have everything working – its generating the image correctly but Piwik just is NOT recognizing the visit. my site id and token auth are definitely correct. Does this not work anymore? Please help!

  12. Sven Says:

    Hi khromov,

    Thank you for this tip, it was really useful.

    However, when I embed a tracking image such as:

    it works from somewhere outside of example.com, such as from an e-mail.

    However, it does not work when it is embedded somewhere on example.com, but the image renders!

    I am almost tearing my hair off! I can not find the reason. Any ideas?

    Kind regards,

    Sven

    • Sven Says:

      I tried to paste some code but it was removed.

      The code was basically the same trackning image as the one you used under step 4 above. I used the same tracking image in an e-mail and embedded in the site “example.com” and it tracks from the e-mail but not from a visit to the site.

  13. Sven Says:

    Hej khromov!

    Thanks for your reply.

    Here is the pb: http://pastebin.com/9NUTPyy3

    As an aside, I have the firefox plugin DoNotTrackMe installed (the plugin, not the setting in ff).

    It does not have an effect on the img.png tracker, I can have it turned on or off, nothing changes: Page outside works, page from server doesn’t work.

    Strange, isn’t it? Any ideas?

    Cheers/ Sven

    • Sven Says:

      Hmm… maybe a bit unclear here… I meant to mention the plugin as an extra information that may be of importance but probably not.

      What I meant was strange was not the behaviour with the plugin, but the general behaviour of Piwik described earlier, i.e. logging when img.png is requested from a page residing on my computer but not logging when requested from a page residing on the hosting server.

      /S

    • khromov Says:

      We can try a few things:

      – Load example.com/test.html and check in Firebug what the status code for the image is. It should not be “304 Not Modified”, that means the image was fetched from browser cache and no request to Piwik was generated.

      – Load the image directly into your browser (example.com/img.png). Press Ctrl + Shift + R to perform a no-cache reload. This -should- generate a hit for each time you do the no-cache reload.

      – Try using img.php instead of img.png in your image tag. (The .htaccess is purely for cosmetic reasons.)

      – Print the content of $_SERVER instead of the image (remove the content-type declaration as well.) Compare between a local load and a remote load from example.com/test.html – any differences? Anything unexpected?

      Hope that gets you started. 🙂

      • Sven Says:

        Thanks khromov for the suggestions!

        Sorry for late reply, had to do some fire extinguishing at work.

        I did some trials, here are the results:

        Setup # 1: example.com/index.html with JS tracker and image tracker
        Setup # 2: example.com/test.html with img tracker
        Setup # 3: computer/test.html with image tracer
        Setup # 4: example.com/img.png (img.png => the image tracker via .htaccess)
        Setup # 5: example.com/test.html embedded with (img.php is the tracker)
        Setup # 6: example.com/test.html embedded with ,(img.php containing “echo($_SERVER);” instead of the png code).
        Comment on #6: $_SERVER never gets printed, only the alt=”XYZ” alternative for the in test.html

        DNTM = DoNotTrackMe Firefox Plugin
        Result = Result page view / unique page view (t=triggered, nt= not triggered)
        FB = Firebird status

        | Setup | DNTM | Result | FB |
        |——–+———+———+——|
        | 1 | On | nt/nt | 200 |
        | 1 | Off | t/t | 200 |
        |——–+———+———+——|
        | 2 | On | nt/nt | 200 |
        | 2 | Off | nt/nt | 200 |
        |——–+———+———+——|
        | 3 | On | t/t | 200 |
        | 3 | Off | t/nt | 200 |
        |——–+———+———+——|
        | 4 | On | t/nt | 200 |
        | 4 | Off | t/nt | 200 |
        | 4 | Off | t/nt | 200 |
        |——–+———+———+——|
        | 5 | On | nt/nt | 200 |
        |——–+———+——–+——-|
        | 6 | On | nt/nt | 200 |
        |——–+———+——–+——-|

        Preliminarily looks like img.png works when accessed on it’s own, but not when embedded as a tag in another file when on the server. When on computer seems to work all the time.

        Not sure about the img.php with $_SERVER code; should I still call it with the image tag from e.g. index.html?

        Any ideas what is going on?

        /Sven

    • khromov Says:

      Hi Sven,

      Did you get this resolved?

      I have a suspicion that this is somehow related to your development environment.

      If you can replicate this on a live site (ie. when both Piwik and your tracking code are on a server on the internet), please email me at stanislav.khromov+nospam@gmail.com

  14. Tom Says:

    Dear khromov,

    Thank you very much for this tool. I’ve been looking for such a thing for quite a while and I’m really glad that a.) you created it and b.) you’re still around. 🙂

    I’m writing you because I’m constantly getting my own servers IP. (ie. when I’m working with stats_t, the normal tracking is working fine.)

    Here is how I proceeded:

    I took a fresh installation of the newest piwik.
    I created a new site. (ID 2)
    I created a new user.
    I gave him admin rights for the new site (ID 2).
    I noted his token.
    I downloaded the three files stats_t.php / stats.png and PiwikTracker.php (I pulled this one out of my installation, example.com/analytics/etcetcetc.)
    I entered the site ID and the token and the link to my piwik installation into my stats_t.php
    I copied those files into the folder on my website /images.
    I modified the .htaccess file as mentioned on your site.

    But all I get is my servers IP. 😦 I’ve read through the comments here and tinkered around for almost two days. I’m adding a justpaste-link to my configuration files.

    http://justpaste.it/dpcd

    Any help would be appreciated! I don’t know what I’m doing wrong, but I know that I’m moving in circles. 😉

    Best wishes

    Tom

    • slim boy fat Says:

      don´t know if i am on the wrong way here…but as your files on justpaste are mostly accurate – there is one question: did it help when you entered only your actual token?
      instead of having this:
      $token_auth = ‘&token_auth=8ae2………78ee4)’;
      $token_auth = ‘8ae2………78ee4’;
      but i think you did not have it that way…

      • khromov Says:

        Yeah this looks wrong. The token should just be a string, for example:

        $token_auth = “3d4cd9433b0361b8780a4ba62860ed2c”;

        If that still doesn’t work, try using the main admin token (Which you can find in the API tab in Piwik, at the top)

    • khromov Says:

      Hey Tom,

      Check slim boy fats reply!

      • slim boy fat Says:

        hey tom,

        it´s just that i am experiencing the same problem here…
        all is set up correctly, no error in the apache log.
        i am get tracked fine when i write an email (and the image-link in my html-mail is called), but when i client is opening this mail, i don´t get any action in piwik.

        i will keep on looking around and trying.

        thanks!

  15. slim boy fat Says:

    hi khromov,
    i figured out my problem. it was something completely different: thunderbird was causing the “call” of the image, when i composed an email. after ixquick-ing a while i found the solution. you have to insert this comment in the link to the tracking image:
    moz-do-not-send=”true”
    this way the image is not send by my mail, but it gets tracked, when the mail is opened and so the image called. this way my client is not more listed and everythings works like a charme.
    thanks again for your great tutorial!

  16. MxyzptlkFishStix Says:

    Does this work with the latest version of Piwik?

    • khromov Says:

      It should still work. Maybe some minor API change (it’s been 3 years after all). If you have any trouble feel free to write here.

  17. Alex Says:

    Does anyone have this working on the latest version of Piwik? Is it needed any changes based on the post? I did everything accordingly and it did not work. I can’t get the track on the piwik console. Any tips will be welcomed.

    I’m using Piwik 2.16.0

  18. Jdoe Says:

    Hello,

    When we try to access the png, the php file loads and we are able to see the image, however the tracking code does not trigger in the background and we receive this error on our server log:

    [things in are actual parameters, removed for privacy]

    file_get_contents(test.com/piwik/piwik.php?idsite=1&rec=1&apiv=1&r=&cip=&token_auth=&_idts=&_idvc=&_viewts=&_id=&url=&urlref=&pv_id=&action_name=Image+viewed): failed to open stream: No such file or directory in ////vendor/piwik/piwik-php-tracker/PiwikTracker.php on line 1608

    We have checked and double checked the site ID and token auth. Token Auth is the one we found under API settings tab for our piwik super user.

    • Jdoe Says:

      Hello,

      When we try to access the png, the php file loads and we are able to see the image, however the tracking code does not trigger in the background and we receive this error on our server log:

      [things in [] are actual parameters, removed for privacy]

      file_get_contents(test.com/piwik/piwik.php?idsite=1&rec=1&apiv=1&r=[r]&cip=[cip]&token_auth=[token_auth]&_idts=[idtsnumber]&_idvc=[idvc]&_viewts=[viewtsnumber]&_id=[id]&url=[url]&urlref=&pv_id=[pvid]&action_name=Image+viewed): failed to open stream: No such file or directory in /[path]/[to]/[piwik]/vendor/piwik/piwik-php-tracker/PiwikTracker.php on line 1608

      We have checked and double checked the site ID and token auth.

      • khromov Says:

        Make sure you are using a recent version of the PiwikTracker library, this blog post is from 2011. 🙂

  19. pupazze Says:

    Still works perfect for me. I just directly linked to the PiwikTracker.php of my installed piwik. Thanks for this tutorial

  20. k Says:

    Aussi bon que Cousy était, Russell était la force motrice de ces Celtics.


  21. newtown ntc33

    Collect visitor stats using any image with the Piwik Tracking API | Living with technology


Leave a reply to Bob Cancel reply