A Laravel artisan based package to create the AWS (SES + SNS) infrastructure to receive email event notifications with Http/Https endpoint.

Overview

Laravel SES Tracking

Latest Stable Version Tests PHP Version Require Total Downloads StyleCI License

Setup the AWS infrastructure to handle email events using SES/SNS and http/s endpoints with a single Laravel artisan command. This package is unopinionated in the sense that every setting can be changed as per your requirements. It follows an interactive CLI based setup process so that you know exactly what will be configured. Also, includes a debug mode where you can see all the settings and configurations that will be used without actually making the API calls. Finally, it can be very painful to clean up the AWS resources when an API call fails. For example, if you are trying to enable some advanced filter policy for an endpoint, only for that setting to fail, then you might have to go back and remove the configuration sets and SNS topics manually. To tackle the issue, the package will automatically try and revert any changes made to the AWS infrastructure when any exceptions occur.

What this package does

As mentioned this package automates the process of:

  • Setting up the SES configuration set.
  • Setting up a SNS Topic.
  • Setting up the event destinations for the configuration set.
  • Subscribing the http/s endpoints to the SNS topic.

What this package doesn't do

The package will not do anything beyond what is mentioned above. So, the package won't:

  • Add the created configuration set to your SES driver.
  • Manage the https/s subscription confirmation or actual processing of event messages from SNS.
  • Create the domains or endpoints with a Laravel project running (but won't that be awesome 😃 ).

Basically, the package refrains from any action that will be implementation specific. After all, you are in a better position to decide what to do when an email bounce event occurs.

Laravel and PHP Versions

The package is written for Laravel 9 and Php 8.

Overview of SES/SNS Event Notification Process

To understand the process of setting up event notifications for emails on AWS we must know the 2 key objects that will need to be set up on these services:

  • Configuration Set (SES)
  • Topic (SNS)

To receive notifications for emails on our http/s endpoints we first need to set up a Configuration Set on SES. The Configuration Set is used with the ses driver on Laravel. This tells AWS that we wish to send email event notifications to some listener.

The 'some listener' in our case will be a SNS topic. This is specified by creating Event Destinations. An Event Destination serves 2 purposes:

  • It specifies which events to send notifications for.
  • It specifies where to send the event notifications.

Since we want to use SNS topics, we next need a SNS topic. The SNS topic receives event notifications from SES. When SNS receives a notification it will send a message to all the subscribers listening on the topic. In this case the subscriber will be a http/s endpoint.

So we need to create 4 objects:

  • Configuration Set
    • Event Destination (Part of a configuration set)
  • Topic
    • Subscription (Subscribes to a topic)

This a brief overview of what needs to be setup in order to enable http/s endpoints to receive email event notifications.

Installation

Via Composer

$ composer require akhan619/laravel-ses-tracking

This package uses Laravel's package auto-discovery so there is no need to add the service provider in config/app.php

Configuration File

You can publish the configuration file using the following artisan command:

$ php artisan vendor:publish --provider="Akhan619\LaravelSesTracking\LaravelSesTrackingServiceProvider" --tag="config"

This is will publish a new configuration file called laravel-ses-tracking.php in the config folder.

Usage

Debug Mode

The package is configured by default to run in debug mode. This means that when you run the setup command, the package will show you all the configuration options that will be used for the actuall API calls including routes/topics/subscriptions etc. Debug mode can be turned off by setting debug => FALSE in the config.

No API calls are made in debug mode. So you can test out the different configuration possibilities without making any changes to your AWS resources.

Setup

Run the following command and follow the interactive steps.

$ php artisan SesTracking:setup

You will have to confirm:

  • The Route names that will be used as endpoints.
  • The Topic names for SNS.
  • The Event Destination Names for SES.

Once you confirm all 3, the package will create and subscribe the endpoints to the SNS Topic.

The SubscriptionArns will be printed to the console on Success. They will show pending confirmation unless you enable ReturnSubscriptionArn in the configuration.

Example Run

An example to show the console steps and output on a succesful run of the setup command.

Confirming Subscription

You will need to set up the code on the actual endpoint service yourself to confirm subscription. Currently, you have 72 hours before the subscriptions expire to confirm the subscription. You may resend the confirmation message from the AWS console.

Configuration

AWS Credentials

AWS credentials are picked up from the .env file

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=

If you wish to use a different set of credentials then specify them in the configuration file under the ses key.

'ses' => [
    'key' => env('AWS_ACCESS_KEY_ID'),
    'secret' => env('AWS_SECRET_ACCESS_KEY'),
    'region' => env('AWS_DEFAULT_REGION'),
],

Note: The AWS credentials must have permissions that allow

  • Creation of SES Configuration Sets
  • Creation of SNS Topics
  • Creation of SES Event Destinations
  • Subscribing an http/s Endpoint to a SNS Topic

Since this is a topic in itself, please refer to the AWS docs to see what permissions need to be setup.

SNS Protocol

Currently, 2 SNS protocols are supported http/https. The default is https. You may change the protocol under the subscriber key by setting one of them to true:

'subscriber' => [
    'http' => FALSE, 
    'https' => TRUE,
],

Domain and Scheme

By default, the package picks up the domain and scheme to use for the endpoint from the APP_URL in the .env file. If you wish to use a different endpoint than the project url, specify the values under the corresponding keys in the config file:

'domain' => null, // If null the domain will be pulled from APP_URL. 
'scheme' => null, // If null the scheme will be pulled from APP_URL. 

Note: The scheme must match the subscriber SNS protocol, when using http/s subscribers.

Events

You may specify exactly which email events that you want to listen to by setting the event to true in the active key:

'active' => [
    'sends' => TRUE,
    'rendering_failures' => TRUE,
    'rejects' => FALSE,
    'deliveries' => FALSE,
    'bounces' => TRUE,
    'complaints' => FALSE,
    'delivery_delays' => FALSE,
    'subscriptions' => FALSE,
    'opens' => FALSE,
    'clicks' => FALSE,
],

Routes

Routes are customizable for each event by specifying values for the route_prefix and the routes key:

'route_prefix' => 'email/notification', // Set to null if no prefix is required.
'routes' => [
    'sends' => 'sends',
    'rendering_failures' => 'rendering-failures',
    'rejects' => 'rejects',
    'deliveries' => 'deliveries',
    'bounces' => 'bounces',
    'complaints' => 'complaints',
    'delivery_delays' => 'delivery-delays',
    'subscriptions' => 'subscriptions',
    'opens' => 'opens',
    'clicks' => 'clicks',
],

The actual endpoint is then generated seperately for each event as:

scheme://domain/route_prefix/route

Note: Routing endpoints are generated and subscribed only for the events that are enabled.

Route Confirmation

When you run the setup command, the package will output to the console the http/s endpoints that will be configured on AWS (when running in Live mode user will be requested to confirm the routes). This allows you to make sure the endpoints are exactly as you want.

The output looks like (based on a fresh laravel project with default values):

Event Route Name
sends https://localhost/email/notification/sends
deliveries https://localhost/email/notification/deliveries
bounces https://localhost/email/notification/bounces

Configuration Set

The package creates a Configuration Set in SES that you may use with the emails that you want event notifications for. All the options that are available on the AWS Console can be set through the configuration file:

'configuration_set' => [
    'ConfigurationSetName' => 'ses-event',

    'DeliveryOptions' => [
        'SendingPoolName' => null,

        'TlsPolicy' => 'REQUIRE',
    ],

    'ReputationOptions' => [
        'LastFreshStart' => null,

        'ReputationMetricsEnabled' => FALSE,
    ],

    'SendingOptions' => [
        'SendingEnabled' => TRUE,
    ],

    'SuppressionOptions' => [
        'SuppressedReasons' => [],
    ],

    'Tags' => [],

    'TrackingOptions' => [
        'CustomRedirectDomain' => null,
    ],
],

Note: Some of the options here when enabled are charged seperately by AWS. You should check the defaults set here for your use case. Please refer to the AWS docs for how to set these options and what impact they have.

SNS Topics

Similar to route names, the topic name that is generated for every event can be modified by changing the topic_name_prefix , topic_name_suffix and the topic_name keys in the config as below:

'topic_name_prefix' => env('APP_NAME', 'local'), // Set to null if no prefix is required.
'topic_names' => [
    'sends' => 'sends',
    'rendering_failures' => 'rendering-failures',
    'rejects' => 'rejects',
    'deliveries' => 'deliveries',
    'bounces' => 'bounces',
    'complaints' => 'complaints',
    'delivery_delays' => 'delivery-delays',
    'subscriptions' => 'subscriptions',
    'opens' => 'opens',
    'clicks' => 'clicks',
],
'topic_name_suffix' => 'us-east-1', // Set to null if no prefix is required.

SNS Topic Configuration

When creating a SNS topic, there are other options that can be set besides the name. For example you may want to enable at-rest encryption for the payload or define a delivery retries policies. These can be specificied under the key sns_topic_configuration_data in the config file. Please refer to the AWS docs to see how to set them properly.

'DeliveryPolicy' => [],

'Policy' => [],

'KmsMasterKeyId' => null,

'Tags' => [],

SNS Topic Names Confirmation

When you run the setup command, the package will output to the console the SNS topics that will be configured on AWS (when running in Live mode user will be requested to confirm the topic names). This allows you to make sure the topic names are exactly as you want.

The output looks like (based on a fresh laravel project with default values):

Event Topic Name
sends Laravel-sends-us-east-1
deliveries Laravel-deliveries-us-east-1
bounces Laravel-bounces-us-east-1

Event Destination Names

Just like before, event destination names can be customized on a per event basis by changing the self-explantory config options below:

'event_destination_prefix' => 'destination',
'destination_names' => [
    'sends' => 'sns',
    'rendering_failures' => 'sns',
    'rejects' => 'sns',
    'deliveries' => 'sns',
    'bounces' => 'sns',
    'complaints' => 'sns',
    'delivery_delays' => 'sns',
    'subscriptions' => 'sns',
    'opens' => 'sns',
    'clicks' => 'sns',
],
'event_destination_suffix' => 'us-east-1',

If instead, you want to attach the Topic names as a suffix for the event destinations, to help with tracking, then set the following option to TRUE.

'topic_name_as_suffix' => TRUE,

Setting this to TRUE disables the event_destination_suffix.

Event Destination Names Confirmation

When you run the setup command, the package will output to the console the SES Event Destination names that will be configured on AWS (when running in Live mode user will be requested to confirm the destination names). This allows you to make sure the destination names are exactly as you want.

The output looks like (based on a fresh laravel project with default values):

Event Event Destination Name
sends destination-sns-Laravel-sends-us-east-1
deliveries destination-sns-Laravel-deliveries-us-east-1
bounces destination-sns-Laravel-bounces-us-east-1

Subscription Configuration

You may specify additional options when subscribing an endpoint to a SNS Topic under the sns_subscription_configuration_data key in the config file. Currently you can set the following options:

'ReturnSubscriptionArn' => false,
'DeliveryPolicy' => [],
'FilterPolicy ' => [],
'RawMessageDelivery' => 'false',
'RedrivePolicy' => null,

Please refer to AWS docs for further details on how to use these settings.

Rollback on Failure

Making API calls always entail failure possibility. So every configuration setting is extensively validated before making the calls. Still, API calls can fail. Maybe, the topic name already exists. Since this is a multi-step process, you maybe left with wasted resources that you would have to go and clear yourself. So the package tries to roll back to a clean state. This means it will delete the Configurations Set and/or the Topic that was created on a failure of the succeding steps. This should be enough for most cases. But, it might be that the call to delete these resources themselves fail. In that case, a manual clean-up is required sadly.

If you are in this boat then as a consoloation, this developer had to manually clean up many times while this package was being developed.

Change log

Please see the changelog for more information on what has changed recently.

Testing

Run the tests with

$ composer test

RoadMap

  • Add tests!!!
  • Add a option to the command to answer yes to all confirmations.
  • Add a seperate command to delete the AWS resources that were created. A way for users to test and clear AWS resources.
  • Add other protocols such as SQS.

Contributing

Please see contributing.md for details and a todolist.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Credits

  • Aman Khan

License

MIT. Please see the license file for more information.

You might also like...
A Laravel 9 package that allows you enforce security of your artisan commands by authenticating users before running.

Introduction This package allows you as a developer to restrict who can and cannot run artisan commands, especially in a production environment. For e

λ Run PHP Coroutines & Fibers as-a-Service on the AWS Lambda.
λ Run PHP Coroutines & Fibers as-a-Service on the AWS Lambda.

λ Swoole Runtime for AWS Lambda Run PHP Coroutines & Fibers as-a-Service on the AWS Lambda. Getting started Create your Lambda function index.php ?ph

CDK patterns for serverless container with AWS Fargate

cdk-fargate-patterns CDK patterns for serverless container with AWS Fargate DualAlbFargateService Inspired by Vijay Menon from the AWS blog post intro

WHMCS Automation Module For AWS EC2 Instances.
WHMCS Automation Module For AWS EC2 Instances.

使用方法 把AWSEC2目录直接扔到 WHMCS/modules/servers 下即可 自定义字段 cloudinit (文本框 textarea 在订单页面显示) pem (文本框 textarea 仅管理员可见) data (文本框 textarea 仅管理员可见) 特性 动态IP (关机再开

Lumen on Docker - Skeleton project with Nginx, MySQL & PHP 8 | Aws ECS, Google Kubernates, Azure Container Engine

Docker infrastructure for Lumen Description Microservice Lumen is a starting skeleton based on Docker and Lumen Framework. This project helps to devel

Private Composer registry for private PHP packages on AWS Serverless
Private Composer registry for private PHP packages on AWS Serverless

Tug Tug is a Composer private registry for private PHP packages installable with Composer (1 and 2). The main idea of this project is to have an inter

AWS DynamoDB session handler for Magento (experimental!)

Magento Session Handler for AWS DynamoDB Author: Fabrizio Branca TODO: disable automatic gc create cron that does gc how does it keep track of lifetim

This demo app shows you how to run a simple PHP application on AWS Elastic Beanstalk.

Elastic Beanstalk + PHP Demo App - "Share Your Thoughts" This demo app shows you how to run a simple PHP application on AWS Elastic Beanstalk. Run the

PHP Runtime Layer for AWS Lambda

PHP Layer For AWS Lambda Ever wanted to run PHP websites in AWS Lambda? It's your lucky day! This Lambda Runtime Layer runs the PHP 7.3/7.1 webserver

Releases(v1.0.7)
Owner
null
Dispatcher is a Laravel artisan command scheduling tool used to schedule artisan commands within your project so you don't need to touch your crontab when deploying.

Dispatcher Dispatcher allows you to schedule your artisan commands within your Laravel project, eliminating the need to touch the crontab when deployi

Indatus 1.1k Dec 21, 2022
A fully-managed real-time messaging service that allows you to send and receive messages between independent applications.

A fully-managed real-time messaging service that allows you to send and receive messages between independent applications.

Google APIs 58 Dec 23, 2022
A tool to create php lambda's in AWS via custom runtime api

Getting Started This composer library assists in the creation, configuration, and testing of an AWS Lambda function. It utilizes the AWS Lambda custom

Mike McGrath 0 Jul 13, 2022
A DDD microservice did in laravel, to test infrastructure

A DDD microservice did in laravel, to test infrastructure

pegons 3 Jul 8, 2022
Magento 2 Email Catcher or Email Logger Module. Available At Packagist.

Magento 2 Module Experius email catcher / - logger ``experius/module-emailcatcher`` Main Functionalities Installation Versions Enable email catcher C

Experius 53 Dec 18, 2022
Nuber is an open source container management platform it provides a front end to manage your own cloud infrastructure, using Linux Containers virtualization technology

Nuber is an open source container management platform it provides a front end to manage your own cloud infrastructure, using Linux Containers virtualization technology

null 33 Dec 14, 2022
This script allows to bypass Oracle Cloud Infrastructure 'Out of host capacity' error immediately when additional OCI capacity will appear in your Home Region / Availability domain.

Resolving Oracle Cloud "Out of Capacity" issue and getting free VPS with 4 ARM cores / 24GB of memory Very neat and useful configuration was recently

Alexander Hitrov 323 Jan 6, 2023
Pika is a nosql compatible with redis, it is developed by Qihoo's DBA and infrastructure team

Introduction中文 Pika is a persistent huge storage service , compatible with the vast majority of redis interfaces (details), including string, hash, li

OpenAtomFoundation 4.9k Jan 6, 2023
Orkestra is a library of infrastructure and architecture helpers for creating CQRS applications

Orkestra Orkestra is an opinionated framework with a plethora of recommendations on architectural design that we use internally at Morebec to develop

Morébec 2 Aug 18, 2021
This component, based on the Symfony serializer and async-aws, is a human-readable and quick abstraction to easily store serialized objects in DynamoDB 🚀.

DynamoDB Storable This component, based on the Symfony serializer and async-aws, is a human-readable and quick abstraction to easily store serialized

Matthieu W. 2 Jun 19, 2022