Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 26 additions & 6 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,17 @@
"larastan/larastan": "^3.0",
"laravel-notification-channels/discord": "^1.6",
"laravel-notification-channels/telegram": "^4.0 || ^5.0 || ^6.0",
"laravel/slack-notification-channel": "^2.5 || ^3.3.2",
"laravel/pint": "^1.17.0",
"laravel/slack-notification-channel": "^2.5 || ^3.3.2",
"nunomaduro/collision": "^7.5.0|^8.4",
"orchestra/testbench": "^8.5.0|^9.4.0",
"pestphp/pest-plugin-laravel": "^3.0",
"pestphp/pest": "^3.0",
"pestphp/pest-plugin-laravel": "^3.0",
"phpstan/extension-installer": "^1.4",
"phpstan/phpstan-deprecation-rules": "^2.0",
"phpstan/phpstan-phpunit": "^2.0",
"phpunit/phpunit": "^11.0"
"phpunit/phpunit": "^11.0",
"resend/resend-laravel": "^0.17.0"
},
"autoload": {
"psr-4": {
Expand All @@ -44,18 +45,37 @@
},
"autoload-dev": {
"psr-4": {
"Vormkracht10\\Mails\\Tests\\": "tests"
"Vormkracht10\\Mails\\Tests\\": "tests",
"Workbench\\App\\": "workbench/app/",
"Workbench\\Database\\Factories\\": "workbench/database/factories/",
"Workbench\\Database\\Seeders\\": "workbench/database/seeders/"
},
"files": [
"helpers.php"
]
},
"scripts": {
"post-autoload-dump": "@php ./vendor/bin/testbench package:discover --ansi",
"post-autoload-dump": [
"@clear",
"@prepare",
"@php ./vendor/bin/testbench package:discover --ansi"
],
"analyse": "vendor/bin/phpstan analyse",
"test": "vendor/bin/pest",
"test-coverage": "vendor/bin/pest --coverage",
"format": "vendor/bin/pint"
"format": "vendor/bin/pint",
"clear": "@php vendor/bin/testbench package:purge-skeleton --ansi",
"prepare": "@php vendor/bin/testbench package:discover --ansi",
"build": "@php vendor/bin/testbench workbench:build --ansi",
"serve": [
"Composer\\Config::disableProcessTimeout",
"@build",
"@php vendor/bin/testbench serve --ansi"
],
"lint": [
"@php vendor/bin/pint --ansi",
"@php vendor/bin/phpstan analyse --verbose --ansi"
]
},
"config": {
"sort-packages": true,
Expand Down
128 changes: 128 additions & 0 deletions src/Drivers/ResendDriver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<?php

namespace Vormkracht10\Mails\Drivers;

use Illuminate\Mail\Events\MessageSending;
use Vormkracht10\Mails\Contracts\MailDriverContract;
use Vormkracht10\Mails\Enums\EventType;
use Vormkracht10\Mails\Exceptions\LaravelResendException;
use Vormkracht10\Mails\Models\Mail;

class ResendDriver extends MailDriver implements MailDriverContract
{
protected array $trackingConfig;

public function __construct()
{
parent::__construct();
$this->trackingConfig = (array) config('mails.logging.tracking');
}

/**
* This method only checks that the Laravel Resend package is installed
* and configured as this package sets up webhook functionality
*/
public function registerWebhooks($components): void
{
/**
* Configuration for webhooks are only available in dashboard
*/
if (! class_exists('Resend\Laravel\ResendServiceProvider')) {
throw new LaravelResendException('Unable to find Laravel Resend Package');
}

if (empty(config('resend.webhook.secret'))) {
throw new LaravelResendException('Invalid Resend webhook secret');
}
}

public function verifyWebhookSignature(array $payload): bool
{
/**
* Using webhook created by laravel resend package.
*/
return false;
}

public function attachUuidToMail(MessageSending $event, string $uuid): MessageSending
{
$event->message->getHeaders()->addTextHeader('X-Resend-Variables', json_encode([config('mails.headers.uuid') => $uuid]));

return $event;
}

public function getUuidFromPayload(array $payload): ?string
{
return $payload['data']['email_id'];
}

protected function getTimestampFromPayload(array $payload): string
{
return $payload['data']['created_at'] ?? now();
}

public function eventMapping(): array
{

return [
EventType::ACCEPTED->value => ['type' => 'email.sent'],
EventType::CLICKED->value => ['type' => 'email.clicked'],
EventType::COMPLAINED->value => ['type' => 'email.complained'],
EventType::DELIVERED->value => ['type' => 'email.delivered'],
EventType::HARD_BOUNCED->value => ['type' => 'email.bounced'],
EventType::OPENED->value => ['type' => 'email.opened'],
EventType::SOFT_BOUNCED->value => ['type' => 'email.delivery_delayed'],
];
}

public function dataMapping(): array
{
return [
'ip_address' => 'data.click.ipAddress',
'link' => 'data.click.link',
'user_agent' => 'data.click.userAgent',
];
}

public function clicked(Mail $mail, string $timestamp): void
{
if (! empty($this->trackingConfig['clicks']) && $this->trackingConfig['clicks']) {
parent::clicked($mail, $timestamp);
}
}

public function complained(Mail $mail, string $timestamp): void
{
if (! empty($this->trackingConfig['complaints']) && $this->trackingConfig['complaints']) {
parent::complained($mail, $timestamp);
}
}

public function delivered(Mail $mail, string $timestamp): void
{
if (! empty($this->trackingConfig['deliveries']) && $this->trackingConfig['deliveries']) {
parent::delivered($mail, $timestamp);
}
}

public function hardBounced(Mail $mail, string $timestamp): void
{
if (! empty($this->trackingConfig['bounces']) && $this->trackingConfig['bounces']) {
parent::hardBounced($mail, $timestamp);
}
}

public function softBounced(Mail $mail, string $timestamp): void
{
if (! empty($this->trackingConfig['bounces']) && $this->trackingConfig['bounces']) {
parent::softBounced($mail, $timestamp);
}
}

public function opened(Mail $mail, string $timestamp): void
{
if (! empty($this->trackingConfig['opened']) && $this->trackingConfig['opened']) {
parent::softBounced($mail, $timestamp);
}
}
}
1 change: 1 addition & 0 deletions src/Enums/Provider.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ enum Provider: string
{
case POSTMARK = 'postmark';
case MAILGUN = 'mailgun';
case RESEND = 'resend';
}
10 changes: 10 additions & 0 deletions src/Exceptions/LaravelResendException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Vormkracht10\Mails\Exceptions;

use Exception;

class LaravelResendException extends Exception
{
//
}
14 changes: 14 additions & 0 deletions src/Listeners/ResendLogMailEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Vormkracht10\Mails\Listeners;

use Vormkracht10\Mails\Enums\Provider;
use Vormkracht10\Mails\Events\MailEvent;

class ResendLogMailEvent
{
public function handle($event): void
{
MailEvent::dispatch(Provider::RESEND->value, $event->payload);
}
}
11 changes: 11 additions & 0 deletions src/MailsServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use Vormkracht10\Mails\Listeners\LogSendingMail;
use Vormkracht10\Mails\Listeners\LogSentMail;
use Vormkracht10\Mails\Listeners\NotifyOnBounce;
use Vormkracht10\Mails\Listeners\ResendLogMailEvent;
use Vormkracht10\Mails\Listeners\StoreMailRelations;
use Vormkracht10\Mails\Listeners\UnsuppressEmailAddress;
use Vormkracht10\Mails\Managers\MailProviderManager;
Expand All @@ -39,6 +40,16 @@ public function registeringPackage(): void
$this->app['events']->listen(MessageSent::class, LogSentMail::class);
$this->app['events']->listen(MailHardBounced::class, NotifyOnBounce::class);
$this->app['events']->listen(MailUnsuppressed::class, UnsuppressEmailAddress::class);

if (class_exists('Resend\Laravel\ResendServiceProvider')) {
$this->app['events']->listen('Resend\Laravel\Events\EmailSent', ResendLogMailEvent::class);
$this->app['events']->listen('Resend\Laravel\Events\EmailBounced', ResendLogMailEvent::class);
$this->app['events']->listen('Resend\Laravel\Events\EmailClicked', ResendLogMailEvent::class);
$this->app['events']->listen('Resend\Laravel\Events\EmailComplained', ResendLogMailEvent::class);
$this->app['events']->listen('Resend\Laravel\Events\EmailDelivered', ResendLogMailEvent::class);
$this->app['events']->listen('Resend\Laravel\Events\EmailDeliveredDelayed ', ResendLogMailEvent::class);
$this->app['events']->listen('Resend\Laravel\Events\EmailOpened', ResendLogMailEvent::class);
}
}

public function bootingPackage(): void
Expand Down
6 changes: 6 additions & 0 deletions src/Managers/MailProviderManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Illuminate\Support\Manager;
use Vormkracht10\Mails\Drivers\MailgunDriver;
use Vormkracht10\Mails\Drivers\PostmarkDriver;
use Vormkracht10\Mails\Drivers\ResendDriver;

class MailProviderManager extends Manager
{
Expand All @@ -23,6 +24,11 @@ protected function createMailgunDriver(): MailgunDriver
return new MailgunDriver;
}

protected function createResendDriver(): ResendDriver
{
return new ResendDriver;
}

public function getDefaultDriver(): ?string
{
return null;
Expand Down