resend/resend-php
Resend PHP is an official PHP 8.1+ client for the Resend email API. Install via Composer and send transactional emails with a clean, simple interface (e.g., $resend->emails->send) in PHP or Laravel.
Pros:
config, services.php, and Mail facade.emails, contacts, templates, etc.), which maps cleanly to Laravel’s Eloquent-like service organization.Idempotency-Key and rate-limiting error handling aligns with Laravel’s queue/retry systems (e.g., Illuminate\Queue).Cons:
laravel-notification-center or spatie/laravel-mailables, this SDK lacks built-in integration with Laravel’s Notifiable trait or Mail classes. A TPM would need to bridge this gap (e.g., via a custom facade or service provider).Illuminate\Bus\Dispatchable) isn’t natively integrated. A TPM would need to design a listener layer (e.g., ResendWebhookHandler) to translate Resend events into Laravel events.Resend::client() can be registered in config/services.php and bound to the container, enabling dependency injection in controllers/services.Mail facade (e.g., via a custom ResendMailer class).Resend::emails->send() wrapped in a job).User extending ResendContact).automations/events). The SDK’s maturity (v1.3.0) suggests stability, but a TPM should monitor for breaking changes.ResendException) may need wrapping to align with Laravel’s exception hierarchy (e.g., Illuminate\Mail\MailerException).contacts->upsert) could impact Laravel’s request lifecycle. A TPM should benchmark under load.config/cache.php to store Resend API keys/endpoints.ResendServiceProvider to centralize configuration and bindings.ResendFacade to abstract SDK calls (e.g., Resend::sendWelcomeEmail()).Mail facade entirely, or coexist with it? If the latter, how will conflicts (e.g., from address validation) be resolved?ResendWebhookController be created, or will events be dispatched via a service?User) sync with Resend contacts? Will a ResendContactable trait be created?resend->logs) be surfaced in Laravel’s logging system (e.g., Monolog)?log, ses)? If so, how will this be implemented?AppServiceProvider:
$this->app->singleton(Resend::class, fn() => Resend::client(config('services.resend.key')));
resend to config/services.php:
'resend' => [
'key' => env('RESEND_API_KEY'),
'webhook_secret' => env('RESEND_WEBHOOK_SECRET'),
],
Mailer to use the SDK:
class ResendMailer extends Mailer {
public function send(MailableContract $mailable, array $failures = []) {
$resend = app(Resend::class);
$resend->emails->send($this->prepare($mailable));
}
}
ResendMailer facade for SDK-specific calls.SendResendEmailJob) for async processing:
class SendResendEmailJob implements ShouldQueue {
use Dispatchable, InteractsWithQueue;
public function handle() {
Resend::emails()->send($this->emailData);
}
}
/resend/webhook to a controller with signature verification:
public function handleWebhook(Request $request) {
$payload = $request->getContent();
$signature = $request->header('x-resend-signature');
if (!Resend::verifyWebhook($payload, $signature, config('services.resend.webhook_secret'))) {
abort(401);
}
event(new ResendWebhookReceived($payload));
}
composer require resend/resend-php.AppServiceProvider.Resend::emails()->send()).ResendFacade or ResendService to abstract SDK calls.// app/Services/ResendService.php
class ResendService {
public function sendWelcomeEmail(User $user) {
return Resend::emails()->send([
'from' => '[email protected]',
'to' => $user->email,
'subject' => 'Welcome!',
'html' => view('emails.welcome', ['user' => $user]),
]);
}
}
// app/Listeners/HandleResendEvent.php
class HandleResendEvent {
public function handle(ResendWebhookReceived $event) {
$data = $event->payload;
if ($data['event'] === 'email.bounce') {
// Update user's email status in DB
}
}
}
// app/Observers/UserObserver.php
class UserObserver {
public function saved(User $user) {
Resend::contacts()->upsert($user->email, [
'name' => $user->name,
'metadata' => ['user_id' => $user->id],
]);
}
}
illuminate/mail, guzzlehttp/guzzle).resend_contacts table for sync metadata.How can I help you explore Laravel packages today?