Message Notifications using PHP and Pushbullet

I’ve been amusing myself following through an excellent series on self-hosting WordPress by Ashley Rich. Mostly so I can experiment with Nginx, pinch the best ideas and use them myself 🙂

Everything had gone swimmingly on a test VPS running the latest LTS version of Ubuntu, but when I tried to implement some of the ideas on the shared hosting1 where this blog runs I ran into a bit of trouble. I was trying to get WordPress installation checksum verification2 and push messaging via Pushbullet working, but the https connect to the Pushbullet API would always fail. After some experimentation it turned out that the command line version of Curl was ancient3 and it wasn’t going to work. I already knew I was wasting my time asking the hosting company to upgrade the version; I had tried that before with another shell program that was obsolete and they (politely) declined4. So, time to get programming!

I already know that the python version on the hosting is ancient and doesn’t have SSL support at all5, ditto Perl, so I am going to have to use PHP. I won’t have a problem with that as there are versions up to 7.1 on this host and the SSL libraries are properly current too. Command-line PHP isn’t great, but it will work just fine for this application.

Here is the resulting simple program to send a notification using the Pushbullet API. This is called from a Bash script if the WordPress verification checks fail; the resulting warning message turns up on all my registered devices.

* PHP program to send messages to pushbullet.
* Usage: php message-pushbullet.php creds='...' title='...' body='...' [quiet] [headers]
error_reporting (E_ALL);

$url = "";
$type = "note";

if(php_sapi_name() == 'cli'){
    //convert cli params to GET params (chop off name of program which is 1st)
    parse_str(implode('&', array_slice($argv, 1)), $_GET);
//process parameters
$credentials = isset($_GET['creds']) ? trim($_GET['creds']) : "";
$title = isset($_GET['title']) ? trim($_GET['title']) : "";
$body = isset($_GET['body']) ? trim($_GET['body']) : "";
$quiet = isset($_GET['quiet']) ? true : false; //silent mode
$headers = isset($_GET['headers']) ? true : false; //show headers for debugging

if(!$credentials || !$title || !$body){
    echo "Usage: message-pushbullet creds='...' title='...' body='...' [quiet] [headers]\n";

$post_fields = json_encode(compact('type', 'title', 'body'));

$ch = curl_init();

$options = [
    CURLOPT_URL => $url,
    CURLOPT_HTTPHEADER => ['Access-Token: ' . $credentials, 
                            'Content-Type: application/json',
                            'Content-Length: ' . strlen($post_fields)],
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $post_fields,
    CURLOPT_HEADER => $headers,
curl_setopt_array($ch, $options);

$result = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    echo $result;
//check ok
if($status == 200){
    exit (0);

/* end */

Command-line parameter handling isn’t great as standard, so I cheat and turn them into GET parameters6. This handily means the program would work if used as a web script too with no further effort.

Oddly the API docs specify the parameters as JSON, but the version Ashley Rich created uses standard POST-style variables set using the CURL -d option and this works too. The Pushbullet API talks about maintaining backwards-compatibility to earlier versions, so I suspect there was a pre-JSON version at one time.

Most of the time was spent sorting out the Curl parameters needed 🙂



  1. TSOHost
  2. Using wp-cli and the “core verify-checksums” command.
  3. curl version 7.15.5 was released on August 7 2006
  4. It’s cheap hosting – that’s just how it is. Their PHP versions are fully up to date though and the support is good; which is what actually matters.
  5. There is a post about another problem I was trying to fix and how I worked round it coming soon.
  6. Alternatives either don’t work cross-platform, or require external libraries – not an option for such a simple program. Bash purists will wince at the non-standard format… yeah, whatever.