Skip to content

Commit b23344e

Browse files
committed
improved mailgun support
1 parent c524749 commit b23344e

File tree

8 files changed

+78
-64
lines changed

8 files changed

+78
-64
lines changed

src/Actions/AttachUuid.php

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,19 @@
44

55
use Illuminate\Mail\Events\MessageSending;
66
use Illuminate\Support\Str;
7+
use Vormkracht10\Mails\Facades\MailProvider;
78
use Vormkracht10\Mails\Shared\AsAction;
89

910
class AttachUuid
1011
{
1112
use AsAction;
1213

13-
public function handle(MessageSending $event)
14+
public function handle(MessageSending $event): void
1415
{
15-
if ($event->message->getHeaders()->has(config('mails.headers.uuid'))) {
16-
return;
17-
}
18-
1916
$uuid = Str::uuid()->toString();
2017

2118
$event->message->getHeaders()->addTextHeader(config('mails.headers.uuid'), $uuid);
2219

23-
// specifically for Postmark
24-
$event->message->getHeaders()->addTextHeader('X-PM-Metadata-'.config('mails.headers.uuid'), $uuid);
20+
$event = MailProvider::with($event->data['mailer'])->attachUuidToMail($event, $uuid);
2521
}
2622
}

src/Actions/LogMail.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Illuminate\Support\Collection;
88
use Illuminate\Support\Facades\Storage;
99
use Symfony\Component\Mime\Address;
10+
use Vormkracht10\Mails\Enums\Provider;
1011
use Vormkracht10\Mails\Shared\AsAction;
1112

1213
class LogMail
@@ -72,14 +73,14 @@ public function getDefaultLogAttributes(MessageSending|MessageSent $event): arra
7273
'html' => $event->message->getHtmlBody(),
7374
'text' => $event->message->getTextBody(),
7475
'tags' => collect($event->message->getHeaders()->all('X-tag'))
75-
->map(fn ($tag) => $tag->getValue())
76-
->toArray(),
76+
->map(fn ($tag) => $tag->getValue())
77+
->toArray(),
7778
];
7879
}
7980

8081
protected function getStreamId(MessageSending|MessageSent $event): ?string
8182
{
82-
if ($event->data['mailer'] !== 'postmark') {
83+
if ($event->data['mailer'] !== Provider::POSTMARK) {
8384
return null;
8485
}
8586

src/Contracts/MailDriverContract.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Vormkracht10\Mails\Contracts;
44

5+
use Illuminate\Mail\Events\MessageSending;
56
use Vormkracht10\Mails\Models\Mail;
67

78
interface MailDriverContract
@@ -10,6 +11,8 @@ public function registerWebhooks($components): void;
1011

1112
public function verifyWebhookSignature(array $payload): bool;
1213

14+
public function attachUuidToMail(MessageSending $event, string $uuid): MessageSending;
15+
1316
public function getUuidFromPayload(array $payload): ?string;
1417

1518
public function getMailFromPayload(array $payload): ?Mail;

src/Drivers/MailDriver.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public function getDataFromPayload(array $payload): array
4141
->mapWithKeys(fn ($value, $key) => [$key => data_get($payload, $value)])
4242
->filter()
4343
->merge([
44+
'payload' => $payload,
4445
'type' => $this->getEventFromPayload($payload),
4546
'occurred_at' => $this->getTimestampFromPayload($payload),
4647
])
@@ -82,7 +83,6 @@ public function accepted(Mail $mail, string $timestamp): void
8283
{
8384
$mail->update([
8485
'accepted_at' => $timestamp,
85-
'opens' => $mail->opens + 1,
8686
]);
8787
}
8888

@@ -115,18 +115,18 @@ public function hardBounced(Mail $mail, string $timestamp): void
115115
]);
116116
}
117117

118-
public function opened(Mail $mail, string $timestamp): void
118+
public function softBounced(Mail $mail, string $timestamp): void
119119
{
120120
$mail->update([
121-
'last_opened_at' => $timestamp,
122-
'opens' => $mail->opens + 1,
121+
'soft_bounced_at' => $timestamp,
123122
]);
124123
}
125124

126-
public function softBounced(Mail $mail, string $timestamp): void
125+
public function opened(Mail $mail, string $timestamp): void
127126
{
128127
$mail->update([
129-
'soft_bounced_at' => $timestamp,
128+
'last_opened_at' => $timestamp,
129+
'opens' => $mail->opens + 1,
130130
]);
131131
}
132132

src/Drivers/MailgunDriver.php

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
namespace Vormkracht10\Mails\Drivers;
44

55
use Illuminate\Http\Client\Response;
6+
use Illuminate\Mail\Events\MessageSending;
67
use Illuminate\Support\Facades\Http;
78
use Illuminate\Support\Facades\URL;
89
use Vormkracht10\Mails\Contracts\MailDriverContract;
910
use Vormkracht10\Mails\Enums\EventType;
11+
use Vormkracht10\Mails\Enums\Provider;
1012

