Start using MailHooks in your Symfony app

Thomas P
3 min readOct 3, 2017

Most of us, Symfony devs, are using Email delivery service like Mailjet 🇫🇷 (Sparkpost or , MailGun etc…).

Those email services are time-saver for our teams, providing scalability to our apps and benefits of their delivery expertise.

Let’s focus on two metrics:

Cost:
Naturally, thoses services have a cost. Pricing are mostly based on emails sent per month or contacts in marketing campaigns.

Engagement:
Bounce rate, spam complaint, policy rejection or open rate, thoses data have impacts on your IP reputation and emails volumes.

Let’s optimize these metrics by using the power of Mailhooks and MailHookBundle!

First, define our scenarios that will help us to have a better deliverability and growth hacking:

The user spam complains about one of our email?
Remove it from your mailing list to avoid regular complain.

The user mail account’s quota has been exceeded and your mail is bounced?
Change the notification channel from mail to mobile push or invite the contact to update his mail address with a private message.

A customer mail address is no longer available?
Let’s warning the account manager related to this contact.

When we have define some scenarios, we wan’t to catch the events from our users email 🚀.

Now let’s configure SwmMailHookBundle to catch those MailHooks:

Add the package to your composer.json file

composer require scullwm/mailhookbundle

Add this to app/AppKernel.php

<?php
public function registerBundles()
{
$bundles = array(
...
new Swm\Bundle\MailHookBundle\SwmMailHookBundle(),
);
... return $bundles;
}

Now let’s configure it:

1) Edit app/config.yml

swm_mail_hook:
secretsalt: notSecret

This secret salt is simply used to obfuscate the mailhook endpoint like:
http://www.mywebsite.com/webhook/{secretSalt}/{serviceName}/catch

2) Edit app/routing.yml

swm_mailhook_controller:
resource: "@SwmMailHookBundle/Controller/"
type: annotation
prefix: /

In fact, you can avoid this routing declaration and declare your own endpoint. Then you will have this kind of route:

http://app.loc/webhook/{secretsalt}/{servicename}/catch

Where servicename might be:
- campainmonitor for https://www.campaignmonitor.com/
- mailgun for https://www.mailgun.com/
- mailjet for https://www.mailjet.com/
- mandrill for https://www.mandrill.com/
- sendgrid for https://sendgrid.com/
- sparkpost for https://www.sparkpost.com/

Last step of configuration is on your email provider service. You have to configure the webhook url and which event you want.

Sparkpost configuration for example.

Perfect! Each Mailhook will now hit your route and dispatch different events in your app. You just have to implement your own listeners on those events name:

swm.mail_hook.event.open
swm.mail_hook.event.send
swm.mail_hook.event.click
swm.mail_hook.event.soft_bounce
swm.mail_hook.event.hard_bounce
swm.mail_hook.event.deferral
swm.mail_hook.event.spam
swm.mail_hook.event.blocked
swm.mail_hook.event.unsub
swm.mail_hook.event.reject
swm.mail_hook.event.other

Event implements HookEventInterface where you can easily get Email.

Here’s a simple implementation:

Now, let’s catch them all!

--

--

Thomas P

Symfony lover, Gopher and opensource enthusiast. Ex-firefighter 🚒, I miss cuting out cars 🚙.