# Enviar emails con Ruby on Rails

> Entrega el correo de Action Mailer a través de Emailit con la gema emailit o la configuración SMTP, llama directamente a la API y verifica los webhooks de Emailit en Rails.

En esta guía se explica cómo enviar el correo de Rails a través de Emailit. Puedes usar el método de entrega de Action Mailer de la gema `emailit`, que envía a través de la API, o apuntar la configuración SMTP de Action Mailer al relay de Emailit. También se explica cómo llamar directamente a la API y cómo verificar los webhooks.

## Requisitos previos

- Ruby 3.0 o posterior y una aplicación Rails.
- Un [dominio de envío verificado](/es/docs/domains/add-a-domain/), por ejemplo `acme.com`.
- Una [clave de API](/es/docs/developers/api-keys/). Basta con una clave Sending Only limitada a tu dominio.
- Hasta que tu espacio de trabajo tenga [acceso de producción](/es/docs/workspaces/production-access/), solo puedes enviar a las direcciones de email de las cuentas de los miembros del espacio de trabajo.

## Instalar la gema

```bash
bundle add emailit
```

La gema no tiene dependencias en tiempo de ejecución aparte de la biblioteca estándar de Ruby.

## Configurar la clave de API

Guarda la clave en tu entorno o en las credenciales de Rails:

```bash
bin/rails credentials:edit
```

```yaml
emailit:
  api_key: secret_••••••••••••••••••••••••••••••••
  webhook_secret: whsec_••••••••
```

Los ejemplos siguientes leen `Rails.application.credentials.dig(:emailit, :api_key)`. Si usas variables de entorno, lee en su lugar `ENV.fetch("EMAILIT_API_KEY")`.

## Enviar con Action Mailer

Cuando la gema detecta Rails, registra un método de entrega `:emailit`. Actívalo en cada entorno:

```ruby title="config/environments/production.rb"
config.action_mailer.delivery_method = :emailit
config.action_mailer.emailit_settings = {
  api_key: Rails.application.credentials.dig(:emailit, :api_key)
}
```

Tus mailers no cambian. La dirección `from` debe pertenecer a un dominio de envío verificado:

```ruby title="app/mailers/user_mailer.rb"
class UserMailer < ApplicationMailer
  default from: "Acme <hello@acme.com>"

  def welcome(user)
    @user = user
    mail(to: @user.email, subject: "Welcome to Acme")
  end
end
```

```ruby
UserMailer.welcome(user).deliver_later
```

El método de entrega convierte cada mensaje en una petición a la API, con `from`, `to`, `cc`, `bcc`, `reply_to`, el asunto, las partes HTML y de texto, y los adjuntos.

## Llamar directamente a la API

Para las funciones que Action Mailer no contempla, como las plantillas guardadas o los envíos programados, usa el cliente:

```ruby
client = Emailit::EmailitClient.new(Rails.application.credentials.dig(:emailit, :api_key))

email = client.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_…"
```

Los errores se lanzan como excepciones tipadas: `Emailit::AuthenticationError` (401), `Emailit::RateLimitError` (429), `Emailit::UnprocessableEntityError` (422) y `Emailit::ApiError` para todo lo demás.

## Enviar por SMTP

Para usar SMTP sin más, configura la entrega SMTP de Action Mailer:

```ruby title="config/environments/production.rb"
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  address: "smtp.emailit.com",
  port: 587,
  user_name: "emailit",
  password: Rails.application.credentials.dig(:emailit, :api_key),
  authentication: :plain,
  enable_starttls_auto: true
}
```

Los mailers y `deliver_later` funcionan igual. Si tu proveedor de hosting bloquea el puerto 587, usa el 2525 o el 2587. Consulta [Configuración SMTP](/es/docs/smtp/settings/).

## Recibir webhooks

[Crea un webhook](/es/docs/webhooks/set-up/) que apunte a `https://your-app.com/webhooks/emailit`. Añade una ruta y un controlador que verifique la firma con el cuerpo en bruto:

```ruby title="config/routes.rb"
post "/webhooks/emailit", to: "emailit_webhooks#create"
```

```ruby title="app/controllers/emailit_webhooks_controller.rb"
class EmailitWebhooksController < ActionController::API
  def create
    payload = request.raw_post
    signature = request.headers["X-Emailit-Signature"].to_s
    timestamp = request.headers["X-Emailit-Timestamp"].to_s

    return head :unauthorized unless valid_signature?(payload, signature, timestamp)

    # The body is a JSON array of up to 100 events.
    JSON.parse(payload).each do |event|
      case event["type"]
      when "email.bounced", "email.complained"
        address = event.dig("data", "object", "to")
        # Stop emailing this address.
      end
    end

    head :ok
  end

  private

  def valid_signature?(payload, signature, timestamp)
    return false if signature.empty? || timestamp.empty?
    return false if (Time.now.to_i - timestamp.to_i).abs > 300

    secret = Rails.application.credentials.dig(:emailit, :webhook_secret)
    expected = OpenSSL::HMAC.hexdigest("SHA256", secret, "#{timestamp}.#{payload}")
    ActiveSupport::SecurityUtils.secure_compare(expected, signature)
  end
end
```

Al heredar de `ActionController::API` se omite la protección CSRF, que Emailit no puede satisfacer. Devuelve un `2xx` en menos de 30 segundos y pasa el trabajo lento a Active Job. Consulta [Firma de las peticiones](/es/docs/webhooks/request-signature/).

## Consejos para producción

- **Entrega más tarde.** Usa `deliver_later` para que las peticiones web no esperen al email, y limita el ritmo de los jobs masivos para no superar tus [límites de envío](/es/docs/limits/) (2 emails por segundo por defecto).
- **Mantén el desarrollo seguro.** En desarrollo, usa `:letter_opener`, `:test` o una clave de preproducción aparte para no enviar emails a usuarios reales por accidente.
- **Elimina los webhooks duplicados.** Guarda cada `event_id` que procesas; las entregas fallidas se reintentan y pueden llegar más de una vez.
- **Rota las claves sin interrupciones** desplegando una clave nueva antes de eliminar la antigua. Consulta [Claves de API](/es/docs/developers/api-keys/).

## Próximos pasos

  - [Enviar emails con la API](/es/docs/email-api/send-email/): Adjuntos, programación y seguimiento.
  - [Plantillas](/es/docs/templates/): Diseña emails en Emailit y envíalos por su alias.
  - [Tipos de eventos de webhook](/es/docs/webhooks/event-types/): Todos los eventos y su payload.
  - [Solución de problemas de SMTP](/es/docs/smtp/troubleshooting/): Corrige los errores de autenticación y de conexión.

---
Fuente: https://emailit.com/es/docs/frameworks/rails/
