AWS Developer Tools Blog
Receiving Amazon SNS Messages in PHP
A little over a year ago, we announced a new feature in the AWS SDK for PHP that allowed customers to validate inbound SNS messages. In the latest version of the SDK, this functionality is now available in its own package, one that does not depend on the SDK, so it’s simpler to listen to SNS topics with lightweight web services. In this blog post, I’ll show you how to use the Amazon SNS message validator for PHP to parse messages in a single-file web application.
About SNS
Amazon Simple Notification Service (Amazon SNS) is a fast and fully managed push messaging service that can deliver messages over email, SMS, mobile push, and HTTP/HTTPS endpoints.
With Amazon SNS, you can set up topics to publish custom messages to subscribed endpoints. SNS messages are used by many of the other AWS services to communicate information asynchronously about your AWS resources. Some examples include:
- Configuring Amazon Glacier to notify you when a retrieval job is complete.
- Configuring AWS CloudTrail to notify you when a new log file has been written.
- Configuring Amazon Elastic Transcoder to notify you when a transcoding job changes status (e.g., from “Progressing” to “Complete”)
Receiving SNS Messages and Verifying Their Signature
Using the SNS Message Validator’s Message
class, you can easily parse raw POST data from SNS:
<?php require 'path/to/vendor/autoload.php'; $message = AwsSnsMessage::fromRawPostData(); echo $message->get('Message');
Amazon SNS sends different types of messages, including SubscriptionConfirmation
, Notification
, and UnsubscribeConfirmation
. The formats of these messages are described in the Appendix: Message and JSON Formats section of the Amazon SNS Developer Guide.
Messages from Amazon SNS are signed. As a best practice, you should use the MessageValidator
class to verify the signature and ensure a message was sent from Amazon SNS.
<?php use AwsSnsMessage; use AwsSnsMessageValidator; $message = Message::fromRawPostData(); // Validate the message $validator = new MessageValidator(); $validator->validate($message);
Instances of AwsSnsMessageValidator
have two methods for validating messages, both of which take an instance of AwsSnsMessage
as their only argument. validate
(shown above) will throw an AwsSnsExceptionInvalidSnsMessageException
. isValid
will return a Boolean — true
for valid messages and false
for invalid ones.
Confirming a Subscription to a Topic
In order for an HTTP(S) endpoint to receive messages, it must first be subscribed to an SNS topic. Subscriptions are confirmed over HTTP(S), so you’ll need to create and deploy an endpoint before you set up a subscription. SubscriptionConfirmation
messages provide a URL you can use to confirm the subscription.
$message = AwsSnsMessage::fromRawPostData(); // Validate the message $validator = new MessageValidator(); if ($validator->isValid($message)) { file_get_contents($message->get('SubscribeURL')); }
Handling Notifications
Let’s put it all together and add some extra code for handling both notifications and subscription control messages.
<?php if ('POST' !== $_SERVER['REQUEST_METHOD']) { http_response_code(405); die; } require 'path/to/vendor/autoload.php'; try { $message = AwsSnsMessage::fromRawPostData(); $validator = new AwsSnsMessageValidator(); $validator->validate($message); if (in_array($message['Type'], ['SubscriptionConfirmation', 'UnsubscribeConfirmation']) { file_get_contents($message['SubscribeURL']); } $log = new SplFileObject('../messages.log', 'a'); $log->fwrite($message['Message'] . "n"); } catch (Exception $e) { http_response_code(404); die; }
Conclusion
As you can see, receiving, verifying, and handling Amazon SNS messages is simple. Setting up your application to receive SNS messages will allow you to create applications that can handle asynchronous communication from AWS services and other parts of your application.