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.
#!/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);
}
}



