PHP Program that Delivers SendGrid Account Stats to a Phone Call

Recently I created a SendGrid account to learn more about their email delivery service. They have an extensive API, and I decided to write a program on my Linux box that retrieves several of my daily SendGrid email statistics (email request count, email delivered count, and invalid email address count) and sends them to my phone as a text-to-speech message.

From the command line, this is the syntax to run it:
$ /SendGrid/sgstats2phone.php 3034029500 nsimon@solidcode.com MySecretApiKey

It calls my phone and delivers a text-to-speech message similar to this:
"send grid stats for nsimon at solidcode dot com May 10th 2011.
 requests 44, delivered 43, invalid 1. Thank you, good bye."

I scheduled a cron job to deliver the stats at 8:00pm every evening:
00 20 * * * /SendGrid/sgstats2phone.php 3034029500 nsimon@solidcode.com MySecretApiKey

App note: requires cURL, the Client URL Request Library. On my Ubuntu system, I installed cURL with this command:
$ sudo apt-get install php5-curl

If you’re a SendGrid developer, I hope you find this helpful.

Download the code
 

#!/usr/bin/php
<?php

/******************************************************************************/
/* Module ..... sgstats2phone.php                                             */
/* Author ..... Neil Simon                                                    */
/* Modified ... 06/07/2011                                                    */
/* Desc ....... Delivers SendGrid account stats to a phone call               */
/* Usage ...... sgstats2phone.php {phone} {username} {api_key}                */
/******************************************************************************/

/******************************************************************************/
/* Include classes                                                            */
/******************************************************************************/

require_once ("CommandLine.php");
require_once ("SendGrid.php");
require_once ("SendGridCurl.php");

/******************************************************************************/
/* main                                                                       */
/******************************************************************************/

main ($argc, $argv);

function main ($argc, $argv)
    {
    // Reset to 0 upon success
    $rc = 1;

    // 3 args (+progname) required
    if ($argc != 4)
        {
        usage ();
        printf ("ERROR: 3 args required.\n");
        }

    else
        {
        // Store args
        $commandLine = new CommandLine_sgstats2phone ($argc, $argv);

        // Extract args
        $commandLine->extractArgs ();

        // Validate args
        if (($argStatus = $commandLine->validateArgs ()) != 0)
            {
            usage ();
            $commandLine->printArgErrorMessage ($argStatus);
            }

        else
            {
            // Store the args in the sendGrid object
            $sendGrid = new SendGrid ($commandLine->argPhone,    // 3034029500
                                      $commandLine->argUser,     // nsimon@solidcode.com
                                      $commandLine->argApiKey);  // MySecretApiKey

            // Get the SendGrid stats for the current day (via REST/XML)
            if ($sendGrid->statsGet () != 0)
                {
                printf ("ERROR: sendGrid->statsGet()\n");
                }
            else
                {
                // Assemble the text-to-speech text, setup params to pass to curl
                $sendGrid->assembleStats ();

                // Send stats to phone
                if (SendGridCurl::issueRequest ($sendGrid->get_statsParams()) == 0)
                    {
                    // Successful
                    $rc = 0;
                    }
                }
            }
        }

    exit ($rc);
    }

function usage ()
    {
    printf ("Usage: sgstats2phone.php {phone} {username} {api_key}\n");
    printf ("Ex:    sgstats2phone.php 3034029500 nsimon@solidcode.com MySecretApiKey\n");
    }

 

<?php

/******************************************************************************/
/* Module ..... CommandLine.php                                               */
/* Author ..... Neil Simon                                                    */
/* Modified ... 06/07/2011                                                    */
/******************************************************************************/

class CommandLine
    {
    protected $_argc = 0;  // Set in constructor
    protected $_argv = 0;  // Set in constructor

    public function __construct ($argc, $argv)
        {
        // Store count
        $this->_argc = $argc;

        // Store values array
        $this->_argv = $argv;
        }
    }

