Tutorial
E-Mails mit Ruby on Rails senden
Stellen Sie E-Mails von Action Mailer über Emailit zu, mit dem Gem emailit oder SMTP-Einstellungen, rufen Sie die API direkt auf und verifizieren Sie Emailit-Webhooks in Rails.
Diese Anleitung zeigt, wie Sie Rails-E-Mails über Emailit senden. Sie können die Action-Mailer-Zustellmethode des Gems emailit verwenden, die über die API sendet, oder die SMTP-Einstellungen von Action Mailer auf das Emailit-Relay ausrichten. Außerdem behandelt sie den direkten Aufruf der API und die Verifizierung von Webhooks.
Voraussetzungen
- Ruby 3.0 oder neuer und eine Rails-App.
- Eine verifizierte Versanddomain, zum Beispiel
acme.com. - Ein API-Schlüssel. Ein reiner Sende-Schlüssel, der auf Ihre Domain beschränkt ist, genügt.
- Solange Ihr Workspace keinen Produktionszugang hat, können Sie nur an die Konto-E-Mail-Adressen von Workspace-Mitgliedern senden.
Gem installieren
bundle add emailitDas Gem hat zur Laufzeit keine Abhängigkeiten außer der Ruby-Standardbibliothek.
API-Schlüssel konfigurieren
Speichern Sie den Schlüssel in Ihrer Umgebung oder in den Rails Credentials:
bin/rails credentials:editemailit:
api_key: secret_••••••••••••••••••••••••••••••••
webhook_secret: whsec_••••••••Die folgenden Beispiele lesen Rails.application.credentials.dig(:emailit, :api_key). Wenn Sie Umgebungsvariablen verwenden, lesen Sie stattdessen ENV.fetch("EMAILIT_API_KEY").
Mit Action Mailer senden
Wenn das Gem Rails erkennt, registriert es die Zustellmethode :emailit. Aktivieren Sie sie pro Umgebung:
config.action_mailer.delivery_method = :emailit
config.action_mailer.emailit_settings = {
api_key: Rails.application.credentials.dig(:emailit, :api_key)
}Ihre Mailer ändern sich nicht. Die Adresse in from muss zu einer verifizierten Versanddomain gehören:
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_laterDie Zustellmethode wandelt jede Nachricht in eine API-Anfrage um, einschließlich from, to, cc, bcc, reply_to, Betreff, HTML- und Textteilen sowie Anhängen.
API direkt aufrufen
Für Funktionen, die Action Mailer nicht abbildet, etwa gespeicherte Vorlagen oder geplante Versände, verwenden Sie den Client:
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_…"Fehler werden als typisierte Exceptions ausgelöst: Emailit::AuthenticationError (401), Emailit::RateLimitError (429), Emailit::UnprocessableEntityError (422) und Emailit::ApiError für alles andere.
Alternativ per SMTP senden
Um einfaches SMTP zu verwenden, konfigurieren Sie die SMTP-Zustellung von Action Mailer:
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
}Mailer und deliver_later funktionieren genauso. Wenn Ihr Hoster Port 587 blockiert, verwenden Sie 2525 oder 2587. Siehe SMTP-Einstellungen.
Webhooks empfangen
Erstellen Sie einen Webhook, der auf https://your-app.com/webhooks/emailit zeigt. Fügen Sie eine Route und einen Controller hinzu, der die Signatur anhand des unveränderten Bodys verifiziert:
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
endDurch das Erben von ActionController::API entfällt der CSRF-Schutz, den Emailit nicht erfüllen kann. Geben Sie innerhalb von 30 Sekunden einen 2xx-Status zurück und verlagern Sie langsame Arbeit in Active Job. Siehe Anfragesignatur.
Tipps für den Produktivbetrieb
- Später zustellen. Verwenden Sie
deliver_later, damit Webanfragen nicht auf E-Mails warten, und drosseln Sie Massen-Jobs, um unter Ihren Versandlimits zu bleiben (standardmäßig 2 E-Mails pro Sekunde). - Entwicklung absichern. Verwenden Sie in der Entwicklung
:letter_opener,:testoder einen separaten Staging-Schlüssel, damit Sie nicht versehentlich echten Nutzern E-Mails senden. - Webhooks deduplizieren. Speichern Sie jede verarbeitete
event_id; fehlgeschlagene Zustellungen werden wiederholt und können mehrfach ankommen. - Schlüssel ohne Ausfallzeit rotieren, indem Sie einen neuen Schlüssel bereitstellen, bevor Sie den alten löschen. Siehe API-Schlüssel.