Aller au contenu
Docs

Tutoriel

Envoyer des e-mails avec Ruby on Rails

Livrez les e-mails d’Action Mailer via Emailit avec la gem emailit ou les paramètres SMTP, appelez l’API directement et vérifiez les webhooks Emailit dans Rails.

Mis à jour le 1 oct. 2026

Ce guide montre comment envoyer les e-mails de Rails via Emailit. Vous pouvez utiliser la méthode de livraison Action Mailer de la gem emailit, qui envoie via l’API, ou faire pointer les paramètres SMTP d’Action Mailer vers le relais Emailit. Il explique aussi comment appeler l’API directement et vérifier les webhooks.

Prérequis

  • Ruby 3.0 ou version ultérieure et une application Rails.
  • Un domaine d’envoi vérifié, par exemple acme.com.
  • Une clé API. Une clé Sending Only limitée à votre domaine suffit.
  • Tant que votre espace de travail n’a pas l’accès production, vous ne pouvez envoyer qu’aux adresses e-mail des comptes des membres de l’espace de travail.

Installer la gem

Terminal
bundle add emailit

La gem n’a aucune dépendance d’exécution en dehors de la bibliothèque standard de Ruby.

Configurer votre clé API

Stockez la clé dans votre environnement ou dans les credentials Rails :

Terminal
bin/rails credentials:edit
YAML
emailit:
  api_key: secret_••••••••••••••••••••••••••••••••
  webhook_secret: whsec_••••••••

Les exemples ci-dessous lisent Rails.application.credentials.dig(:emailit, :api_key). Si vous utilisez des variables d’environnement, lisez plutôt ENV.fetch("EMAILIT_API_KEY").

Envoyer avec Action Mailer

Quand la gem détecte Rails, elle enregistre une méthode de livraison :emailit. Activez-la par environnement :

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

Vos mailers ne changent pas. L’adresse from doit appartenir à un domaine d’envoi vérifié :

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

La méthode de livraison convertit chaque message en requête API, avec from, to, cc, bcc, reply_to, l’objet, les parties HTML et texte, et les pièces jointes.

Appeler l’API directement

Pour les fonctionnalités qu’Action Mailer ne prend pas en charge, comme les modèles enregistrés ou les envois programmés, utilisez le client :

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

Les erreurs sont levées sous forme d’exceptions typées : Emailit::AuthenticationError (401), Emailit::RateLimitError (429), Emailit::UnprocessableEntityError (422) et Emailit::ApiError pour tout le reste.

Envoyer plutôt via SMTP

Pour utiliser le SMTP simple, configurez la livraison SMTP d’Action Mailer :

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
}

Les mailers et deliver_later fonctionnent de la même façon. Si votre hébergeur bloque le port 587, utilisez 2525 ou 2587. Consultez Paramètres SMTP.

Recevoir des webhooks

Créez un webhook qui pointe vers https://your-app.com/webhooks/emailit. Ajoutez une route et un contrôleur qui vérifie la signature à partir du corps brut :

config/routes.rb
post "/webhooks/emailit", to: "emailit_webhooks#create"
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

Hériter de ActionController::API désactive la protection CSRF, qu’Emailit ne peut pas satisfaire. Renvoyez un 2xx dans les 30 secondes et déplacez les traitements lents dans Active Job. Consultez Signature des requêtes.

Conseils pour la production

  • Livrez en différé. Utilisez deliver_later pour que les requêtes web n’attendent pas l’envoi, et limitez le débit des jobs d’envoi en masse pour rester sous vos limites d’envoi (2 e-mails par seconde par défaut).
  • Sécurisez le développement. Utilisez :letter_opener, :test ou une clé de préproduction distincte en développement pour ne pas envoyer d’e-mails à de vrais utilisateurs par accident.
  • Dédoublonnez les webhooks. Enregistrez chaque event_id traité : Emailit réessaie les livraisons en échec, qui peuvent donc arriver plusieurs fois.
  • Effectuez la rotation des clés sans interruption de service en déployant une nouvelle clé avant de supprimer l’ancienne. Consultez Clés API.

Étapes suivantes

Pièces jointes, programmation et suivi.
Concevez vos e-mails dans Emailit et envoyez-les par alias.
Tous les événements et leur payload.
Corrigez les erreurs d’authentification et de connexion.

Cette page vous a-t-elle été utile ?

Merci pour votre retour.

Merci, nous lisons chaque message.