Send email with Ruby on Rails
A service object called from a background job, with the key in credentials.
You need a verified sending domain and an API key from Settings › API Keys. If neither exists yet, the quickstart covers both in a couple of minutes.
Send
require "net/http"
require "json"
class WelcomeEmail
ENDPOINT = URI("https://sending.dev/api/v1/emails")
def self.deliver(user)
request = Net::HTTP::Post.new(ENDPOINT)
request["Authorization"] = "Bearer #{Rails.application.credentials.sending_api_key}"
request["Content-Type"] = "application/json"
request.body = {
from: "Acme <[email protected]>",
to: user.email,
subject: "Welcome",
html: "<p>You're in.</p>",
idempotencyKey: "welcome-#{user.id}"
}.to_json
Net::HTTP.start(ENDPOINT.host, ENDPOINT.port, use_ssl: true) do |http|
http.request(request)
end
end
endA successful call answers 202 with the message id: accepted and queued, not yet delivered. Delivery, opens, bounces and complaints arrive later, on webhooks or in the dashboard.
What changes in Ruby on Rails
Call it from an ActiveJob, not from the controller. Rails credentials keep the key encrypted in the repository, which is the one place a key can safely live in version control.
The thing that catches people
ActionMailer is not in this path: previews, deliver_later and the test adapter do not apply. If you want both, keep transactional email here and leave ActionMailer for internal mail.
Next
- All the fields: cc and bcc, reply-to, attachments, templates, scheduling.
- Webhooks: delivery, bounce and complaint events, signed with HMAC.
- Domains: SPF, DKIM and MAIL FROM, and why sending is refused until they are in place.
- MCP: the same operations as tools, when the one writing the code is an agent.