Ruby Sending Emails - SMTP
SMTP (Simple Mail Transfer Protocol) is a simple mail transfer protocol, a set of rules for transferring emails from the source address to the destination address, controlling the method of message relay.
Ruby provides Net::SMTP for sending emails and offers two methods: new
and start
.
new method has two parameters:
- server name defaults to localhost
- port number defaults to 25
start method has the following parameters:
- server - SMTP server IP, defaults to localhost
- port - port number, defaults to 25
- domain - sender's domain name, defaults to ENV["HOSTNAME"]
- account - username, defaults to nil
- password - user password, defaults to nil
- authtype - authentication type, defaults to cram_md5
The SMTP object instantiation method calls sendmail
, with the following parameters:
- source - a string or array or anything that the iterator returns at any time
- sender - a string that appears in the email's form field
- recipients - a string or array of strings representing the recipient's addresses
Example
Below is a simple Ruby script to send an email:
require 'net/smtp'
message = <<MESSAGE_END
From: Private Person <[email protected]>
To: A Test User <[email protected]>
Subject: SMTP e-mail test
This is a test e-mail message.
MESSAGE_END
Net::SMTP.start('localhost') do |smtp|
smtp.send_message message, '[email protected]',
'[email protected]'
end
Using Net::SMTP to connect to the SMTP server on the local machine, the send_message
method is used to send the email, with the sender's and receiver's emails as parameters.
If you do not have an SMTP server running on your machine, you can communicate with a remote SMTP server using Net::SMTP. If you use an email service (like Hotmail or Yahoo Mail), your email provider will provide you with the details of the mail server:
Net::SMTP.start('mail.your-domain.com')
The above code will connect to the mail server at mail.your-domain.com, port 25. If you need to enter a username and password, the code would be:
Net::SMTP.start('mail.your-domain.com',
25,
'localhost',
'username', 'password', :plain)
The above example connects to the mail server at mail.your-domain.com, port 25, with the specified username and password.
Sending HTML Emails with Ruby
Net::SMTP also supports sending HTML-formatted emails.
When sending an email, you can set the MIME version, document type, and character set to send HTML-formatted emails.
Example
The following example is for sending an HTML-formatted email:
require 'net/smtp'
message = <<MESSAGE_END
From: Private Person <[email protected]>
To: A Test User <[email protected]>
MIME-Version: 1.0
Content-type: text/html
Subject: SMTP e-mail test
This is an e-mail message to be sent in HTML format
<b>This is HTML message.</b>
<h1>This is headline.</h1>
MESSAGE_END
Net::SMTP.start('localhost') do |smtp|
smtp.send_message message, '[email protected]',
'[email protected]'
end
Sending Emails with Attachments
If you need to send mixed-content emails, you need to set the Content-type to multipart/mixed. This allows you to add attachment content to the email.
Attachments need to be encoded in base64 format using the pack("m") function before transmission.
Example
The following example sends an email with an attachment from /tmp/test.txt:
require 'net/smtp'
filename = "/tmp/test.txt"
# Read the file and encode it as base64
filecontent = File.read(filename)
encodedcontent = [filecontent].pack("m") # base64
marker = "AUNIQUEMARKER"
body =<<EOF
This is a test email to send an attachment.
EOF
# Define the main headers
part1 =<<EOF
From: Private Person <[email protected]>
To: A Test User <[email protected]>
Subject: Sending Attachment
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=#{marker}
--#{marker}
EOF
# Define the message action
part2 =<<EOF
Content-Type: text/plain
Content-Transfer-Encoding:8bit
#{body}
--#{marker}
EOF
# Define the attachment part
part3 =<<EOF
Content-Type: multipart/mixed; name=\"#{filename}\"
Content-Transfer-Encoding:base64
Content-Disposition: attachment; filename="#{filename}"
#{encodedcontent}
--#{marker}--
EOF
mailtext = part1 + part2 + part3
# Send the email
begin
Net::SMTP.start('localhost') do |smtp|
smtp.sendmail(mailtext, '[email protected]',
['[email protected]'])
end
rescue Exception => e
print "Exception occurred: " + e
end
Note: You can specify multiple recipient addresses, but they need to be separated by commas.