Pular para o conteúdo
couryo

Guia do desenvolvedorIntegrações

Enviar e-mail no Laravel

Enviar e-mail pelo Couryo no Laravel com Mail::to()->send(), pelo transporte couryo do SDK PHP ou por SMTP, com tags, filas e webhook assinado.

Ver em Markdown

Duas formas, as duas com Mail::to()->send() e os seus Mailables de sempre:

  • Transporte couryo do SDK PHP (recomendado): fala com a API, devolve o ID da mensagem e leva as tags e os metadados do Mailable.
  • SMTP: nenhuma dependência nova, só o .env.

Opção 1: transporte do SDK#

Terminal
composer require couryo/couryo-php

O service provider é registrado sozinho (auto-discovery). Configure o .env:

.env
MAIL_MAILER=couryo
COURYO_API_KEY=ck_test_...
COURYO_WEBHOOK_SECRET=whsec_...
MAIL_FROM_ADDRESS=oi@exemplo.com.br
MAIL_FROM_NAME="Exemplo"

E acrescente o mailer em config/mail.php:

config/mail.php
'mailers' => [
    // ...
    'couryo' => [
        'transport' => 'couryo',
    ],
],

Pronto. O código que já existe continua igual:

app/Http/Controllers/PedidoController.php
use App\Mail\PedidoEnviado;
use Illuminate\Support\Facades\Mail;

Mail::to($pedido->cliente->email)->send(new PedidoEnviado($pedido));

// Em fila (recomendado para não segurar a requisição):
Mail::to($pedido->cliente->email)->queue(new PedidoEnviado($pedido));

Tags e metadados do Mailable viram tags e metadata no Couryo, para filtrar no painel e nos webhooks:

app/Mail/PedidoEnviado.php
use Illuminate\Mail\Mailables\Envelope;

public function envelope(): Envelope
{
    return new Envelope(
        subject: "Seu pedido {$this->pedido->numero} saiu para entrega",
        tags: ['pedido'],
        metadata: ['pedido_id' => (string) $this->pedido->id],
    );
}

Para mandar no fluxo de marketing (com descadastro em um clique), acrescente o cabeçalho X-Couryo-Stream: marketing no método headers() do Mailable. Sem ele, o e-mail é transacional.

Chamar a API direto#

Para o que o Mail não cobre (lote, templates salvos, domínios, contatos, eventos e campanhas), injete o cliente:

app/Http/Controllers/CadastroController.php
use Couryo\Couryo;

public function store(Request $request, Couryo $couryo)
{
    $usuario = User::create($request->validated());

    $couryo->events->track([
        'contact' => ['email' => $usuario->email, 'attributes' => ['nome' => $usuario->name]],
        'name' => 'user.signed_up',
    ], ['idempotency_key' => "signup-{$usuario->id}"]);

    return redirect('/painel');
}

Opção 2: SMTP#

Sem pacote nenhum. No Laravel 11 ou mais novo:

.env
MAIL_MAILER=smtp
MAIL_SCHEME=smtp
MAIL_HOST=smtp.couryo.com
MAIL_PORT=587
MAIL_USERNAME=couryo
MAIL_PASSWORD=ck_live_...
MAIL_FROM_ADDRESS=oi@exemplo.com.br
MAIL_FROM_NAME="Exemplo"

Na porta 587 a conexão sobe para TLS (STARTTLS) sozinha. Para a 465, use MAIL_SCHEME=smtps. No Laravel 10 ou anterior, troque MAIL_SCHEME por MAIL_ENCRYPTION=tls.

Por SMTP, X-Couryo-Tags: tipo=pedido e X-Couryo-Stream: marketing nos cabeçalhos do Mailable fazem o mesmo papel das tags e do fluxo. Veja SMTP.

Receber webhooks#

routes/web.php
use Couryo\Exception\WebhookVerificationError;
use Couryo\Webhook;
use Illuminate\Http\Request;

Route::post('/webhooks/couryo', function (Request $request) {
    try {
        $evento = Webhook::verify(config('couryo.webhook_secret'), $request->headers->all(), $request->getContent());
    } catch (WebhookVerificationError $e) {
        abort(400, 'assinatura inválida');
    }

    if ($evento['type'] === 'bounced') {
        // $evento['data']['recipient'], $evento['data']['explanation']
    }

    return response()->noContent();
});

Tire a rota da proteção CSRF (a assinatura já protege). No Laravel 11 ou mais novo:

bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
    $middleware->validateCsrfTokens(except: ['webhooks/couryo']);
})

Testar sem enviar#

Com uma chave ck_test_, os e-mails são capturados e aparecem no painel, sem chegar a ninguém (modo de teste). Nos testes automatizados, continue usando Mail::fake().

Problemas comuns#

Sintoma O que fazer
Unsupported mail transport [couryo] o pacote não foi carregado: rode composer dump-autoload e php artisan config:clear
domain_not_verified o MAIL_FROM_ADDRESS precisa estar num domínio verificado
535 5.7.8 no SMTP usuário diferente de couryo ou chave inválida, revogada ou sem escopo send
Webhook com 419 a rota ainda está na proteção CSRF