Skip to content

sidemail/sidemail-sdk-ruby

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Sidemail Ruby Library

Official Sidemail.io Ruby library providing convenient access to the Sidemail API from Ruby applications.

Requirements

  • Ruby 2.6+

Installation

Using RubyGems:

gem install sidemail

Or using Bundler:

bundle add sidemail

Usage

First, the client needs to be configured with your project's API key, which you can find in the Sidemail Dashboard after you sign up.

require "sidemail"

# Initialize with API key
sm = Sidemail.new(api_key: "your-api-key")

# Or set environment variable SIDEMAIL_API_KEY
# sm = Sidemail.new
response = sm.send_email(
  toAddress: "user@email.com",
  fromAddress: "you@example.com",
  fromName: "Your App",
  templateName: "Welcome",
  templateProps: { foo: "bar" }
)

puts "Email sent! ID: #{response.id}"

The response looks like:

{
  "id": "5e858953daf20f3aac50a3da",
  "status": "queued"
}

Shortcut sm.send_email(...) calls sm.email.send(...) under the hood.

Authentication

Explicit key:

require "sidemail"
sm = Sidemail.new(api_key: "your-api-key")

Or if you set environment variable SIDEMAIL_API_KEY, then simply:

require "sidemail"
sm = Sidemail.new # reads SIDEMAIL_API_KEY

Client configuration

require "sidemail"

sm = Sidemail.new(
  api_key: "your-api-key",
  base_url: "https://api.sidemail.io/v1", # override for testing/mocking
  timeout: 10.0,  # per-request timeout (seconds)
  http_client: custom_http_client, # custom Net::HTTP client (proxies, retries, etc.)
)

Email Sending Examples

Password reset template

sm.send_email(
  toAddress: "user@email.com",
  fromAddress: "you@example.com",
  fromName: "Your App",
  templateName: "Password reset",
  templateProps: { resetUrl: "https://your.app/reset?token=123" }
)

Schedule email delivery

require "date"

# Schedule for 60 minutes from now
scheduled_iso = (Time.now + 60 * 60).utc.iso8601

sm.send_email(
  toAddress: "user@email.com",
  fromAddress: "your@startup.com",
  fromName: "Startup name",
  templateName: "Welcome",
  templateProps: { firstName: "Patrik" },
  scheduledAt: scheduled_iso
)

Template with dynamic list

sm.send_email(
  toAddress: "user@email.com",
  fromAddress: "your@startup.com",
  fromName: "Startup name",
  templateName: "Template with dynamic list",
  templateProps: {
    list: [
      { text: "Dynamic list" },
      { text: "allows you to generate email template content" },
      { text: "based on template props." }
    ]
  }
)

Custom HTML email

sm.send_email(
  toAddress: "user@email.com",
  fromAddress: "your@startup.com",
  fromName: "Startup name",
  subject: "Testing html only custom emails :)",
  html: "<html><body><h1>Hello world! 👋</h1></body></html>"
)

Custom plain text email

sm.send_email(
  toAddress: "user@email.com",
  fromAddress: "your@startup.com",
  fromName: "Startup name",
  subject: "Testing plain-text only custom emails :)",
  text: "Hello world! 👋"
)

Error handling

The SDK raises Sidemail::Error for all errors. API errors include message, http_status, error_code, and more_info.

require "sidemail"

sm = Sidemail.new(api_key: "your-api-key")

begin
  sm.send_email(
    toAddress: "user@example.com",
    fromAddress: "you@example.com",
    subject: "Hello",
    text: "Hello"
  )
rescue Sidemail::Error => e
  puts e.message
  if e.http_status # API error
    puts "#{e.http_status} #{e.error_code} #{e.more_info}"
  end
end

Response objects

Most responses are wrapped in a Resource enabling attribute access while remaining hash-like.

  • Methods return Resource wrappers (attribute + hash access); unwrap via .to_h.
  • Original JSON available via .raw.
response = sm.email.get("email-id")
puts "#{response.email.id} #{response.email.status}"
puts response.email["id"] # hash-style
raw_json = response.raw # original JSON mapping
flat_hash = response.to_h # fully unwrapped hash

Attachments helper

require "sidemail"

file_content = File.read("invoice.pdf")
attachment = Sidemail.file_to_attachment("invoice.pdf", file_content)

