Here is my code if you want to set it up yourself (it just dispatches an even to the right place with the data I need). You can setup the webhooks on their website.
<?php
namespace App\Webhooks;
use App\Jobs\ParseMailDelivered;
use App\Jobs\ParseMailFailed;
use App\Models\Survey\EmailTemplate;
class MailgunWebhook
{
/**
* @var \App\Models\Survey\EmailTemplate
*/
protected $email;
/**
* MailgunWebhook constructor.
*
* @param \App\Models\Survey\EmailTemplate $email Email template instance.
*/
public function __construct(EmailTemplate $email)
{
$this->email = $email;
}
/**
* Handle delivered message data
*
* @param array $data Incoming data.
*
* @return mixed
* @throws \Exception Signature is invalid.
*/
public function handleDelivered(array $data)
{
if (!$this->validate($data['signature'])) {
throw new \Exception('Invalid signature!');
}
$event_data = $data['event-data'];
$delivered_data = [
'tags' => $event_data['tags'],
'recipient' => $event_data['recipient'],
'headers' => $event_data['message']['headers'],
'timestamp' => $event_data['timestamp'],
];
return ParseMailDelivered::dispatchNow($this->email, $delivered_data);
}
/**
* Handle failed message data
*
* @param array $data Incoming data.
*
* @return mixed
* @throws \Exception Signature is invalid.
*/
public function handleFailed(array $data)
{
if (!$this->validate($data['signature'])) {
throw new \Exception('Invalid signature!');
}
$event_data = $data['event-data'];
$delivered_data = [
'tags' => $event_data['tags'],
'recipient' => $event_data['recipient'],
'headers' => $event_data['message']['headers'],
'timestamp' => $event_data['timestamp'],
'delivery_status' => $event_data['delivery-status'],
'severity' => $event_data['severity'],
];
return ParseMailFailed::dispatchNow($this->email, $delivered_data);
}
/**
* @param array $signature
* @param string $api_key
*
* @return bool
*/
protected function validate(array $signature, $api_key = null)
{
$timestamp = $signature['timestamp'];
$token = $signature['token'];
$signature = $signature['signature'];
//Concat timestamp and token values
if (empty($timestamp) || empty($token) || empty($signature)) {
return false;
}
$api_key = $api_key ? $api_key : config('mailgun.api_key');
$hmac = hash_hmac('sha256', $timestamp.$token, $api_key);
if (function_exists('hash_equals')) {
// hash_equals is constant time, but will not be introduced until PHP 5.6
return hash_equals($hmac, $signature);
} else {
return $hmac === $signature;
}
}
}
And the routes. Remember to disable CsrfToken check for the routes in VerifyCsrfToken (middleware)
Route::post('/mailgun/delivered', 'WebhookController@emailDelivered');
Route::post('/mailgun/failed', 'WebhookController@emailFailed');