Handling AWS Simple Email Service notifications
Tags: sns, aws, complaints, bounces
Published: 2019-03-22 15:54:54

---
title: Handling AWS Simple Email Service notifications
published: true
tags: SNS,aws,complaints,bounces
canonical_url: https://deeb.me/20180627/handling-aws-simple-email-service-notifications
---

Apparently it’s not enough to [gather information on your email sending, bounces and complaints](http://deeb.me/20180321/amazon-ses-dashboard). You also need to act when there’s a problem otherwise Amazon will put your account under probation and might even shut it completely if you don’t fix the problem.

And it’s pretty easy to implement per their sample code and the [explanation in the aws blog](https://aws.amazon.com/blogs/messaging-and-targeting/handling-bounces-and-complaints/)

Here are the steps I use to set it up:

- Create an SNS topic. Let’s call it SES-BOUNCES. Or create 2 SNS topics (1 for bounces, another for complaints). I will go with just one.
- Create a service on your site to handle the bounces. I used some simple PHP code (pasted below) for that.
- Create a subscription in your SNS topic (created first)

The service should handle 2 things:

- the subscription (that will happen once!): call the SubscribeURL and you’re done.
- the bounces/complaints: Remove the email addresses form your mailing list, or blacklist them, or … The main idea is to stop sending emails to those who complain. And stop trying to send emails to addresses that bounce.

Here’s the code for the PHP service, it’s pretty straight forward

```
if ( 'POST' !== $\_SERVER['REQUEST\_METHOD'] ) { http\_response\_code( 405 ); die; } require 'vendor/autoload.php'; use Aws\Sns\Message; use Aws\Sns\MessageValidator; function parse\_bounce( $message ) { $recipients = array(); foreach ( $message['bounce']['bouncedRecipients'] as $recipient ) { $recipients[] = $recipient['emailAddress']; } switch ( $message['bounce']['bounceType'] ) { case 'Transient': error\_log( "BouncesController - Soft bounces occurred for " . join( ', ', $recipients ) ); return array(); break; case 'Permanent': error\_log( "BouncesController - Hard bounces occurred for " . join( ', ', $recipients ) ); return $recipients; break; } } function parse\_complaint( $message ) { $recipients = array(); foreach ( $message['complaint']['complainedRecipients'] as $recipient ) { $recipients[] = $recipient['emailAddress']; } return $recipients; } function blacklist\_recipients( $recipients ) { foreach ( $recipients as $email\_address ) { // blacklist those emails } } try { $sns\_message = Message::fromRawPostData(); $validator = new MessageValidator(); $validator-\>validate( $sns\_message ); if ( $validator-\>isValid( $sns\_message ) ) { if ( in\_array( $sns\_message['Type'], ['SubscriptionConfirmation', 'UnsubscribeConfirmation'] ) ) { file\_get\_contents( $sns\_message['SubscribeURL'] ); error\_log( 'Subscribed to ' . $sns\_message['SubscribeURL'] ); } if ( $sns\_message['Type'] == 'Notification' ) { $message = $sns\_message['Message']; $notification\_type = $message['notificationType']; if ( $notification\_type == 'Bounce' ) { blacklist\_recipients( parse\_bounce( $message ) ); } if ( $notification\_type == 'Complaint' ) { blacklist\_recipients( parse\_complaint( $message ) ); } } } } catch ( Exception $e ) { error\_log( 'Error: ' . $e-\>getMessage() ); http\_response\_code( 404 ); die; }
```

Don’t forget to run composer to get those dependencies:

```
{ "require": { "aws/aws-sdk-php": "3.\*", "aws/aws-php-sns-message-validator": "1.4.0" } }
```

And make sure you don’t send unsolicited emails! it’s just not nice.