1113
class MailgunDriver extends MailDriver implements MailDriverContract
1214
{
@@ -19,7 +21,7 @@ public function registerWebhooks($components): void
1921
$scheme = config('services.mailgun.scheme', 'https');
2022
$endpoint = config('services.mailgun.endpoint', 'api.mailgun.net');
2123

22-
$webhookUrl = URL::signedRoute('mails.webhook', ['provider' => 'mailgun']);
24+
$webhookUrl = URL::signedRoute('mails.webhook', ['provider' => Provider::MAILGUN]);
2325

2426
$events = [];
2527

@@ -60,11 +62,12 @@ public function registerWebhooks($components): void
6062
$message = $response->json()['message'] ?? null;
6163

6264
if ($response->successful()) {
63-
$components->info("Created Mailgun webhook for: $event ($message)");
65+
$components->info("Created Mailgun webhook for: $event");
6466
} elseif ($message === 'Webhook already exists') {
6567
$components->info("Mailgun webhook already exists for: $event");
6668
} else {
67-
$components->error("Failed to create Mailgun webhook for: $event");
69+
$components->warn("Failed to create Mailgun webhook for: $event");
70+
$components->error($message);
6871
}
6972
}
7073
}
@@ -88,12 +91,16 @@ public function verifyWebhookSignature(array $payload): bool
8891
return $hmac === $payload['signature']['signature'];
8992
}
9093

94+
public function attachUuidToMail(MessageSending $event, string $uuid): MessageSending
95+
{
96+
$event->message->getHeaders()->addTextHeader('X-Mailgun-Variables', json_encode([config('mails.headers.uuid') => $uuid]));
97+
98+
return $event;
99+
}
100+
91101
public function getUuidFromPayload(array $payload): ?string
92102
{
93-
return $payload['event-data']['message']['headers'][$this->uuidHeaderName] ??
94-
$payload['event-data']['message']['headers'][strtolower($this->uuidHeaderName)] ??
95-
$payload['event-data']['message']['headers'][strtoupper($this->uuidHeaderName)] ??
96-
null;
103+
return $payload['event-data']['user-variables'][config('mails.headers.uuid')] ?? null;
97104
}
98105

99106
protected function getTimestampFromPayload(array $payload): string
@@ -118,14 +125,15 @@ public function eventMapping(): array
118125
public function dataMapping(): array
119126
{
120127
return [
121-
'ip_address' => 'ip',
122-
'platform' => 'client-info.device-type',
123-
'os' => 'client-info.client-os',
124-
'browser' => 'client-info.client-name',
125-
'user_agent' => 'client-info.user-agent',
126-
'country_code' => 'geolocation.region',
128+
'ip_address' => 'event-data.ip',
129+
'platform' => 'event-data.client-info.device-type',
130+
'os' => 'event-data.client-info.client-os',
131+
'browser' => 'event-data.client-info.client-name',
132+
'user_agent' => 'event-data.client-info.user-agent',
133+
'city' => 'event-data.geolocation.city',
134+
'country_code' => 'event-data.geolocation.country',
127135
'link' => 'event-data.url',
128-
'tag' => 'tags',
136+
'tag' => 'event-data.tags',
129137
];
130138
}
131139

src/Drivers/PostmarkDriver.php

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
namespace Vormkracht10\Mails\Drivers;
44

55
use Illuminate\Http\Client\Response;
6+
use Illuminate\Mail\Events\MessageSending;
67
use Illuminate\Support\Facades\Http;
78
use Illuminate\Support\Facades\URL;
89
use Vormkracht10\Mails\Contracts\MailDriverContract;
910
use Vormkracht10\Mails\Enums\EventType;
11+
use Vormkracht10\Mails\Enums\Provider;
1012

1113
class PostmarkDriver extends MailDriver implements MailDriverContract
1214
{
@@ -38,7 +40,7 @@ public function registerWebhooks($components): void
3840
],
3941
];
4042

41-
$webhookUrl = URL::signedRoute('mails.webhook', ['provider' => 'postmark']);
43+
$webhookUrl = URL::signedRoute('mails.webhook', ['provider' => Provider::POSTMARK]);
4244

4345
$token = (string) config('services.postmark.token');
4446

@@ -100,6 +102,13 @@ public function verifyWebhookSignature(array $payload): bool
100102
return true;
101103
}
102104

105+
public function attachUuidToMail(MessageSending $event, string $uuid): MessageSending
106+
{
107+
$event->message->getHeaders()->addTextHeader('X-PM-Metadata-'.config('mails.headers.uuid'), $uuid);
108+
109+
return $event;
110+
}
111+
103112
public function getUuidFromPayload(array $payload): ?string
104113
{
105114
return $payload['Metadata'][$this->uuidHeaderName] ??
@@ -150,12 +159,7 @@ public function unsuppressEmailAddress(string $address, $stream_id): Response
150159
->baseUrl('https://api.postmarkapp.com/');
151160

152161
return $client->post('message-streams/'.$stream_id.'/suppressions/delete', [
153-
'Suppressions' => [
154-
[
155-
'emailAddress' => $address,
156-
],
157-
],
162+
'Suppressions' => [['emailAddress' => $address]],
158163
]);
159-
160164
}
161165
}

0 commit comments

Comments
 (0)