Elegant Ruby SDK with idiomatic patterns, Rails integration, and comprehensive testing support.
# Add to Gemfile
gem 'sparkmailr'
# Or install directly
gem install sparkmailr
# Then run
bundle install
require 'sparkmailr'
# Initialize client
client = SparkMailr::Client.new(
api_key: 'your-api-key'
)
begin
# Send email
response = client.emails.send(
to: ['user@example.com'],
from: 'noreply@yourapp.com',
subject: 'Welcome to SparkMailr!',
html: '<h1>Hello World</h1>',
text: 'Hello World'
)
puts "Email sent: #{response.id}"
rescue SparkMailr::Error => e
puts "Error: #{e.message}"
end
require 'sparkmailr'
# Full configuration
client = SparkMailr::Client.new(
api_key: 'your-api-key',
base_url: 'https://api.sparkmailr.com', # Optional
timeout: 30, # Request timeout in seconds
max_retries: 3, # Max retry attempts
retry_delay: 1.0, # Delay between retries
debug: false # Enable debug logging
)
# Environment-based configuration
client = SparkMailr::Client.new(
api_key: ENV['SPARKMAILR_API_KEY'],
debug: ENV['DEBUG'] == 'true'
)
# config/initializers/sparkmailr.rb
SparkMailr.configure do |config|
config.api_key = Rails.application.credentials.sparkmailr_api_key
config.base_url = 'https://api.sparkmailr.com'
config.timeout = 30
config.debug = Rails.env.development?
end
# app/mailers/user_mailer.rb
class UserMailer < ApplicationMailer
def welcome_email(user)
sparkmailr_client = SparkMailr::Client.new
response = sparkmailr_client.emails.send(
to: [user.email],
from: 'noreply@yourapp.com',
template_id: 'welcome-template',
template_data: {
name: user.name,
activation_url: activate_user_url(user)
}
)
Rails.logger.info "Welcome email sent: #{response.id}"
response
end
def password_reset(user, token)
SparkMailr::Client.new.emails.send(
to: [user.email],
from: 'noreply@yourapp.com',
subject: 'Password Reset Request',
html: render_to_string(
template: 'user_mailer/password_reset',
locals: { user: user, token: token }
)
)
end
end
# app/jobs/send_email_job.rb
class SendEmailJob < ApplicationJob
queue_as :emails
def perform(user_id, template_id, template_data = {})
user = User.find(user_id)
client = SparkMailr::Client.new
response = client.emails.send(
to: [user.email],
from: 'noreply@yourapp.com',
template_id: template_id,
template_data: template_data.merge(
name: user.name,
email: user.email
)
)
# Log the email ID for tracking
Rails.logger.info "Email job completed: #{response.id}"
rescue SparkMailr::Error => e
Rails.logger.error "Email job failed: #{e.message}"
raise e
end
end
# Usage in controller
class UsersController < ApplicationController
def create
@user = User.new(user_params)
if @user.save
# Send welcome email in background
SendEmailJob.perform_later(
@user.id,
'welcome-template',
{ signup_date: Date.current.to_s }
)
redirect_to @user, notice: 'User created successfully!'
else
render :new
end
end
end
# Send email with template
response = client.emails.send(
to: ['user@example.com'],
from: 'noreply@yourapp.com',
template_id: 'welcome-template',
template_data: {
name: 'John Doe',
activation_link: 'https://app.example.com/activate/123',
features: ['Feature 1', 'Feature 2', 'Feature 3'],
user: {
first_name: 'John',
last_name: 'Doe',
plan: 'premium'
}
}
)
puts "Template email sent: #{response.id}"
# Send bulk emails with Ruby arrays
users = [
{ email: 'user1@example.com', name: 'User 1', code: 'ABC123' },
{ email: 'user2@example.com', name: 'User 2', code: 'DEF456' },
{ email: 'user3@example.com', name: 'User 3', code: 'GHI789' }
]
recipients = users.map do |user|
{
to: user[:email],
template_data: {
name: user[:name],
promo_code: user[:code]
}
}
end
response = client.emails.send_bulk(
from: 'newsletter@yourapp.com',
template_id: 'newsletter-template',
recipients: recipients
)
puts "Bulk batch: #{response.batch_id}"
# Get email status
email_id = 'em_1234567890'
status = client.emails.get_status(email_id)
puts "Status: #{status.status}"
puts "Delivered: #{status.delivered_at}"
puts "Opened: #{status.opened_at}" if status.opened_at
# Get analytics with date range
analytics = client.analytics.get_email_stats(
start_date: '2025-01-01',
end_date: '2025-01-31'
)
puts "Total sent: #{analytics.sent}"
puts "Delivery rate: #{analytics.delivery_rate}%"
puts "Open rate: #{analytics.open_rate}%"
puts "Click rate: #{analytics.click_rate}%"
# Get detailed analytics
detailed = client.analytics.get_detailed_stats(
start_date: Date.current.beginning_of_month,
end_date: Date.current.end_of_month,
group_by: 'day'
)
detailed.each do |day_stats|
puts "#{day_stats.date}: #{day_stats.sent} sent, #{day_stats.delivered} delivered"
end
require 'sparkmailr'
client = SparkMailr::Client.new(api_key: 'your-api-key')
begin
response = client.emails.send(
to: ['invalid-email'],
from: 'noreply@yourapp.com',
subject: 'Test Email'
)
rescue SparkMailr::AuthenticationError => e
puts "Authentication failed: #{e.message}"
rescue SparkMailr::RateLimitError => e
puts "Rate limited. Retry after: #{e.retry_after} seconds"
# Implement exponential backoff
sleep(e.retry_after)
retry
rescue SparkMailr::ValidationError => e
puts "Validation failed:"
e.validation_errors.each do |field, errors|
puts " #{field}: #{errors.join(', ')}"
end
rescue SparkMailr::NetworkError => e
puts "Network error: #{e.message}"
# Retry logic for network issues
rescue SparkMailr::Error => e
puts "SparkMailr error: #{e.message}"
rescue StandardError => e
puts "Unexpected error: #{e.message}"
end
require 'sinatra'
require 'sparkmailr'
require 'json'
# Configure SparkMailr
configure do
set :sparkmailr, SparkMailr::Client.new(
api_key: ENV['SPARKMAILR_API_KEY']
)
end
# Contact form endpoint
post '/contact' do
content_type :json
begin
data = JSON.parse(request.body.read)
response = settings.sparkmailr.emails.send(
to: ['admin@yourapp.com'],
from: 'noreply@yourapp.com',
subject: 'New Contact Form Submission',
html: "<h2>Contact Form</h2>
<p><strong>Name:</strong> #{data['name']}</p>
<p><strong>Email:</strong> #{data['email']}</p>
<p><strong>Message:</strong></p>
<p>#{data['message']}</p>"
)
{ success: true, email_id: response.id }.to_json
rescue => e
status 500
{ success: false, error: e.message }.to_json
end
end
# Newsletter signup
post '/newsletter/subscribe' do
content_type :json
email = params[:email]
response = settings.sparkmailr.emails.send(
to: [email],
from: 'newsletter@yourapp.com',
template_id: 'newsletter-welcome',
template_data: {
email: email,
unsubscribe_url: "#{request.base_url}/unsubscribe?email=#{email}"
}
)
{ subscribed: true, email_id: response.id }.to_json
end
# spec/spec_helper.rb
require 'webmock/rspec'
require 'sparkmailr'
RSpec.configure do |config|
config.before(:each) do
WebMock.reset!
end
end
# spec/sparkmailr_spec.rb
RSpec.describe SparkMailr::Client do
let(:client) { SparkMailr::Client.new(api_key: 'test-key') }
describe '#send_email' do
it 'sends email successfully' do
# Stub HTTP request
stub_request(:post, 'https://api.sparkmailr.com/v1/emails/send')
.with(
body: hash_including(
to: ['test@example.com'],
from: 'noreply@test.com'
)
)
.to_return(
status: 200,
body: {
id: 'em_123456',
status: 'queued'
}.to_json,
headers: { 'Content-Type' => 'application/json' }
)
response = client.emails.send(
to: ['test@example.com'],
from: 'noreply@test.com',
subject: 'Test Email',
html: '<p>Test content</p>'
)
expect(response.id).to eq('em_123456')
expect(response.status).to eq('queued')
end
it 'handles rate limit errors' do
stub_request(:post, 'https://api.sparkmailr.com/v1/emails/send')
.to_return(
status: 429,
body: {
error: 'Rate limit exceeded',
retry_after: 60
}.to_json
)
expect {
client.emails.send(
to: ['test@example.com'],
from: 'noreply@test.com',
subject: 'Test'
)
}.to raise_error(SparkMailr::RateLimitError) do |error|
expect(error.retry_after).to eq(60)
end
end
end
end
# spec/mailers/user_mailer_spec.rb
RSpec.describe UserMailer do
let(:user) { create(:user, email: 'test@example.com', name: 'Test User') }
before do
stub_request(:post, 'https://api.sparkmailr.com/v1/emails/send')
.to_return(
status: 200,
body: { id: 'em_test123', status: 'queued' }.to_json
)
end
describe '#welcome_email' do
it 'sends welcome email with correct parameters' do
UserMailer.welcome_email(user)
expect(WebMock).to have_requested(:post, 'https://api.sparkmailr.com/v1/emails/send')
.with(
body: hash_including(
to: ['test@example.com'],
template_id: 'welcome-template',
template_data: hash_including(name: 'Test User')
)
)
end
end
end