# Odesílání e-mailů z Ruby on Rails

> Doručujte e-maily z Action Maileru přes Emailit pomocí gemu emailit nebo nastavení SMTP, volejte API přímo a ověřujte webhooky Emailitu v Rails.

Tento návod ukazuje, jak odesílat poštu z Rails přes Emailit. Můžete použít metodu doručování Action Maileru z gemu `emailit`, která odesílá přes API, nebo nasměrovat nastavení SMTP v Action Maileru na SMTP relay Emailitu. Popisuje také přímé volání API a ověřování webhooků.

## Předpoklady

- Ruby 3.0 nebo novější a aplikace v Rails.
- [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.

## Nainstalujte gem

```bash
bundle add emailit
```

Gem nemá za běhu kromě standardní knihovny Ruby žádné závislosti.

## Nastavte API klíč

Uložte klíč do proměnných prostředí nebo do Rails credentials:

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

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

Příklady níže čtou `Rails.application.credentials.dig(:emailit, :api_key)`. Pokud používáte proměnné prostředí, čtěte místo toho `ENV.fetch("EMAILIT_API_KEY")`.

## Odesílejte přes Action Mailer

Když gem zjistí, že běží v Rails, zaregistruje metodu doručování `:emailit`. Zapněte ji pro jednotlivá prostředí:

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

Vaše mailery se nemění. Adresa `from` musí být na ověřené odesílací doméně:

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

Metoda doručování převede každou zprávu na požadavek na API, včetně `from`, `to`, `cc`, `bcc`, `reply_to`, předmětu, částí HTML a prostého textu a příloh.

## Volejte API přímo

Pro funkce, které Action Mailer nepokrývá, například uložené šablony nebo plánované odesílání, použijte klienta:

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

Chyby se vyhazují jako typované výjimky: `Emailit::AuthenticationError` (401), `Emailit::RateLimitError` (429), `Emailit::UnprocessableEntityError` (422) a `Emailit::ApiError` pro všechno ostatní.

## Odesílání přes SMTP

Pokud chcete použít obyčejné SMTP, nastavte doručování přes SMTP v Action Maileru:

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

Mailery i `deliver_later` fungují stejně. Pokud váš hosting blokuje port 587, použijte 2525 nebo 2587. Viz [Nastavení SMTP](/cs/docs/smtp/settings/).

## Přijímejte webhooky

[Vytvořte webhook](/cs/docs/webhooks/set-up/), který míří na `https://your-app.com/webhooks/emailit`. Přidejte routu a controller, který ověří podpis vůči surovému tělu požadavku:

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

Dědění z `ActionController::API` přeskočí ochranu CSRF, kterou Emailit nemůže splnit. Do 30 sekund vraťte `2xx` a pomalou práci přesuňte do Active Job. Viz [Ověření podpisu webhooků](/cs/docs/webhooks/request-signature/).

## Tipy pro produkční provoz

- **Doručujte později.** Použijte `deliver_later`, aby webové požadavky nečekaly na e-mail, a hromadné úlohy zpomalte, abyste zůstali pod svými [limity odesílání](/cs/docs/limits/) (ve výchozím stavu 2 e-maily za sekundu).
- **Vývoj udržujte bezpečný.** Při vývoji použijte `:letter_opener`, `:test` nebo samostatný klíč pro staging, abyste omylem neposlali e-mail skutečným uživatelům.
- **Odstraňujte duplicitní webhooky.** Ukládejte si každé zpracované `event_id`; neúspěšná doručení se opakují a mohou dorazit víckrát.
- **Vyměňujte klíče bez výpadku** tak, že nový klíč nasadíte dřív, než starý smažete. Viz [API klíče](/cs/docs/developers/api-keys/).

## Další kroky

  - [Odesílání e-mailů přes API](/cs/docs/email-api/send-email/): Přílohy, plánování a měření.
  - [Š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/rails/
