Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send email with Ruby without SMTP server installed/running?

On Mac, I can send email from command line using the command mail, but definitely I don't have SMTP server installed on my MacBookPro.

So, it is possible to send email with Ruby without an SMTP server? I don't care about the speed, I just want a way to send email without additional software needed.

like image 543
Howard Avatar asked Jul 23 '13 14:07

Howard


3 Answers

You could just call the mail command from within your Ruby code. Use system or backticks or something more sophisticated like open3 to interact with system commands... Here is a nice overview over the different methods: http://mentalized.net/journal/2010/03/08/5_ways_to_run_commands_from_ruby/

like image 78
severin Avatar answered Sep 19 '22 14:09

severin


About mail and sendmail

I don't know much about mail, but results from a quick search on Google seem to indicate that it uses postfix, which is the default SMTP server that is installed on Macs. In other words, you have installed and are running a SMTP server on your Macbook Pro.

About Ruby

So, it is possible to send email with Ruby without an SMTP server?

Yes and No. You don't need to have a SMTP server running on the same machine as your Ruby process. In fact, you don't even need to run your own SMTP server. However, you need a SMTP server somewhere to send your email.

About SMTP

This article on howstuffworks gives a good explanation of what SMTP does. Essentially, you need a SMTP server somewhere that accepts your email, talks to other SMTP servers, and passes your email on for delivery. With Ruby, you can configure Net::SMTP to connect to a SMTP server of your choice.

About What You Are Trying To Do

If you want to write and execute a script that will deliver a small number of email messages, create a fake email account on Gmail/Live and use their SMTP servers for sending email.

If you want to build and launch an app that will deliver emails to your users, use Mandrill, MailGun, or SendGrid. Mandrill has a free tier for you to get started.

I don't recommend running your own SMTP server for most use cases, because your emails will likely be marked as spam. (Comcast might also think that you have malware on your network.) Professional services like Mandrill will help you setup SPF and DKIM records to authenticate your emails and improve sending reputation.

(If you just want to test email in dev mode, use MailCatcher.)

Conclusion

Sign up for a Mandrill account, then use Net::SMTP in Ruby to connect to their SMTP servers. No additional software is required.

like image 27
James Lim Avatar answered Sep 18 '22 14:09

James Lim


If your mail command is working, then you can send mail from within ruby. And if your mail command is working on your mac already, then you also already have an SMTP server working on your mac, since by default it uses postfix which comes installed. The mail command defaults to using /usr/sbin/sendmail, which is in this case an interface to postfix. (Try man sendmail from the Terminal.)

Now, that said, you will probably experience something like this when trying to use Net::SMTP locally:

[3] pry(main)> smtp = Net::SMTP.start('localhost',25)
Errno::ECONNREFUSED: Connection refused - connect(2)

This means that you need to do something to tell your mac that it can accept connections on port 25. Another alternative is to use that sendmail program as a transport access method, which might actually be the better option. The port 25 access is turned off so that no one else can use your mac as a mail relay. Having to go through the sendmail command means that only programs on your mac can send mail (go figure).

My suggestion here would be to use the mail gem (or pony if you prefer) and configure it to use sendmail. From the mail README file:

Sending via sendmail can be done like so:

mail = Mail.new do
  from     '[email protected]'
  to       '[email protected]'
  subject  'Here is the image you wanted'
  body     File.read('body.txt')
  add_file :filename => 'somefile.png', :content => File.read('/somefile.png')
end

mail.delivery_method :sendmail

mail.deliver

Likewise, if you're using ActionMailer you can configure it to use sendmail as well.

like image 35
tamouse Avatar answered Sep 21 '22 14:09

tamouse