Tutoriál
Odesílání e-mailů z Laravelu
Odesílejte poštu z Laravelu přes Emailit pomocí mail transportu a fasády z emailit/emailit-laravel, nebo přes obyčejné SMTP, a ověřujte webhooky Emailitu.
Tento návod ukazuje dva způsoby, jak odesílat poštu z Laravelu přes Emailit: balíček emailit/emailit-laravel, který přidává mail transport emailit a fasádu Emailit, a obyčejné SMTP s vestavěným mailerem Laravelu. Na konci najdete webhookovou routu, která ověřuje podpisy.
Předpoklady
- PHP 8.1 nebo novější a Laravel 10, 11 nebo 12.
- Ověřená odesílací doména, například
acme.com. - API klíč. Stačí klíč jen pro odesílání omezený na vaši doménu.
- Dokud váš workspace nemá produkční přístup, můžete odesílat jen na e-mailové adresy účtů členů workspace.
Možnost 1: balíček Emailit pro Laravel
Balíček odesílá vaše stávající Mailables, Markdown Mailables, notifikace i poštu z fronty přes API Emailitu, aniž byste museli měnit kód pro odesílání pošty.
Nainstalujte balíček
composer require emailit/emailit-laravelService provider se zaregistruje automaticky (auto-discovery).
Nastavte transport
Do .env přidejte svůj klíč a nastavte Emailit jako výchozí mailer:
EMAILIT_API_KEY=secret_••••••••••••••••••••••••••••••••
MAIL_MAILER=emailit
MAIL_FROM_ADDRESS=hello@acme.com
MAIL_FROM_NAME="Acme"Zaregistrujte mailer v config/mail.php:
'mailers' => [
// ...
'emailit' => [
'transport' => 'emailit',
],
],MAIL_FROM_ADDRESS musí být na ověřené odesílací doméně. Pokud chcete změnit základní URL API, publikujte konfigurační soubor příkazem php artisan vendor:publish --tag=emailit-config; při běžném použití to nepotřebujete.
Odešlete Mailable
Vytvořte Mailable jako obvykle:
php artisan make:mail WelcomeEmailnamespace App\Mail;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class WelcomeEmail extends Mailable
{
use Queueable, SerializesModels;
public function __construct(public User $user) {}
public function envelope(): Envelope
{
return new Envelope(subject: 'Welcome to Acme');
}
public function content(): Content
{
return new Content(view: 'emails.welcome');
}
}Odešlete ho, nebo ho zařaďte do fronty, aby požadavek nečekal na API:
use App\Mail\WelcomeEmail;
use Illuminate\Support\Facades\Mail;
Mail::to($user)->send(new WelcomeEmail($user));
Mail::to($user)->queue(new WelcomeEmail($user));Funkce API používejte přes fasádu
Fasáda Emailit zpřístupňuje celé PHP SDK pro funkce, které mailer Laravelu nepokrývá, například uložené šablony a plánované odesílání:
use Emailit\Laravel\Facades\Emailit;
$email = Emailit::emails()->send([
'from' => 'Acme <hello@acme.com>',
'to' => $user->email,
'template' => 'welcome',
'variables' => ['first_name' => $user->first_name],
'scheduled_at' => 'tomorrow at 9am',
]);
$email->id; // em_…Fasáda pokrývá také domény, kontakty, seznamy kontaktů, blokované adresy, webhooky a další zdroje. Pokud dáváte přednost dependency injection, uveďte typ Emailit\EmailitClient v controlleru nebo jobu a Laravel ho vytvoří s nastaveným klíčem.
Chyby ošetřete zachytáváním typovaných výjimek:
use Emailit\Exceptions\ApiErrorException;
use Emailit\Exceptions\RateLimitException;
try {
Emailit::emails()->send($payload);
} catch (RateLimitException $e) {
// 429: release the job back to the queue and try again later
} catch (ApiErrorException $e) {
report($e); // $e->getHttpStatus() has the status code
}Možnost 2: obyčejné SMTP
Pokud nechcete přidávat balíček, nasměrujte SMTP mailer Laravelu na SMTP relay Emailitu:
MAIL_MAILER=smtp
MAIL_HOST=smtp.emailit.com
MAIL_PORT=587
MAIL_USERNAME=emailit
MAIL_PASSWORD=secret_••••••••••••••••••••••••••••••••
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=hello@acme.com
MAIL_FROM_NAME="Acme"Na portu 587 mailer Laravelu přepne spojení na šifrované příkazem STARTTLS. Starší soubory config/mail.php čtou MAIL_ENCRYPTION a novější ho ignorují, takže ho můžete bez obav ponechat. Pro implicitní TLS použijte port 465; pokud váš hosting blokuje port 587, použijte 2525 nebo 2587. Mailables, notifikace i fronty fungují stejně jako s balíčkem. Viz Nastavení SMTP.
Přes SMTP nemůžete používat uložené šablony ani scheduled_at; k tomu použijte fasádu, nebo API.
Přijímejte webhooky
Vytvořte webhook, který míří na https://your-app.com/webhooks/emailit, a pak uložte jeho tajný klíč:
EMAILIT_WEBHOOK_SECRET=whsec_••••••••'emailit' => [
'webhook_secret' => env('EMAILIT_WEBHOOK_SECRET'),
],Přidejte controller, který porovná podpis se surovým tělem požadavku:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class EmailitWebhookController extends Controller
{
public function __invoke(Request $request)
{
$payload = $request->getContent();
$signature = (string) $request->header('X-Emailit-Signature');
$timestamp = (string) $request->header('X-Emailit-Timestamp');
$expected = hash_hmac('sha256', $timestamp.'.'.$payload, config('services.emailit.webhook_secret'));
if (abs(time() - (int) $timestamp) > 300 || ! hash_equals($expected, $signature)) {
abort(401, 'Invalid signature');
}
// The body is a JSON array of up to 100 events.
foreach (json_decode($payload, true) as $event) {
match ($event['type']) {
'email.bounced', 'email.complained' => $this->stopEmailing($event['data']['object']['to']),
default => null,
};
}
return response()->noContent();
}
private function stopEmailing(string $address): void
{
// Mark the address as undeliverable in your database.
}
}Zaregistrujte routu a vyjměte ji z ochrany CSRF, protože Emailit nemůže poslat token CSRF:
use App\Http\Controllers\EmailitWebhookController;
Route::post('/webhooks/emailit', EmailitWebhookController::class);->withMiddleware(function (Middleware $middleware) {
$middleware->validateCsrfTokens(except: ['webhooks/emailit']);
})V Laravelu 10 místo toho přidejte 'webhooks/emailit' do pole $except v app/Http/Middleware/VerifyCsrfToken.php. Do 30 sekund vraťte 2xx a pomalou práci přesuňte do fronty. Viz Ověření podpisu webhooků.
Tipy pro produkční provoz
- Řaďte poštu do fronty. Použijte
queue()neboShouldQueue, aby webové požadavky nečekaly na e-mail, a hromadné joby zpomalte (například pomocíRedis::throttle), abyste zůstali pod svými limity odesílání. Nové workspace mohou ve výchozím stavu odeslat 2 e-maily za sekundu. - Konfiguraci cachujte bezpečně. Po
php artisan config:cachefungujeenv()jen v konfiguračních souborech. Klíč čtěte přes konfiguraci, stejně jako to dělá balíček. - Používejte vyhrazený klíč. Dejte každé aplikaci a prostředí vlastní klíč jen pro odesílání, abyste mohli jeden vyměnit, aniž byste sahali na ostatní. Viz API klíče.
- Odstraňujte duplicitní webhooky. Ukládejte si každé zpracované
event_ida opakované události přeskakujte, protože neúspěšná doručení se opakují.