Ruby SDK
Ruby 3.0+
Bundler
Send emails with Ruby using the official Laneful Ruby SDK. Built for modern Ruby applications with comprehensive features and type safety.
Full Feature Support
Templates, attachments, tracking, webhooks
Modern Ruby
Ruby 3.0+ with modern syntax
Easy Integration
Simple API with comprehensive examples
On this page
Prerequisites
To get the most out of this guide, you'll need:
- • Ruby 3.0 or higher
- • Bundler (for dependency management)
- • A Laneful account with API key
- • Verified domain for sending emails
Installation
Bundler
Add the following to your Gemfile
:
gem 'laneful-ruby'
Then run:
bundle install
Quick Start
Send your first email in minutes:
Send Simple Text Email
require 'laneful' # Create client client = Laneful::Client.new( 'https://your-endpoint.send.laneful.net', 'your-auth-token' ) # Create email email = Laneful::Email::Builder.new .from(Laneful::Address.new('sender@example.com', 'Your Name')) .to(Laneful::Address.new('recipient@example.com', 'Recipient Name')) .subject('Hello from Laneful!') .text_content('This is a simple test email sent using the Laneful Ruby SDK.') .build # Send email begin response = client.send_email(email) puts "✓ Email sent successfully!" puts "Response: #{response}" rescue Laneful::ValidationException => e puts "✗ Validation error: #{e.message}" rescue Laneful::ApiException => e puts "✗ API error: #{e.message}" puts "Status code: #{e.status_code}" rescue Laneful::HttpException => e puts "✗ HTTP error: #{e.message}" rescue StandardError => e puts "✗ Unexpected error: #{e.message}" end
Examples
Common use cases and patterns:
HTML Email with Tracking
# Create tracking settings tracking = Laneful::TrackingSettings.new( opens: true, clicks: true, unsubscribes: false ) email = Laneful::Email::Builder.new .from(Laneful::Address.new('sender@example.com')) .to(Laneful::Address.new('user@example.com')) .subject('HTML Email with Tracking') .html_content('<h1>Welcome!</h1><p>This is an <strong>HTML email</strong> with tracking enabled.</p>') .text_content('Welcome! This is an HTML email with tracking enabled.') .tracking(tracking) .tag('welcome-email') .build response = client.send_email(email)
Template Email
email = Laneful::Email::Builder.new .from(Laneful::Address.new('sender@example.com')) .to(Laneful::Address.new('user@example.com')) .template_id('welcome-template') .template_data({ 'name' => 'John Doe', 'company' => 'Acme Corporation', 'activation_link' => 'https://example.com/activate' }) .build response = client.send_email(email)
Email with Attachments
# Create attachment from file attachment = Laneful::Attachment.from_file('/path/to/document.pdf') email = Laneful::Email::Builder.new .from(Laneful::Address.new('sender@example.com')) .to(Laneful::Address.new('user@example.com')) .subject('Document Attached') .text_content('Please find the document attached.') .attachment(attachment) .build response = client.send_email(email)
Multiple Recipients with Reply-To
email = Laneful::Email::Builder.new .from(Laneful::Address.new('sender@example.com', 'Your Name')) .to(Laneful::Address.new('user1@example.com', 'User One')) .to(Laneful::Address.new('user2@example.com', 'User Two')) .cc(Laneful::Address.new('cc@example.com', 'CC Recipient')) .bcc(Laneful::Address.new('bcc@example.com', 'BCC Recipient')) .reply_to(Laneful::Address.new('reply@example.com', 'Reply To')) .subject('Email to Multiple Recipients') .text_content('This email is being sent to multiple recipients.') .build response = client.send_email(email)
Scheduled Email
# Schedule for 24 hours from now send_time = Time.now.to_i + (24 * 60 * 60) email = Laneful::Email::Builder.new .from(Laneful::Address.new('sender@example.com')) .to(Laneful::Address.new('user@example.com')) .subject('Scheduled Email') .text_content('This email was scheduled.') .send_time(send_time) .build response = client.send_email(email)
Batch Email Sending
emails = [ Laneful::Email::Builder.new .from(Laneful::Address.new('sender@example.com')) .to(Laneful::Address.new('user1@example.com')) .subject('Email 1') .text_content('First email content.') .build, Laneful::Email::Builder.new .from(Laneful::Address.new('sender@example.com')) .to(Laneful::Address.new('user2@example.com')) .subject('Email 2') .text_content('Second email content.') .build ] response = client.send_emails(emails)
Webhook Handler Example
require 'sinatra' require 'json' require 'laneful' # Complete webhook handler implementation class WebhookController def initialize(webhook_secret) @webhook_secret = webhook_secret end def handle_webhook(request) begin # Extract signature from headers signature = Laneful::WebhookVerifier.extract_signature_from_headers(request.env) if signature.nil? return [401, { 'Content-Type' => 'application/json' }, { error: 'Missing signature' }.to_json] end # Get raw payload payload = request.body.read # Verify signature unless Laneful::WebhookVerifier.verify_signature(@webhook_secret, payload, signature) return [401, { 'Content-Type' => 'application/json' }, { error: 'Invalid signature' }.to_json] end # Parse and validate payload webhook_data = Laneful::WebhookVerifier.parse_webhook_payload(payload) # Process events webhook_data[:events].each do |event| event_type = event['event'] email = event['email'] case event_type when 'delivery' puts "Email delivered to: #{email}" when 'open' puts "Email opened by: #{email}" when 'click' url = event['url'] || 'Unknown URL' puts "Link clicked by #{email}: #{url}" when 'bounce' is_hard = event['is_hard'] || false puts "Email bounced (#{is_hard ? 'hard' : 'soft'}) for: #{email}" end end [200, { 'Content-Type' => 'application/json' }, { status: 'success' }.to_json] rescue ArgumentError => e [400, { 'Content-Type' => 'application/json' }, { error: "Invalid payload: #{e.message}" }.to_json] rescue StandardError => e [500, { 'Content-Type' => 'application/json' }, { error: "Processing error: #{e.message}" }.to_json] end end end
API Reference
Laneful::Client
Constructor
- •
Laneful::Client.new(base_url, auth_token, timeout: 30)
- Create a new client instance
Methods
- •
send_email(email)
- Send a single email - •
send_emails(emails)
- Send multiple emails
Laneful::Email::Builder
Required Fields
- •
from(address)
- Sender address
Optional Fields
- •
to(address)
- Recipient addresses - •
cc(address)
- CC addresses - •
bcc(address)
- BCC addresses - •
subject(subject)
- Email subject - •
text_content(content)
- Plain text content - •
html_content(content)
- HTML content - •
template_id(id)
- Template ID - •
template_data(data)
- Template data - •
attachment(attachment)
- File attachments - •
headers(headers)
- Custom headers - •
reply_to(address)
- Reply-to address - •
send_time(time)
- Scheduled send time (Unix timestamp) - •
webhook_data(data)
- Webhook data - •
tag(tag)
- Email tag for categorization - •
tracking(tracking)
- Tracking settings
Utility Classes
- •
Laneful::Address.new(email, name = nil)
- Email address with optional name - •
Laneful::Attachment.from_file(file_path)
- Create attachment from file - •
Laneful::Attachment.new(filename, content_type, content)
- Create attachment from raw data - •
Laneful::TrackingSettings.new(opens: false, clicks: false, unsubscribes: false)
- Email tracking configuration
Laneful::WebhookVerifier
Signature Verification
- •
verify_signature(secret, payload, signature)
- Verifies webhook signature (supports sha256= prefix) - •
generate_signature(secret, payload, include_prefix: false)
- Generates signature for payload
Payload Processing
- •
parse_webhook_payload(payload)
- Parse and validate webhook payload structure - •
signature_header_name
- Get the correct header name for webhook signatures - •
extract_signature_from_headers(headers)
- Extract signature from HTTP headers
WebhookData
- •
is_batch
- Returns true if payload contains multiple events - •
events
- Returns array of parsed events
Error Handling
Comprehensive error handling with specific exception types:
begin response = client.send_email(email) puts "✓ Email sent successfully!" puts "Response: #{response}" rescue Laneful::ValidationException => e # Invalid input data puts "✗ Validation error: #{e.message}" puts "Please check your email configuration" rescue Laneful::ApiException => e # API returned an error puts "✗ API error: #{e.message}" puts " Status code: #{e.status_code}" puts " Error message: #{e.error_message}" puts "Please check your API credentials and endpoint" rescue Laneful::HttpException => e # Network or HTTP-level error puts "✗ HTTP error: #{e.message}" puts " Status code: #{e.status_code}" puts "Please check your network connection and endpoint URL" rescue StandardError => e # Other unexpected errors puts "✗ Unexpected error: #{e.message}" puts e.backtrace end
Exception Types
- •
Laneful::ValidationException
- Input validation fails - •
Laneful::ApiException
- API returns error response
Methods: status_code, error_message - •
Laneful::HttpException
- HTTP communication fails
Methods: status_code - •
Laneful::LanefulException
- Base exception class
Best Practices
- • Always wrap API calls in begin-rescue
- • Handle specific exception types first
- • Log errors with context information
- • Implement retry logic for transient failures
Webhook Handling
Comprehensive webhook handling with signature verification, payload parsing, and validation:
Basic Signature Verification
# In your webhook handler payload = request.body.read signature = request.headers['x-webhook-signature'] secret = 'your-webhook-secret' if Laneful::WebhookVerifier.verify_signature(secret, payload, signature) # Process webhook data webhook_data = Laneful::WebhookVerifier.parse_webhook_payload(payload) # Handle webhook events else # Invalid signature head :unauthorized end
Advanced Webhook Processing
# Complete webhook verification and processing workflow begin # Step 1: Get raw payload payload = request.body.read # Step 2: Extract signature from headers (supports multiple formats) signature = Laneful::WebhookVerifier.extract_signature_from_headers(request.env) # Step 3: Verify signature (supports sha256= prefix) unless signature && Laneful::WebhookVerifier.verify_signature(webhook_secret, payload, signature) raise StandardError, "Invalid webhook signature" end # Step 4: Parse and validate payload structure webhook_data = Laneful::WebhookVerifier.parse_webhook_payload(payload) # Step 5: Process events (handles both batch and single event formats) webhook_data[:events].each do |event| event_type = event['event'] email = event['email'] case event_type when 'delivery' handle_delivery_event(event) when 'open' handle_open_event(event) when 'click' handle_click_event(event) when 'bounce' handle_bounce_event(event) when 'drop' handle_drop_event(event) when 'spam_complaint' handle_spam_complaint_event(event) when 'unsubscribe' handle_unsubscribe_event(event) end end rescue ArgumentError => e # Payload validation error status 400 { error: "Invalid payload: #{e.message}" }.to_json rescue StandardError => e # Other errors status 401 { error: e.message }.to_json end
Batch Mode Support
webhook_data = Laneful::WebhookVerifier.parse_webhook_payload(payload) if webhook_data[:is_batch] # Processing multiple events in batch mode puts "Processing #{webhook_data[:events].length} events in batch" else # Processing single event puts "Processing single event" end # Process all events webhook_data[:events].each do |event| process_event(event) end
Supported Webhook Events
Delivery Events
- •
delivery
- Email delivered successfully - •
bounce
- Email bounced (hard or soft) - •
drop
- Email dropped (spam, invalid, etc.) - •
spam_complaint
- Recipient marked email as spam
Engagement Events
- •
open
- Email opened by recipient - •
click
- Link clicked in email - •
unsubscribe
- Recipient unsubscribed
Webhook Features
Security
- • HMAC-SHA256 signature verification
- • Support for
sha256=
prefix - • Constant-time comparison (timing attack protection)
- • Multiple header format support
Validation
- • JSON payload structure validation
- • Required field validation
- • Event type validation
- • Email format validation
- • UUID format validation for lane_id
Ready to Get Started?
Start sending emails with Ruby in minutes. Check out the examples and integrate with your application.