How to Send Email in Ruby Using Mail Gem or Email API

Editorial Note: We may earn a commission when you visit links on our website.

Do you need to add email functionality to your Ruby application? You’re in the right place.

I’ve spent years building email systems for Ruby apps, from simple scripts to Rails applications sending thousands of transactional emails daily. The method you choose to send email in Ruby makes all the difference in deliverability and reliability.

In this guide, I’ll cover two proven approaches: the Mail gem for standalone apps, and the SendLayer Ruby SDK for scalable delivery. You’ll get working code for plain text emails, HTML emails, and attachments.

Let’s dive in.

How to Send Email with Ruby

There are different ways to send emails using Ruby. If you’re using Ruby on Rails, you can integrate quickly with the ActionMailer gem. This guide will focus on sending methods for vanilla Ruby applications.

Prerequisites

Before diving into the email implementations, make sure you have:

  • Basic Ruby programming knowledge
  • A text editor or IDE of your choice
  • An email service provider

You can use any email service provider you want. However, for this tutorial, I’ll use SendLayer’s SMTP credentials when implementing the email function.

SendLayer is one of the leading email service providers that lets you send emails easily and integrates with any application.

One of the standout features I like is the domain reputation protection. SendLayer automatically creates a subdomain to handle email sending activities. This thereby protects your main domain from any deliverability issues.

  • 200 Free Emails
  • Easy Setup
  • 5 Star Support

How to Send Emails in Ruby Using the Mail Gem

The Ruby Mail gem is a customizable library that gives you control over your email implementation. It is perfect for Ruby applications outside of Rails. Here’s how to get started with the Mail gem.

Installation and Setup

To start, you’ll need to install the Mail gem as a dependency to your project. To install it, open a terminal window and run the command below:

gem install mail

Tip: Prefix the command with sudo if you encounter permission issues when installing the Mail Ruby gem.

Once the installation completes, you should see a success notification in your terminal window.

Ruby Mail gem installation in terminal

Basic Email Configuration

Before you can send an email, you’ll need to configure your SMTP server. Here’s how to configure the Mail gem with SendLayer SMTP. Start by creating an email_service.rb file in your project’s directory.

touch email_service.rb

Then open the file with a code editor. Once open, copy and paste the code below to the email service file:

require 'mail'

Mail.defaults do
  delivery_method :smtp, {
    address: 'smtp.sendlayer.net',
    port: 587,
    user_name: 'your_sendlayer_username',
    password: 'your_sendlayer_password',
    authentication: 'plain',
    enable_starttls_auto: true
  }
end

You’ll need to retrieve your SMTP credentials from the email provider you chose. In SendLayer, you’ll be able to access these details from your account area.

Once logged in, navigate to the Settings sidebar menu. Then select the SMTP Credentials tab.

SendLayer SMTP credentials

You’ll see the SMTP credentials required to use SendLayer’s SMTP server. The Host and Port number are the same for all users. However, the Username and Password details are unique to your SendLayer account.

Go ahead and replace user_name and password in the snippet above with your actual credentials.

Pro Tip: Never commit sensitive credentials to version control platforms. Always use environment variables.

To use environment variables, first install the dotenv library.

gem install dotenv

Then create a new file called .env and add your SMTP credentials.

SENDLAYER_USERNAME=your-smtp-username
SENDLAYER_PASSWORD=your-smtp-password

After updating your SMTP credentials, you’re ready to start sending emails.

Sending Plain Text Emails

Here’s a basic implementation for sending text emails:

require 'mail'

class EmailService
  def self.configure_smtp
    Mail.defaults do
      delivery_method :smtp, {
        address: 'smtp.sendlayer.net',
        port: 587,
        user_name: ENV['SENDLAYER_USERNAME'],
        password: ENV['SENDLAYER_PASSWORD'],
        authentication: 'plain',
        enable_starttls_auto: true
      }
    end
  end

  def self.send_welcome_email(user_email, user_name)
    welcome_message = generate_welcome_message(user_name)

    mail = Mail.new do
      from     '[email protected]'
      to       user_email
      subject  'Welcome to Our Platform!'
      body     welcome_message
    end

    mail.deliver!
    puts "Welcome email sent to #{user_email}"
  rescue Mail::SMTPError => e
    puts "Failed to send email: #{e.message}"
  end

  private

  def self.generate_welcome_message(name)
    <<~MESSAGE
      Hello #{name},

      Welcome to our platform! We're excited to have you join our community.

      You can log in to your account at: https://yourdomain.com/login

      If you have any questions, please don't hesitate to contact our support team.

      Best regards,
      The Team
    MESSAGE
  end
end

Code breakdown

The configure_smtp method sets up the mail delivery configuration using Mail.defaults. We specify the SMTP details, including the address (smtp.sendlayer.net), port (587 for TLS), authentication credentials from environment variables, and enable STARTTLS for secure transmission.

The send_welcome_email method creates a new Mail object using a block syntax. We set the sender address with from, recipient with to, email subject, and generate the email body by calling a private helper method.

The mail.deliver! method actually sends the email through the configured SMTP server. The exclamation mark indicates this method will raise an exception if delivery fails.

