Ruby SDK

Elegant Ruby SDK with idiomatic patterns, Rails integration, and comprehensive testing support.

✅ Ready v1.0.0 RubyGems

Quick Start

Installation

# Add to Gemfile
gem 'sparkmailr'

# Or install directly
gem install sparkmailr

# Then run
bundle install

Basic Usage

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

Configuration

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'
)

Rails Integration

Initializer Setup

# 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

Mailer Integration

# 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

Background Jobs with Sidekiq

# 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

Advanced Features

Template Emails

# 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}"

Bulk Email Sending

# 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}"

Email Tracking & Analytics

# 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

Error Handling

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

Sinatra Integration

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

Testing with RSpec

# 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

Need More Help?

Complete Documentation RubyGems Contact Support