Tuesday, May 01, 2012

Send Email using SendGrid PHP library on Github


We are hosting the 3mik.com boxes on Rackspace right now and  we get 40,000 emails/month free of cost  from one of their partners, SendGrid. We use SendGrid to send  emails from our application written in PHP.  The SendGrid documentation suggests using SMTP relays and swiftmail-4.x library.  However, SendGrid also has a PHP front-end library published on github that makes it super easy to send emails.

Here is one complete test script


    require_once($_SERVER['WEBGLOO_LIB_ROOT']. '/ext/sendgrid-php/SendGrid_loader.php');
    set_error_handler('offline_error_handler');
    $sendgrid = new SendGrid('your-sendgrid-login', 'your-sendgrid-password');
    $mail = new SendGrid\Mail();


     $mail->addTo('foo@gmail.com')->
       setFrom('foo@3mik.com')->
       setSubject('Sendgrid github PHP library test')->
       setText('Hello World! from sendgrid library')->
       setHtml('Hello World! from sendgrid github lib');  

    $response = $sendgrid->web->send($mail);
    // Error Handling:- 
    // sendgrid->web method uses curl_exec CURLOPT_RETURNTRANSFER set. 
    // This means you will get FALSE
    // when the send method fails at network level.
    // you get JSON response back when curl is able to communicate with the server
    // success from API is returned as
    // {"message":"success"}
    // Error from API is returned as
    // {"message": "error", "errors": ["Bad username / password"]}
    print_r($response);



?>

Though all SendGrid documentation exhorts you to use SMTP, I do not see a problem in using the WEB method.  As per this SO question, http://stackoverflow.com/questions/6193702/sendgrid-smtp-or-curl , " The  web API actually works faster than SMTP, as you only need to make a single cURL request to us to send a message, whereas with SMTP there's a lot of back-and-forth TCP chatter for connection, HELO, and such." 


Error checks are crucial part of any code. Here is my complete sendgrid wrapper complete with error checks. I do not want to throw exceptions because I want clients to handle the error their own way.





namespace com\indigloo\mail {
use com\indigloo\Util as Util ;
use com\indigloo\Configuration as Config ;
use com\indigloo\Logger as Logger ;
/**
* class to wrap sendgrid-php web API.
* sendgrid-php web API uses curl to communicate to sendgrid endpoint.
*
* @see SendGrid/Web#send($mail)
* @see http://docs.sendgrid.com/documentation/api/web-api/mail/#send
*
*/
class SendGrid {
const BAD_INPUT_ERROR = 1 ;
const CURL_ERROR = 2 ;
const MALFORMED_RESPONSE = 3 ;
const SENDGRID_ERROR = 4 ;
const UNKNOWN_ERROR = 5 ;
/**
*
* @param $tos an array containing to addresses, is required.
* @param from : sender's email address, is required
* @param fromName : human friendly sender's name
* @param subject required
* @param text - text content of mail, is required
* @param html - html content of mail, is required
*
* @return return value of zero indicates success
* A non zero return value indicates failure.
*
*/
static function sendViaWeb($tos,$from,$fromName,$subject,$text,$html){
$login = Config::getInstance()->get_value("sendgrid.login");
$password = Config::getInstance()->get_value("sendgrid.password");
if(empty($login)
|| empty($password)
|| empty($tos)
|| empty($from)
|| empty($text)
|| empty($html)) {
//bad input
return self::BAD_INPUT_ERROR ;
}
// SendGrid PHP LIB path should be included before
// webgloo libraries for this to work
$sendgrid = new \SendGrid($login,$password);
$mail = new \SendGrid\Mail();
$fromName = empty($fromName) ? $from : $fromName ;
$mail->setTos($tos)->
setFrom($from)->
setFromName($fromName)->
setSubject($subject)->
setText($text)->
setHtml($html);
/*
* response handling.
* CURLOPT_RETURNTRANSFER option is set in SendGrid/Web#send()
* that method will return the result on success, FALSE on failure
*
* @see http://docs.sendgrid.com/documentation/api/web-api/#responseserror
* {"message":"error","errors":[]}
*
* @see http://docs.sendgrid.com/documentation/api/web-api/#responsessuccess
* {"message":"success"}
*
*/
$response = $sendgrid->web->send($mail);
if($response === FALSE) {
//problem with curl transport
$message = " Error communicating with sendgrid mail endpoint" ;
Logger::getInstance()->error($message);
return self::CURL_ERROR;
}
//parse response json
$responseObj = json_decode($response);
if(!is_object($responseObj) || !property_exists($responseObj,"message")) {
//bad json from sendgrid
$message = sprintf("Sendgrid mail api response :: [[%s]] is malformed",$response) ;
Logger::getInstance()->error($message);
return self::MALFORMED_RESPONSE ;
}
$message = $responseObj->message ;
if(strcasecmp($message,"error") == 0 ) {
//sendgrid returned error.
//get errors array
$message = " Sendgrid mail api returned error" ;
Logger::getInstance()->error($message);
foreach($responseObj->errors as $error) {
Logger::getInstance()->error($error);
}
return self::SENDGRID_ERROR ;
}
if(strcasecmp($message,"success") == 0 ) {
//success
return 0 ;
}
return self::UNKNOWN_ERROR ;
}
}
}


© 2025 Life of a third world developer
Maira Gall