Error handling is implemented using a rescue block that catches Mail::SMTPError exceptions. When an SMTP error occurs during delivery, it prints a failure message instead of crashing the application.

The private generate_welcome_message method uses Ruby’s heredoc syntax (<<~MESSAGE) to create a multi-line string template. The ~ removes leading whitespace, making the code more readable while preserving the email formatting.

Send a Test Email

The next step after implementing the email function is to call the class. Let’s create a main.rb file that’ll send the message. After that, copy and paste the code below into the file:

# importing the email service
require_relative 'email_service'

# configure SMTP settings
EmailService.configure_smtp

# send welcome email
EmailService.send_welcome_email('[email protected]', 'Pattie Paloma')

In the snippet above, we first import the email service file. Then call the configure_smtp() method to initialize the SMTP connection. Finally, we call the send_welcome_email() method to send the email. This method accepts 2 parameters: the recipient’s email address and name.

To run the script, open a terminal window and run the command:

ruby main.rb

You should see a welcome email delivered to the specified email address with personalized content.

Send email in ruby Gmail example

Send Email with Attachments

The Mail gem includes support for attaching files to emails. To send an email with an attachment, you’ll need to include the add_file property when specifying the email parameters. Here’s an example:

require 'mail'

def send_email_with_attachment(recipient, attachment_path)
  mail = Mail.new do
    from     '[email protected]'
    to       recipient
    subject  'Document Attached'
    body     'Please find the attached document.'
    
    add_file attachment_path
  end

  mail.deliver!
end

The value of the add_file property should be the path to the file you wish to attach. The Mail gem handles encoding and also tries to guess the file type.

To send multiple attachments, use Ruby’s foreach syntax to map each attachment file to the add_file property. Here is an example:

# For multiple attachments
def send_email_with_multiple_attachments(recipient, attachment_paths)
  mail = Mail.new do
    from     '[email protected]'
    to       recipient
    subject  'Multiple Documents Attached'
    body     'Please find the attached documents.'
    
    attachment_paths.each { |path| add_file path }
  end

  mail.deliver!
end

That’s it! You’ve now learned how to send emails in Ruby using SMTP.

How to Send Emails in Ruby Using Email API

While SMTP works well for smaller projects, using an email API via the SendLayer Ruby gem offers better performance and reliability. It also includes features such as webhook management and event tracking.

  • 200 Free Emails
  • Easy Setup
  • 5 Star Support

Before getting started, you’ll need to install the SendLayer Ruby SDK using RubyGems:

gem install sendlayer

Once the installation completes, create a new .rb file and initialize the SDK with your API key:

require 'sendlayer'

# Initialize the email client with your API key
sendlayer = SendLayer::SendLayer.new('your-api-key')

Retrieving SendLayer API Key

To get your API key, log in to your SendLayer account. Once you’re logged in, click the Settings menu and select the API Keys tab.

Click API keys tab

Then click the copy icon next to Default API key to copy it.

Copy SendLayer API key to send email with python

Sending an Email in Ruby via API

Here is the complete snippet for sending a plain-text email in Ruby using the SendLayer Ruby gem.

require 'sendlayer'

sendlayer = SendLayer::SendLayer.new('your-api-key')

params = {
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Test Email',
  text: 'This is a test email'
}

response = sendlayer.emails.send(params)

if response['MessageID']
  puts "Email sent successfully! Message ID: #{response['MessageID']}"
else
  puts "Failed to send email"
end

Code breakdown

The SDK requires an active API key to initialize it before you can send an email. Make sure to replace your-api-key with your actual API key.

Pro Tip: Never hardcode sensitive credentials, such as API keys or SMTP username and password, in your code. Use environment variables instead and add the .env file to your project’s .gitignore file before uploading the code to a version control system like GitHub.

After initializing the package, configure the email parameters. The SDK accept multiple parameters. However, the following are required to send the API request:

  • from: Sender email address
  • to: A string or list of email recipient(s)
  • subject: The email subject line
  • text or html: Either HTML or plain text email content

To send the email, call the .emails.send() method and pass the parameter.

Sending HTML Emails with the SDK

The SDK also supports HTML emails. To send an HTML email, add the html property to the email params field. This is useful when integrating dynamic, reusable email templates for activities such as password reset and order confirmation emails.

# ...other code snippets

params = {
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Test Email',
  html: "<html><body><p>This is a test email sent with the <a href='https://sendlayer.com'>SendLayer</a> API!</p></body></html>"
}

Note: You can include both text and html parameters to have both plain text and HTML versions of your email.

Sending to Multiple Recipients

To send emails to multiple recipients, update the to property in the params variable to a list of email recipients.

You can either pass the recipients as a comma-separated list of email addresses. Or a list of key-value pairs with the email and name properties for each recipient.

# ...other code snippets

