Tutoriál
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, například
acme.com. - API klíč. Stačí klíč jen pro odesílání omezený na vaši doménu.
- Dokud váš workspace nemá produkční přístup, můžete odesílat jen na e-mailové adresy účtů členů workspace.
Nainstalujte gem
bundle add emailitGem 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:
bin/rails credentials:editemailit:
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í:
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ě:
class UserMailer < ApplicationMailer
default from: "Acme <hello@acme.com>"
def welcome(user)
@user = user
mail(to: @user.email, subject: "Welcome to Acme")
end
endUserMailer.welcome(user).deliver_laterMetoda 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:
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:
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.
Přijímejte webhooky
Vytvořte webhook, 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:
post "/webhooks/emailit", to: "emailit_webhooks#create"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
endDě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ů.
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í (ve výchozím stavu 2 e-maily za sekundu). - Vývoj udržujte bezpečný. Při vývoji použijte
:letter_opener,:testnebo 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.