sm.send_email(
  toAddress: "user@email.com",
  fromAddress: "you@example.com",
  subject: "Invoice",
  text: "Invoice attached.",
  attachments: [attachment]
)

Auto-pagination

List/search methods return a PaginatedResponse containing the first page in result.data. Iterate across all pages with auto_paginate.

result = sm.contacts.list(limit: 50)

result.auto_paginate.each do |contact|
  puts contact.emailAddress
end

Supported auto-paging methods:

  • sm.contacts.list
  • sm.contacts.query
  • sm.email.search
  • sm.messenger.list

Email Methods

Search emails

Paginated (supports auto-pagination).

result = sm.email.search(
  query: {
    toAddress: "john.doe@example.com",
    status: "delivered",
    templateProps: { foo: "bar" }
  },
  limit: 50
)

puts "First page count: #{result.items.count}"
result.auto_paginate.each do |email|
  puts "#{email.id} #{email.status}"
end

Retrieve a specific email

resp = sm.email.get("SIDEMAIL_EMAIL_ID")
puts resp.email

Delete a scheduled email

Only scheduled (future) emails can be deleted.

resp = sm.email.delete("SIDEMAIL_EMAIL_ID")
puts "Deleted: #{resp.deleted}"

Contact Methods

Create or update a contact

resp = sm.contacts.create_or_update(
  emailAddress: "marry@lightning.com",
  identifier: "123",
  customProps: {
    name: "Marry Lightning"
    # ... more props ...
  }
)
puts "Contact status: #{resp.status}"

Find a contact

resp = sm.contacts.find("marry@lightning.com")
if resp.contact
  puts "Found contact: #{resp.contact.emailAddress}"
end

List all contacts

result = sm.contacts.list(limit: 50)
puts "Has more: #{result.has_more}"
result.auto_paginate.each do |c|
  puts c.emailAddress
end

Query contacts (filtering)

result = sm.contacts.query(limit: 100, query: { "customProps.plan" => "pro" })
result.auto_paginate.each do |c|
  puts c.emailAddress
end

Delete a contact

resp = sm.contacts.delete("marry@lightning.com")
puts resp

Project Methods

Linked projects are associated with the parent project of the API key used to initialize Sidemail. After creation, update the design to personalize templates.

Create a linked project

project = sm.project.create(name: "Customer X linked project")
# Important! Save project.apiKey for later use

Update a linked project

updated = sm.project.update(
  name: "New name",
  emailTemplateDesign: {
    logo: {
      sizeWidth: 50,
      href: "https://example.com",
      file: "PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLW1pdGVybGltaXQ9IjIiIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtMTIgNS43MmMtMi42MjQtNC41MTctMTAtMy4xOTgtMTAgMi40NjEgMCAzLjcyNSA0LjM0NSA3LjcyNyA5LjMwMyAxMi41NC4xOTQuMTg5LjQ0Ni4yODMuNjk3LjI4M3MuNTAzLS4wOTQuNjk3LS4yODNjNC45NzctNC44MzEgOS4zMDMtOC44MTQgOS4zMDMtMTIuNTQgMC01LjY3OC03LjM5Ni02Ljk0NC0xMC0yLjQ2MXoiIGZpbGwtcnVsZT0ibm9uemVybyIvPjwvc3ZnPg==",
    },
    font: { name: "Acme" },
    colors: { highlight: "#0000FF", isDarkModeEnabled: true },
    unsubscribeText: "Darse de baja",
    footerTextTransactional: "You're receiving these emails because you registered for Acme Inc."
  }
)

Get a project

project = sm.project.get
puts "#{project.id} #{project.name}"

Delete a linked project

resp = sm.project.delete
puts resp

Messenger API (newsletters)

result = sm.messenger.list(limit: 20)
result.auto_paginate.each do |m|
  puts "#{m.id} #{m.name}"
end

messenger = sm.messenger.get("messenger-id")
created = sm.messenger.create(subject: "My Messenger", markdown: "Broadcast message...")
updated = sm.messenger.update("messenger-id", name: "Updated name")
deleted = sm.messenger.delete("messenger-id")

Sending domains API

domains = sm.domains.list
domain = sm.domains.create(name: "example.com")
deleted = sm.domains.delete("domain-id")

More Info

Visit Sidemail docs for more information.

About

Sidemail.io Ruby SDK

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages