Sunday, February 3, 2013

Send mail with Gmail SMTP and Xoauth (Xoauth.php)

Since I couldn't find a complete solution anywhere else, I thought I'd make a post about how to send mail using Gmail SMTP, Zend Mail and Xoauth2.

First, you need to put a file called Xoauth.php in Zend/Mail/Protocol/Smtp/Auth. The contents of the file are as follows:

require_once 'Zend/Mail/Protocol/Smtp.php';
class Zend_Mail_Protocol_Smtp_Auth_Xoauth extends Zend_Mail_Protocol_Smtp
{
 protected $_xoauth_request;
    public function __construct($host = '127.0.0.1', $port = null, $config = null)
    {
  if (isset($config['xoauth_request'])) {
   $this->_xoauth_request = $config['xoauth_request'];
  }
     parent::__construct($host, $port, $config);
 }
    public function auth()
    {
        parent::auth();
  $this->_send('AUTH XOAUTH2 ' . $this->_xoauth_request);
  $this->_expect(235);
  $this->_auth = true;
    }
}

If you're curious about how this file gets called, look in Transport/Smtp.php for the _sendMail function. The variable connectionClass is what defines the file location.

Now to actually send the email you need the following code:
require_once 'Zend/Mail/Transport/Smtp.php';
require_once 'Zend/Mail.php';

function constructAuthString($email,$accessToken) {
  return base64_encode("user=$email\1auth=Bearer $accessToken\1\1");
}

function sendEmail($email,$accessToken){
 $smtpInitClientRequestEncoded = constructAuthString($email, $accessToken);
 $config = array('ssl' => 'ssl',
                  'port' => '465',
                  'auth' => 'xoauth',
                  'xoauth_request' => $smtpInitClientRequestEncoded);
     
 $transport = new Zend_Mail_Transport_Smtp('smtp.gmail.com', $config); 
 $mail = new Zend_Mail();
 $mail->setBodyText('some body text');
 $mail->setFrom($email, 'Some Sender');
 $mail->addTo("email of recipient", 'Some Recipient');
 $mail->setSubject('Test sending by smtp');
 $mail->send($transport);
}

Call sendEmail() with the arguments email and accessToken and you'll be sending an email with Gmail SMTP and XOauth!

Note: I'll put this stuff on Github in a bit.

9 comments:

  1. Hi!

    Thanks for this. It's been very helpful.

    I am successfully authenticating with my Google Account and getting an access_token, but then everytime I try to send an email I am getting this error:

    334 eyJzdGF0dXMiOiI0MDAiLCJzY2hlbWVzIjoiQmVhcmVyIiwic2NvcGUiOiJodHRwczovL21haWwuZ29vZ2xlLmNvbS8ifQ==

    Do you know the reason by any chance?

    Thanks!

    ReplyDelete
  2. That's a weird one. Can you do an ini_set("display_errors",1) at the top of your php page that sends the email and show me what that says?

    ReplyDelete
  3. tried many times still getting same error:

    eyJzdGF0dXMiOiI0MDAiLCJzY2hlbWVzIjoiQmVhcmVyIiwic2NvcGUiOiJodHRwczovL21haWwuZ29vZ2xlLmNvbS8ifQ==


    please help???

    ReplyDelete
  4. Really, amazing piece of code by piecewise.

    Thanks

    ReplyDelete
  5. Hey, you are a life saver!
    Wasted 2 days of trying to work it out, than did the smart thing of googling it, came across this post, and in 15 minutes it was up and running.
    How the heck did you figure the Xoauth.php requirement and it's content?
    Kudos! Yaniv

    ReplyDelete
    Replies
    1. Banging my head against the Google/Zend/Stackoverflow docs for at least 12 hours straight :P Then talking to my uber genius programmer friend for about an hour. Then after a long nights sleep, everything just kind of came together. Glad this was of use!

      Delete
  6. Can you please share the full source? I have been stuck with this. I get rend fw errors :/

    ReplyDelete
  7. How can i get the access token ? can you share your full code starting with getting the access token .

    ReplyDelete
  8. You did not write the complete solution as well like other people. Where can we get the Smtp.php?
    What is wrong with you guys?

    ReplyDelete