Using an ESP32 to get my WordPress viewing stats

I remember seeing an ESP8266 project years ago that displayed a Youtubers subscriber count on an LED display. I was really impressed by that project. Recently I wondered if a similar thing could be done with wordpress.com stats, in this case not showing subscribers, but daily views.

I did come across this response to a WordPress forum How can I query blog stats via HTTP? that includes “You can, however, access your blog’s stats at an older (still active) API: http://stats.wordpress.com/csv.php” That post was back in 2013. It looks like that API is still running but as there are newer APIs it may not remain around too long.

While it only provides stats on a limited number of things it does include daily hits and total hits which are the two things that I’m interested in. It is also really easy to use and set up. To use it you only need your site URL and an API key.

Getting the URL and API key

The URL is just the site URL. The API key was just as easy to get. In a browser where I was already logged into my WordPress account I simply went to https://apikey.wordpress.com/. The API key displays on the page.

Testing in a browser

The next bit was to test it in a browser. Going to https://stats.wordpress.com/csv.php displays some information about it and the parameters, that is this:

Required parameters: api_key, blog_id or blog_uri.
Optional parameters: table, post_id, end, days, limit, summarize.

Parameters:
api_key     String    A secret unique to your WordPress.com user account.
blog_id     Integer   The number that identifies your blog. Find it in other stats URLs.
blog_uri    String    The full URL to the root directory of your blog. Including the full path.
table       String    One of views, postviews, referrers, referrers_grouped, searchterms, clicks, videoplays.
post_id     Integer   For use with postviews table. Also accepts a comma-separated list of integers.
end         String    The last day of the desired time frame. Format is 'Y-m-d' (e.g. 2007-05-01) and default is UTC date.
days        Integer   The length of the desired time frame. Default is 30. "-1" means unlimited.
period      String    For use with views table and the 'days' parameter. The desired time period grouping. 'week' or 'month'
                      Use 'days' as the number of results to return (e.g. '&period=week&days=12' to return 12 weeks)
limit       Integer   The maximum number of records to return. Default is 100. "-1" means unlimited. If days is -1, limit is capped at 500.
summarize   Flag      If present, summarizes all matching records.
format      String    The format the data is returned in, 'csv', 'xml' or 'json'. Default is 'csv'.

Non-working query example: ?api_key=123456789abc&blog_id=155&table=referrers&days=30&limit=-1&summarize

Result format is csv with one row per line and column names in first row.

