# 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](/cs/docs/domains/add-a-domain/), například `acme.com`.
- [API klíč](/cs/docs/developers/api-keys/). Stačí klíč jen pro odesílání omezený na vaši doménu.
- Dokud váš workspace nemá [produkční přístup](/cs/docs/workspaces/production-access/), 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

```bash
composer require emailit/emailit-laravel
```

Service provider se zaregistruje automaticky (auto-discovery).

### Nastavte transport

Do `.env` přidejte svůj klíč a nastavte Emailit jako výchozí mailer:

```bash title=".env"
EMAILIT_API_KEY=secret_••••••••••••••••••••••••••••••••
MAIL_MAILER=emailit
MAIL_FROM_ADDRESS=hello@acme.com
MAIL_FROM_NAME="Acme"
```

Zaregistrujte mailer v `config/mail.php`:

```php title="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:

```bash
php artisan make:mail WelcomeEmail
```

```php title="app/Mail/WelcomeEmail.php"
namespace 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:

```php
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](/cs/docs/frameworks/php/) pro funkce, které mailer Laravelu nepokrývá, například uložené šablony a plánované odesílání:

```php
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:

```php
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:

```bash title=".env"
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](/cs/docs/smtp/settings/).

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](/cs/docs/webhooks/set-up/), který míří na `https://your-app.com/webhooks/emailit`, a pak uložte jeho tajný klíč:

```bash title=".env"
EMAILIT_WEBHOOK_SECRET=whsec_••••••••
```

```php title="config/services.php"
'emailit' => [
    'webhook_secret' => env('EMAILIT_WEBHOOK_SECRET'),
],
```

Přidejte controller, který porovná podpis se surovým tělem požadavku:

```php title="app/Http/Controllers/EmailitWebhookController.php"
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:

```php title="routes/web.php"
use App\Http\Controllers\EmailitWebhookController;

Route::post('/webhooks/emailit', EmailitWebhookController::class);
```

```php title="bootstrap/app.php (Laravel 11 a 12)"
->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ů](/cs/docs/webhooks/request-signature/).

## Tipy pro produkční provoz

- **Řaďte poštu do fronty.** Použijte `queue()` nebo `ShouldQueue`, 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í](/cs/docs/limits/). Nové workspace mohou ve výchozím stavu odeslat 2 e-maily za sekundu.
- **Konfiguraci cachujte bezpečně.** Po `php artisan config:cache` funguje `env()` 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](/cs/docs/developers/api-keys/).
- **Odstraňujte duplicitní webhooky.** Ukládejte si každé zpracované `event_id` a opakované události přeskakujte, protože neúspěšná doručení se opakují.

## Další kroky

  - [Návod k PHP SDK](/cs/docs/frameworks/php/): Klient, který je za fasádou.
  - [Šablony](/cs/docs/templates/): Navrhněte e-maily v Emailitu a odesílejte je podle aliasu.
  - [Typy událostí webhooků](/cs/docs/webhooks/event-types/): Všechny události a jejich obsah.
  - [Řešení problémů se SMTP](/cs/docs/smtp/troubleshooting/): Opravte chyby autentizace a připojení.

---
Zdroj: https://emailit.com/cs/docs/frameworks/laravel/