class CommandLine_sgstats2phone extends CommandLine
    {
    // Error constants
    const ERROR_ARG_PHONE_NOT_10      = 1;
    const ERROR_ARG_PHONE_NOT_NUMERIC = 2;

    // Extracted from command line positional values
    public $argPhone  = "";
    public $argUser   = "";
    public $argApiKey = "";

    public function __construct ($argc, $argv)
        {
        // Store argc, argv
        parent::__construct ($argc, $argv);
        }

    public function extractArgs ($display = true)
        {
        // Extract values
        $this->argPhone  = $this->_argv [1];
        $this->argUser   = $this->_argv [2];
        $this->argApiKey = $this->_argv [3];

        if ($display)
            {
            // Display the args
            printf ("argPhone ......... %s\n", $this->argPhone);
            printf ("argUser .......... %s\n", $this->argUser);
            printf ("argApiKey ........ %s\n", $this->argApiKey);
            printf ("\n");
            }
        }

    public function validateArgs ()
        {
        $rc = 1;

        // Phone must be length 10
        if (strlen ($this->argPhone) != 10)
            {
            $rc = self::ERROR_ARG_PHONE_NOT_10;
            }

        // Phone must be numeric
        elseif (!is_numeric ($this->argPhone))
            {
            $rc = self::ERROR_ARG_PHONE_NOT_NUMERIC;
            }

        else
            {
            // Success
            $rc = 0;
            }

        return ($rc);
        }

    public function printArgErrorMessage ($argErrorNum)
        {
        // Display error message
        switch ($argErrorNum)
            {
            case self::ERROR_ARG_PHONE_NOT_10:
                {
                printf ("ERROR: phone must be 10 characters.\n");
                break;
                }
            case self::ERROR_ARG_PHONE_NOT_NUMERIC:
                {
                printf ("ERROR: phone must be numeric.\n");
                break;
                }
            default:
                {
                printf ("ERROR: unknown error.\n");
                break;
                }
            }
        }
    }

 

<?php

/******************************************************************************/
/* Module ..... SendGrid.php                                                  */
/* Author ..... Neil Simon                                                    */
/* Modified ... 06/07/2011                                                    */
/******************************************************************************/

