Tuesday, 5 November 2013

GMail email relay from PHP in Azure worker role

I have a worker role that needs to connect to a web application regularly to force it to keep it's database connection established (poor I know!) but in this case, the connection can take 10 seconds to connect and if you are the unlucky person who hits it at that point, you have to wait.

Anyway, I wanted to test how the Azure PHP worker role worked and check that it did what I thought it would do so I decided I would get it to send me an email in the worker loop to ensure it was all happy and running properly.

When you add an Azure worker role, it creates a whole load of weird files that run certain commands, set up paths etc but the only one you need to care about is index.php which is invoked by default when the worker role starts. The way it works, therefore, like .net worker roles is that you should have some PHP that sits inside a while(true) loop (assuming you want it to loop) and which then calls whatever PHP code you need it to.

In my case, I was using swiftMailer to relay email via our Google accounts and swiftMailer uses PHP's open ssl extension (which was already enabled by default).

Anyway, this was all fine but the emails weren't coming through, although the role was running. This was because I put the bit I expected to fail inside a try/catch to ensure that any errors would not make the deployment break!

I ended up enabling remote desktop for the role (see previous post!) and went straight into d:\windows\temp\php53_errors.log and saw the following error:

PHP Warning:  fsockopen(): SSL operation failed with code 1. OpenSSL Error messages:
error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol in E:\approot\swiftMailer\classes\Swift\Transport\StreamBuffer.php on line 233
PHP Warning:  fsockopen(): Failed to enable crypto in E:\approot\swiftMailer\classes\Swift\Transport\StreamBuffer.php on line 233
PHP Warning:  fsockopen(): unable to connect to ssl://smtp.gmail.com:587 (Unknown error) in E:\approot\swiftMailer\classes\Swift\Transport\StreamBuffer.php on line 233

Fortunately, I found a useful blog post with a similar issue on another framework and it is related to how Google works and a few shortcomings in the swiftMailer's SSL functionality. Long story short, you need to use the following config: $transport = Swift_SmtpTransport::newInstance('smtp.gmail.com', 465, 'ssl'); Note the use of port 465 (not 587) and protocol ssl.

So a complete example for a simple PHP mailer using swiftmailer is as below:

$transport = Swift_SmtpTransport::newInstance('smtp.gmail.com', 465, 'ssl');
$mailer = Swift_Mailer::newInstance($transport);
// Create the message
$message = Swift_Message::newInstance();
$message->setSubject('This is the subject');
$message->setFrom(array('no-reply@server.com' => 'No reply'));
$message->setTo(array('someone@somewhere.com' => 'john'));
$message->setBody("This is the actual content");

Post a Comment