params = {
  from: { email: '[email protected]', name: 'Paulie Paloma' },
  to: [
    { email: '[email protected]', name: 'Recipient 1' },
    { email: '[email protected]', name: 'Recipient 2' }
  ],
  subject: 'Sending Emails to Multiple Recipients',
  html: '<p>This is a <strong>test email</strong>!</p>',
  text: 'This is a test email!',
  cc: [{ email: '[email protected]', name: 'CC Recipient' }],
  bcc: [{ email: '[email protected]', name: 'BCC Recipient' }],
  reply_to: [{ email: '[email protected]', name: 'Reply To' }]
}

The SDK also lets you include CC and BCC email addresses when sending an email.

Note: Rate limit applies to the number of recipients you can add per email request. To learn more, see our rate limit guide.

Send Email with Attachments via API in Ruby

You can send emails with attachments by adding the attachments property to the email params. It requires two fields:

  • path: Path to the file you intend to attach. It accepts both local and remote files.
  • type: The MIME type of the attachment file
# ...other code snippets

params = {
  from: { email: '[email protected]', name: 'Paulie Paloma' },
  to: [{ email: '[email protected]', name: 'Recipient' }],
  subject: 'Email with Attachment',
  html: '<p>Please find the attached document.</p>',
  attachments: [
    {
      path: 'path/to/file.pdf',
      type: 'application/pdf'
    }
  ]
}

Note: The maximum email size is 10MB (message plus attachments).

Comparing Different Ways to Send Email in Ruby

Now that you know how to implement email functionality, let’s explore the different methods available for sending emails in Ruby applications. Each approach has its strengths and is suited for different use cases:

MethodBest ForLibrary/ToolDifficulty
SMTPBasic scripts, standalone appsNet::SMTP (built-in)Easy
Mail GemSimple Ruby applicationsmail gemEasy
Rails ActionMailerRuby on Rails web appsActionMailer (built-in Rails)Medium
Email APIScalable production appsSendLayer gemEasy

Troubleshooting Common Issues

Here are the most common issues developers encounter when sending emails in Ruby and how to fix them:

SMTP Authentication Failed

Net::SMTPAuthenticationError: 535 Authentication failed

This error is often caused by incorrect SMTP credentials or authentication method. You might also encounter it if you’ve set up two-factor authentication (2FA) on your email account.

Solutions:

To resolve the error, verify your SMTP credentials are correct. If you’re using Gmail SMTP, use an app-specific password.

Gmail SMTP Blocked

Gmail may block sign-in attempts from apps it considers less secure.

Solutions:

  • Use App Passwords instead
  • Switch to a professional SMTP service like SendLayer

Invalid Email Address Format

Mail::Field::ParseError: invalid email address

Solution: Always validate email addresses before sending:

def valid_email?(email)
  email.match?(/\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i)
end

# Use before sending
if valid_email?(user_email)
  send_email(user_email)
else
  puts "Invalid email address"
end

FAQs – Send Emails With Ruby

These are answers to some of the questions developers ask about sending emails in Ruby.

What’s the difference between Action Mailer and the Mail gem in Ruby?

Action Mailer is a built-in email framework providing seamless integration with Ruby on Rails applications. It includes templating, testing helpers, and background job integration. The Mail gem, on the other hand, is a standalone library that works in any Ruby application. It offers more low-level control over email creation and delivery.

How do I handle bounced emails and delivery failures?

The best way to handle delivery failures is by implementing proper error handling with try-catch blocks. You can also use webhook endpoints provided by your SMTP service to handle bounce notifications. Services like SendLayer provide detailed delivery reports and bounce handling.

How do I configure SMTP settings for production?

Proper mailer configuration is crucial for production environments. Always use environment variables for SMTP Ruby credentials and ensure your SMTP class implementation includes proper error handling and connection pooling.

What are the security best practices for email delivery in Ruby?

Below, we’ve highlighted some of the best practices for handling email in Ruby applications:

  • Always use environment variables for credentials
  • Enable TLS/SSL connections
  • Validate email addresses before sending
  • Implement rate limiting
  • Use reputable SMTP providers with proper authentication.
  • Never expose API keys or passwords in your source code. Use environment variables to store and manage sensitive credentials.

What is the difference between send and public_send in Ruby?

While both send and public_send are method invocation methods in Ruby, they serve different purposes:

  • send – Can invoke any method (public, private, or protected) on an object. This bypasses Ruby’s access control.
  • public_send – Only invokes public methods, respecting Ruby’s access control mechanism.

In the context of email sending, this distinction doesn’t typically apply. The Mail gem uses deliver! or deliver_now methods directly rather than dynamic method invocation.

Can I use the Mail gem in Rails applications?

Yes, ActionMailer is actually built on top of the Mail gem. However, ActionMailer provides Rails-specific conveniences like:

  • Integration with Rails views and templates
  • Asset pipeline support for email assets
  • Built-in testing helpers
  • Background job integration

For Rails applications, it’s recommended to use ActionMailer rather than the Mail gem directly.

That’s it! Now you know how to send emails in Ruby.

Next, would you like to learn about the difference between different sending methods? Check out our tutorial on SMTP vs API for more information.

  • 200 Free Emails
  • Easy Setup
  • 5 Star Support

Ready to send your emails in the fastest and most reliable way? Get started today with the most user-friendly and powerful SMTP email delivery service. SendLayer Business includes 5,000 emails a month with premium support.