class SendGrid
    {
    private $_argPhone  = "";  // Set in constructor
    private $_argUser   = "";  // Set in constructor
    private $_argApiKey = "";  // Set in constructor

    private $_statsGetXml;     // Returned from stats.get.xml
    private $_statsParams;     // Filled by assembleStats ()

    public function __construct ($argPhone, $argUser, $argApiKey)
        {
        // Store values
        $this->_argPhone  = $argPhone;
        $this->_argUser   = $argUser;
        $this->_argApiKey = $argApiKey;
        }

    public function get_statsParams ()
        {
        // This is passed to curl
        return ($this->_statsParams);
        }

    public function statsGet ()
        {
        // Reset to 0 upon success
        $rc = 1;

        // Define constant for stats get
        define ("SENDGRID_XML_STATS_GET", "https://sendgrid.com/api/stats.get.xml?" .
                "api_user=$this->_argUser&api_key=$this->_argApiKey");

        // Call the SendGrid API -- suppress any errors
        if (($statsGet = @file_get_contents (SENDGRID_XML_STATS_GET)) != FALSE)
            {
            // Create addressable XML array object to pass out
            $this->_statsGetXml = new SimpleXMLElement ($statsGet);

            // Success
            $rc = 0;
            }

        return ($rc);
        }

    public function assembleStats ($display = true)
        {
        // Split-out the date
        $month = date ("F",  strtotime ($this->_statsGetXml->day->date));  // May
        $day   = date ("jS", strtotime ($this->_statsGetXml->day->date));  // 10th
        $year  = date ("Y",  strtotime ($this->_statsGetXml->day->date));  // 2011

        // Extract the stats
        $requests      = $this->_statsGetXml->day->requests;
        $delivered     = $this->_statsGetXml->day->delivered;
        $invalid_email = $this->_statsGetXml->day->invalid_email;

        if ($display)
            {
            printf ("month ............ %s\n", $month);
            printf ("day .............. %s\n", $day);
            printf ("year ............. %s\n", $year);
            printf ("\n");

            printf ("requests ......... %s\n", $requests);
            printf ("delivered ........ %s\n", $delivered);
            printf ("invalid_email .... %s\n", $invalid_email);
            printf ("\n");
            }

        // Split-out the user email into 3 pieces (split on @ and .)
        $emailPieces = preg_split ("/[@\.]/", $this->_argUser);  // nsimon solidcode com

        // Build the text-to-speech string, part 1
        $textToSpeech1 = sprintf ("send grid stats for . " .
                                   "%s . at %s dot %s . %s %s . %s . ",
                                   $emailPieces [0],
                                   $emailPieces [1],
                                   $emailPieces [2],
                                   $month,
                                   $day,
                                   $year);

        // Build the text-to-speech string, part 2
        $textToSpeech2 = sprintf ("requests . %s . delivered . %s . in valid . %s . ",
                                   $requests,
                                   $delivered,
                                   $invalid_email);

        // Build the text-to-speech string, part 3
        $textToSpeech3 = "thank you . good bye";

        if ($display)
            {
            printf ("textToSpeech1 .... %s\n", $textToSpeech1);
            printf ("textToSpeech2 .... %s\n", $textToSpeech2);
            printf ("textToSpeech3 .... %s\n", $textToSpeech3);
            printf ("\n");
            }

        // Assemble the 3 text-to-speech pieces into the fullText
        $fullText = $textToSpeech1 . $textToSpeech2 . $textToSpeech3;

        // Setup params array for curl POSTFIELDS
        $this->_statsParams = array ("api_user"  => $this->_argUser,
                                     "api_key"   => $this->_argApiKey,
                                     "x-smtpapi" => "",
                                     "to"        => $this->_argPhone . "@phone",
                                     "subject"   => "",
                                     "html"      => "",
                                     "text"      => $fullText,
                                     "from"      => "");
        }
    }

 

<?php

/******************************************************************************/
/* Module ..... SendGridCurl.php                                              */
/* Author ..... Neil Simon                                                    */
/* Modified ... 06/07/2011                                                    */
/******************************************************************************/

class SendGridCurl
    {
    public function issueRequest ($params, $display = true)
        {
        // Reset to 0 upon success
        $rc = 1;

        // Define constant for SendGrid JSON URL
        define ("SENDGRID_JSON_REQUEST_URL", "http://sendgrid.com/api/mail.send.json");

        // Generate curl request
        if (($hCurl = curl_init (SENDGRID_JSON_REQUEST_URL)) == FALSE)
            {
            if ($display)
                {
                printf ("STATUS ........... ERROR: curl_init() failed\n");
                }
            }

        else
            {
            // Set the curl options
            curl_setopt ($hCurl, CURLOPT_POST,           true);    // POST
            curl_setopt ($hCurl, CURLOPT_HEADER,         false);   // Dont return headers
            curl_setopt ($hCurl, CURLOPT_RETURNTRANSFER, true);    // Return the response
            curl_setopt ($hCurl, CURLOPT_POSTFIELDS,     $params); // Add the POST body

            // Exec curl
            if (($response = curl_exec ($hCurl)) == FALSE)
                {
                if ($display)
                    {
                    printf ("STATUS ........... ERROR: curl_exec() failed\n");
                    }
                }

            else
                {
                if ($display)
                    {
                    printf ("STATUS ........... Message sent successfully\n");
                    }

                // Success
                $rc = 0;
                }

            // Close the curl handle
            curl_close ($hCurl);
            }

        return ($rc);
        }
    }