Strings containing double quotes, commas, or "\n" are enclosed in double-quotes. Double-qoutes in strings are escaped by inserting another double-quote.
Example: "pet food" recipe
Becomes: """pet food"" recipe"

Developers, please cache the results for at least 180 seconds.

Next was to try and get the current days hits. I started by constructing a url. The first part with the blog url and api key is the same for all requests. In my case something like:

https://stats.wordpress.com/csv.php?api_key=myaccountkey&blog_uri=www.myblogname.com

I say something like because that url needs to have myaccountkey replaced with the actual key and myblogname changed to work.

The remainder of the url is made up of parameters to get the data I’m after

I tested these:

&days=-1 - lists hits per day for a long period. In my case it seems to go back to when the blog started
&days=-1&summarize - displays only the hits for the last day

At this point I started seeing discrepancies with what I see within WordPress with the last days hits. In my case it was all about time zones. These seem to return the number of hits for the current day in UTC. I am UTC + 10 hours so I found I was not getting todays numbers until after 10:00am. Using the parameters below seems to fix it and returns todays numbers that match what I see in WordPress

&period=days&days=1&summarize

For my blog the full url looks like this:

https://stats.wordpress.com/csv.php?api_key=myaccountkey&blog_uri=www.myblogname.com&period=days&days=1&summarize 

Next was trying to get the number of hits for all time. I was unable to find a way to return stats that included the current day, so I settled for this:

&days=-1&summarize

It is sometimes a few out but then catches up. I think this too is due to the difference in timezones. Not perfect, but good enough for me.

Writing an Arduino sketch

Next was the task of writing an Arduino sketch. I started with this Random Nerd Tutorial ESP32 HTTP GET and HTTP POST with Arduino IDE (JSON, URL Encoded, Text). I’ve found these tutorials to be really helpful for using the ESP32.

With a few modifications to one of the examples I’ve got it returning data. It returns a string of character, for example

"views"
8

Yes, this really is a small blog. To get that into a variable with just the number as an integer I’ve used subtring and toInt to keep only the part after the 8th character and turn it into an integer that I can use with LED displays.

todaysViews = payload.substring(8).toInt();

I don’t know if there is a better way to do this, but so far it is working.

I’ll list basic code that I started with that sends the number of the day’s views to the serial monitor. I’ve developed it further to run two LED displays and a speaker, but I think it needs more work before it should be released into the wild. I doubt anyone else would want to use the two different displays that I am using. I’ve only used them as I have a thing for LED displays and had some spare ones.

Here it is in a case with two LED displays and a speaker for notifications.

The Arduino code

/*
  Sample sketch using ESP32 to fetch stats from wordpress.com

  An old API http://stats.wordpress.com/csv.php is used to source the stats. Go to
  this URL to get a list of parameters

  An API key is required and can be gained by logging into your wordpress account
  and going to https://apikey.wordpress.com/

  Developers are asked to cache the results for at least 180 seconds (3 minutes)
*/

#include <WiFi.h>
#include <HTTPClient.h>

// Your Wifi network credentials
const char *ssid = "wifiname";         // Replace with WiFi network name
const char *password = "wifipassword";        // Replace with WiFi password

// Worpress URL and key
String BLOGURL = "www.blogname.com";      // The wordpress site URL
String APIKEY = "apikey";             // Replace with Wordpess account API key


// Store stats
int todaysViews;

// For storing last time the stats where checked
unsigned long lastTime = 0;

// Milliseconds between API calls. WordPress request no more than every 180 seconds
unsigned long timerDelay = 300000;

void setup(){
// Serial monitor for displaying results  
  Serial.begin(115200);

  connectToWifi();

  // Check stats imediately when connected
  updateStats(); 
}

void loop(){
  static unsigned long lastTime = 0;

  // Check if it is time to update stats
  if ((millis() - lastTime) > timerDelay) {
    updateStats(); 
    lastTime = millis();
  }
}

void connectToWifi () {
  // Connect to Wi-Fi
  Serial.print("Connecting to: ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("-----------------------");
}  

void updateStats() {
//Check WiFi connection status
    if(WiFi.status()== WL_CONNECTED){
      HTTPClient http;

      String serverName = "https://stats.wordpress.com/csv.php?api_key=" + APIKEY + "&blog_uri=" + BLOGURL + "&period=days&days=1&summarize";
      
      http.begin(serverName.c_str());
      
      // Send HTTP GET request
      int httpResponseCode = http.GET();
      
      if (httpResponseCode>0) {
        Serial.print("HTTP Response code: ");
        Serial.println(httpResponseCode);
        String payload = http.getString();

        // Print payload for debugging
        Serial.println("Payload: ");
        Serial.println(payload);
        
        Serial.print("Today's views: ");
        // Keep only part after 8 characters from start and convert to int
        todaysViews = payload.substring(8).toInt();
        Serial.println(todaysViews);

        Serial.println("-----------------------");
      }
      else {
        Serial.print("Error code: ");
        Serial.println(httpResponseCode);
      }
      // Free resources
      http.end();
    }
    else {
      Serial.println("WiFi Disconnected");
    }
}

I don’t know if anyone will find this useful, how long the API will be around or if there are security implications of using it. However, I found it to be an interesting project. Let me know if you have any feedback or know of how this might be achieved with more modern APIs.

2 thoughts on “Using an ESP32 to get my WordPress viewing stats

Add yours

  1. Interesting that there’s not a way to grab the stats from a newer API. I took a quick look through the REST API endpoints, and couldn’t find anything related to view statistics… so it seems the legacy API is the only way to grab that data for now.

    I picked up a 64×32 LED panel a few months ago and was thinking about building some sort of stats display for Twitter, YT, WP, and others… your post here is motivating me to do that project sooner rather than later. Great post as always, Garry!

    Like

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 )

Facebook photo

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

Connecting to %s

Website Powered by WordPress.com.

Up ↑

%d bloggers like this: