473,287 Members | 1,560 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes and contribute your articles to a community of 473,287 developers and data experts.

Sending & Testing Emails with Ruby

Let’s say you have a working Ruby app and need to add an email delivery functionality to it. This could be related to user authentication, or any other kind of transactional emails, it makes no difference. This tutorial is tailored is aimed at helping you implement sending emails with Ruby.

Options for sending an email in Ruby

Mostly, you can pick one of the three options.

The simplest one is using Net::SMTP class. It provides the functionality to send email via SMTP. The drawback of this option is that Net::SMTP lacks functions to compose emails. You can always create them yourself, but this takes time.

The second option is to use a dedicated Ruby gem like Mail, Pony, or others. These solutions let you handle email activities in a simple and effective way. Action Mailer is a perfect email solution through the prism of Rails. And, most likely, this will be your choice.

The third option is class Socket. Mostly, this class allows you to set communication between processes or within a process. So, email sending can be implemented with it as well. However, the truth is that Socket does not provide you with extensive functionalities, and you’re unlikely to want to go with it.

Now, let’s try to send an email using each of the described solutions.

How to send emails in Ruby via Net::SMTP

From my experience, the use of that option in a regular web app is uncommon. However, sending emails via Net::SMTP could be a fit if you use mruby (a lightweight implementation of the Ruby language) on some IoT device. Also, it will do if used in serverless computing, for example, AWS Lambda. Check out this script example first and then we’ll go through it in detail.

Expand|Select|Wrap|Line Numbers
  1.  require 'net/smtp'
  2.  
  3. message = <<END_OF_MESSAGE
  4.  
  5. From: YourRubyApp <info@yourrubyapp.com>
  6.  
  7. To: BestUserEver <your@bestuserever.com>
  8.  
  9. Subject: Any email subject you want
  10.  
  11. Date: Tue, 02 Jul 2019 15:00:34 +0800
  12.  
  13.  
  14.  
  15. Lorem Ipsum
  16.  
  17. END_OF_MESSAGE
  18.  
  19. Net::SMTP.start('your.smtp.server', 25) do |smtp|
  20.  
  21.   smtp.send_message message,
  22.  
  23.   'info@yourrubyapp.com',
  24.  
  25.   'your@bestuserever.com'
  26.  
  27. end
This is a simple example of sending a textual email via SMTP (official documentation can be found here). You can see four headers: From, To, Subject, and Date. Keep in mind that you have to separate them with a blank line from the email body text. Equally important is to connect to the SMTP server.

Expand|Select|Wrap|Line Numbers
  1. Net::SMTP.start('your.smtp.server', 25) do |smtp| 
  2.  
Naturally, here will appear your data instead of ‘your.smtp.server‘, and 25 is a default port number. If needed, you can specify other details like username, password, or authentication scheme (:plain, :login, and :cram_md5). It may look as follows:

Expand|Select|Wrap|Line Numbers
  1. `Net::SMTP.start('your.smtp.server', 25, ‘localhost’, ‘username’, ‘password’ :plain) do |smtp|`
Here, you will connect to the SMTP server using a username and password in plain text format, and the client’s hostname will be identified as localhost.

After that, you can use the send_message method and specify the addresses of the sender and the recipient as parameters. The block form of SMTP.start (`Net::SMTP.start('your.smtp.server', 25) do |smtp|`) closes the SMTP session automatically.

In the Ruby Cookbook, sending emails with the Net::SMTP library is referred to as minimalism since you have to build the email string manually. Nevertheless, it’s not as hopeless as you may think of. Let’s see how you can enhance your email with HTML content and even add an attachment.

Sending an HTML email in Net::SMTP

Check out this script example that refers to the message section.

Expand|Select|Wrap|Line Numbers
  1.  message = <<END_OF_MESSAGE
  2.  
  3. From: YourRubyApp <info@yourrubyapp.com>
  4.  
  5. To: BestUserEver <your@bestuserever.com>
  6.  
  7. MIME-Version: 1.0
  8.  
  9. Content-type: text/html
  10.  
  11. Subject: Any email subject you want
  12.  
  13. Date: Tue, 02 Jul 2019 15:00:34 +0800
  14.  
  15.  
  16.  
  17. A bit of plain text.
  18.  
  19.  
  20.  
  21. <strong>The beginning of your HTML content.</strong>
  22.  
  23. <h1>And some headline, as well.</h1>
  24.  
  25. END_OF_MESSAGE
  26.  
Apart from HTML tags in the message body, we’ve got two additional headers: MIME-Version and Content-type. MIME refers to Multipurpose Internet Mail Extensions. It is an extension to Internet email protocol that allows you to combine different content types in a single message body. The value of MIME-Version is typically 1.0. It indicates that a message is MIME-formatted.

As for the Content-type header, everything is clear. In our case, we have two types – HTML and plain text. Also, make sure to separate these content types using defining boundaries.

Except for MIME-Version and Content-type, you can use other MIME headers:

- Content-Disposition – specifies the presentation style (inline or attachment)

- Content-Transfer-Encoding – indicates a binary-to-text encoding scheme (7bit, quoted-printable, base64, 8bit, or binary).

Sending an email with an attachment in Net::SMTP]

Let’s add an attachment, such as a PDF file. In this case, we need to update Content-type to multipart/mixed. Also, use the pack("m") function to encode the attached file with base64 encoding.


Expand|Select|Wrap|Line Numbers
  1. require 'net/smtp'
  2.  
  3. filename = "/tmp/Attachment.pdf"
  4.  
  5. file_content = File.read(filename)
  6.  
  7. encoded_content = [file_content].pack("m")   # base64
  8.  
  9.  
  10.  
  11. marker = "AUNIQUEMARKER"

After that, you need to define three parts of your email.

Part 1 – Main headers

Expand|Select|Wrap|Line Numbers
  1.  part1 = <<END_OF_MESSAGE
  2.  
  3. From: YourRubyApp <info@yourrubyapp.com>
  4.  
  5. To: BestUserEver <your@bestuserever.com>
  6.  
  7. Subject: Adding attachment to email
  8.  
  9. MIME-Version: 1.0
  10.  
  11. Content-Type: multipart/mixed; boundary = #{marker}
  12.  
  13. --#{marker}
  14.  
  15. END_OF_MESSAGE
Part 2 – Message action

Expand|Select|Wrap|Line Numbers
  1. part2 = <<END_OF_MESSAGE
  2.  
  3. Content-Type: text/html
  4.  
  5. Content-Transfer-Encoding:8bit
  6.  
  7.  
  8.  
  9. A bit of plain text.
  10.  
  11.  
  12.  
  13. <strong>The beginning of your HTML content.</strong>
  14.  
  15. <h1>And some headline, as well.</h1>
  16.  
  17. --#{marker}
  18.  
  19. END_OF_MESSAGE
Part 3 – Attachment

Expand|Select|Wrap|Line Numbers
  1. part3 = <<END_OF_MESSAGE
  2.  
  3. Content-Type: multipart/mixed; name = "#{filename}"
  4.  
  5. Content-Transfer-Encoding:base64
  6.  
  7. Content-Disposition: attachment; filename = "#{filename}"
  8.  
  9.  
  10.  
  11. #{encoded_content}
  12.  
  13. --#{marker}--
  14.  
  15. END_OF_MESSAGE
Now, we can put all the parts together and finalize the script. That’s how it will look:

Expand|Select|Wrap|Line Numbers
  1.  require 'net/smtp'
  2.  
  3.  
  4.  
  5. filename = "/tmp/Attachment.pdf"
  6.  
  7. file_content = File.read(filename)
  8.  
  9. encoded_content = [file_content].pack("m")   # base64
  10.  
  11.  
  12.  
  13. marker = "AUNIQUEMARKER"
  14.  
  15.  
  16.  
  17. part1 = <<END_OF_MESSAGE
  18.  
  19. From: YourRubyApp <info@yourrubyapp.com>
  20.  
  21. To: BestUserEver <your@bestuserever.com>
  22.  
  23. Subject: Adding attachment to email
  24.  
  25. MIME-Version: 1.0
  26.  
  27. Content-Type: multipart/mixed; boundary = #{marker}
  28.  
  29. --#{marker}
  30.  
  31. END_OF_MESSAGE
  32.  
  33.  
  34.  
  35. part2 = <<END_OF_MESSAGE
  36.  
  37. Content-Type: text/html
  38.  
  39. Content-Transfer-Encoding:8bit
  40.  
  41.  
  42.  
  43. A bit of plain text.
  44.  
  45.  
  46.  
  47. <strong>The beginning of your HTML content.</strong>
  48.  
  49. <h1>And some headline, as well.</h1>
  50.  
  51. --#{marker}
  52.  
  53. END_OF_MESSAGE
  54.  
  55.  
  56.  
  57. part3 = <<END_OF_MESSAGE
  58.  
  59. Content-Type: multipart/mixed; name = "#{filename}"
  60.  
  61. Content-Transfer-Encoding:base64
  62.  
  63. Content-Disposition: attachment; filename = "#{filename}"
  64.  
  65.  
  66.  
  67. #{encoded_content}
  68.  
  69. --#{marker}--
  70.  
  71. END_OF_MESSAGE
  72.  
  73.  
  74.  
  75. message = part1 + part2 + part3
  76.  
  77.  
  78.  
  79. begin
  80.  
  81.   Net::SMTP.start('your.smtp.server', 25) do |smtp|
  82.  
  83.     smtp.send_message message,
  84.  
  85.     'info@yourrubyapp.com',
  86.  
  87.     'your@bestuserever.com'
  88.  
  89.   end

Can I send an email to multiple recipients in Net::SMTP?

Definitely, you can. send_message expects second and subsequent arguments to contain recipients’ emails. For example, like this:

Expand|Select|Wrap|Line Numbers
  1.  Net::SMTP.start('your.smtp.server', 25) do |smtp|
  2.  
  3.   smtp.send_message message,
  4.  
  5.   'info@yourrubyapp.com',
  6.  
  7.   'your@bestuserever1.com',
  8.  
  9.   ‘your@bestuserever2.com’,
  10.  
  11.   ‘your@bestuserever3.com
  12.  
  13. end
Best Ruby gems for sending emails

In Ruby ecosystem, you can find specific email gems that can improve your email sending experience.

Ruby Mail

This library is aimed at giving a single point of access to manage all email-related activities including sending and receiving email.

Pony

You might have heard a fairy tale about sending an email in one command. Hold on to your hats, cause it’s real and provided by Pony gem.

ActionMailer

This is the most popular gem for sending emails on Rails. In case your app is written on top of it, ActionMailer will certainly come up. It lets you send emails using mailer classes and views.

Using Mailtrap to test email sending with Net::SMTP

Setup is very simple. Once you’re in your demo inbox, copy the SMTP credentials on the SMTP Settings tab and insert them in your code. Or you can get a ready-to-use template of a simple message in the Integrations section. Just choose a programming language or framework your app is built with.

Expand|Select|Wrap|Line Numbers
  1. require 'net/smtp'
  2.  
  3.  
  4.  
  5. message = <<END_OF_MESSAGE
  6.  
  7. From: YourRubyApp <info@yourrubyapp.com>
  8.  
  9. To: BestUserEver <your@bestuserever.com>
  10.  
  11. Subject: Any email subject you want
  12.  
  13. Date: Tue, 02 Jul 2019 15:00:34 +0800
  14.  
  15.  
  16.  
  17. Lorem Ipsum
  18.  
  19. END_OF_MESSAGE
  20.  
  21. Net::SMTP.start('smtp.mailtrap.io', 587, '<username>', '<password>', :cram_md5) do |smtp|
  22.  
  23.   smtp.send_message message,
  24.  
  25.   'info@yourrubyapp.com',
  26.  
  27.   'your@bestuserever.com'
  28.  
  29. end
If everything is alright, you’ll see your message in the Mailtrap Demo inbox. Also, you can try to check your email with HTML content and an attachment. Mailtrap allows you to see how your email will look and check HTML if necessary.

You have just read the full tutorial on how to test and send emails in Ruby. Hope you enjoyed!
Apr 27 '22 #1
0 10922

Sign in to post your reply or Sign up for a free account.

Similar topics

2
by: Damien | last post by:
Hi to all, After hours of attempts and "googling", I'm still pulling my hair off my head when I try to send multipart html emails. It "works" on PCs with Outlook when I juste send a single...
8
by: Good Man | last post by:
Hi I'm building a 'job posting' site of sorts. When a job is available in a particular state, I want the system to send an email to everyone who is 'watching' that state. I know how to do...
1
by: Ian Taylor | last post by:
Hi all... Is it possible to send RTF-formatted emails using the .NET SmtpMail implementation? I can only find provision in the BodyFormat property of the message to send plain text or HTML...
2
by: Thief_ | last post by:
I need to monitor POP3 & IMAP servers for new emails. Ideally my app needs to sit in the system tray. Has anyone done this before? -- | +-- Thief_ | VB.NET 2003
1
by: robbiesmith79 | last post by:
Just so this is out there on the web, I battled the past 24 hours about this. Background info... I developed a ecommerce website in PHP 4 on a shared linux hosting plan from GoDaddy and had the...
2
by: Big Moxy | last post by:
Here is my code for formatting an HTML email. I know that spinning through the $_POST array as I am isn't very pretty but it's a long list so for now I'm using this approach. The problem is that...
0
by: sheel331 | last post by:
Hello, I am new to coding in vb.net and have run into an issue with some code that I am looking over. This is a webform that is filled out and once it is filled out, it takes the responses from...
2
by: lstanikmas | last post by:
Hi, I'm validating a form with this ASP but receiving some blank email responses; does anyone see anything wrong with it?: function isFormVarExcluded(thisForm, strToCheck) { var strExcludeVars...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: Aftab Ahmad | last post by:
So, I have written a code for a cmd called "Send WhatsApp Message" to open and send WhatsApp messaage. The code is given below. Dim IE As Object Set IE =...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: marcoviolo | last post by:
Dear all, I would like to implement on my worksheet an vlookup dynamic , that consider a change of pivot excel via win32com, from an external excel (without open it) and save the new file into a...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.