# Enviar e-mails com Laravel

> Envie os e-mails do Laravel pelo Emailit com o transporte de e-mail e a facade do emailit/emailit-laravel, ou com SMTP simples, e verifique os webhooks do Emailit.

Este guia mostra duas formas de enviar os e-mails do Laravel pelo Emailit: o pacote `emailit/emailit-laravel`, que adiciona um transporte de e-mail `emailit` e uma facade `Emailit`, e o SMTP simples com o mailer nativo do Laravel. Ele termina com uma rota de webhook que verifica as assinaturas.

## Pré-requisitos

- PHP 8.1 ou mais recente e Laravel 10, 11 ou 12.
- Um [domínio de envio verificado](/pt/docs/domains/add-a-domain/), por exemplo, `acme.com`.
- Uma [chave de API](/pt/docs/developers/api-keys/). Uma chave Sending Only restrita ao seu domínio é suficiente.
- Até o seu workspace ter [acesso de produção](/pt/docs/workspaces/production-access/), você só pode enviar para os e-mails das contas dos membros do workspace.

## Opção 1: o pacote Laravel do Emailit

O pacote envia as suas Mailables, Markdown mailables, notificações e e-mails em fila existentes pela API do Emailit, sem alterações no seu código de e-mail.

### Instalar o pacote

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

O service provider é descoberto automaticamente.

### Configurar o transporte

Adicione a sua chave e defina o Emailit como mailer padrão no `.env`:

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

Registre o mailer em `config/mail.php`:

```php title="config/mail.php"
'mailers' => [
    // ...

    'emailit' => [
        'transport' => 'emailit',
    ],
],
```

`MAIL_FROM_ADDRESS` deve estar em um domínio de envio verificado. Para alterar a URL base da API, publique o arquivo de configuração com `php artisan vendor:publish --tag=emailit-config`; isso não é necessário no uso normal.

### Enviar uma Mailable

Crie uma Mailable como de costume:

```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');
    }
}
```

Envie-a ou coloque-a na fila para que a requisição não espere pela 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));
```

### Usar a facade para recursos da API

A facade `Emailit` expõe o [SDK de PHP](/pt/docs/frameworks/php/) completo, para recursos que o mailer do Laravel não modela, como templates salvos e envios agendados:

```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_…
```

A facade também cobre domínios, contatos, listas de contatos, supressões, webhooks e os outros recursos. Se você preferir injeção de dependência, declare o tipo `Emailit\EmailitClient` em um controller ou job, e o Laravel o resolve com a chave configurada.

Capture as exceções tipadas para tratar as falhas:

```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
}
```

## Opção 2: SMTP simples

Se você preferir não adicionar um pacote, aponte o mailer SMTP do Laravel para o relay do Emailit:

```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 porta 587, o mailer do Laravel ativa o STARTTLS na conexão. Os arquivos `config/mail.php` mais antigos leem `MAIL_ENCRYPTION`, e os mais novos o ignoram, então é seguro mantê-lo. Para TLS implícito, use a porta `465`; se o seu host bloquear a 587, use `2525` ou `2587`. Mailables, notificações e filas funcionam exatamente como com o pacote. Consulte [Configurações de SMTP](/pt/docs/smtp/settings/).

Pelo SMTP, não é possível usar templates salvos nem `scheduled_at`; use a facade ou a API para isso.

## Receber webhooks

[Crie um webhook](/pt/docs/webhooks/set-up/) que aponte para `https://your-app.com/webhooks/emailit` e depois guarde o segredo de assinatura dele:

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

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

Adicione um controller que confira a assinatura com base no corpo bruto:

```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.
    }
}
```

Registre a rota e exclua-a da proteção contra CSRF, porque o Emailit não consegue enviar um 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 e 12)"
->withMiddleware(function (Middleware $middleware) {
    $middleware->validateCsrfTokens(except: ['webhooks/emailit']);
})
```

No Laravel 10, adicione `'webhooks/emailit'` ao array `$except` em `app/Http/Middleware/VerifyCsrfToken.php`. Retorne um `2xx` em até 30 segundos e envie o trabalho demorado para uma fila. Consulte [Assinatura das requisições](/pt/docs/webhooks/request-signature/).

## Dicas para produção

- **Coloque os e-mails na fila.** Use `queue()` ou `ShouldQueue` para que as requisições web não esperem pelo e-mail e limite o ritmo dos jobs em massa (por exemplo, com `Redis::throttle`) para ficar dentro dos seus [limites de envio](/pt/docs/limits/). Por padrão, os workspaces novos podem enviar 2 e-mails por segundo.
- **Use o cache de configuração com segurança.** Depois de `php artisan config:cache`, `env()` só funciona dentro dos arquivos de configuração. Leia a chave pela configuração, como o pacote faz.
- **Use uma chave dedicada.** Dê a cada aplicação e ambiente a sua própria chave Sending Only para poder fazer a rotação de uma sem mexer nas outras. Consulte [Chaves de API](/pt/docs/developers/api-keys/).
- **Elimine webhooks duplicados.** Guarde cada `event_id` que você processa e ignore as repetições, porque as entregas com falha recebem novas tentativas.

## Próximos passos

  - [Guia do SDK de PHP](/pt/docs/frameworks/php/): O cliente por trás da facade.
  - [Templates](/pt/docs/templates/): Crie e-mails no Emailit e envie-os pelo alias.
  - [Tipos de evento de webhook](/pt/docs/webhooks/event-types/): Todos os eventos e os payloads deles.
  - [Solução de problemas de SMTP](/pt/docs/smtp/troubleshooting/): Corrija erros de autenticação e de conexão.

---
Fonte: https://emailit.com/pt/docs/frameworks/laravel/
