views:

1311

answers:

4

Hi All,

Does anyone have any quality (and up-to-date) information regarding sending mail via Gmail using Ruby's Net::SMTP? I've seen several examples -- most dating from 2007 to mid-2008 and none of them work for me. I need more current examples that use the most recent 1.8.7 release. I'd also appreciate if the documentation didn't only cover simple examples that no one ever really uses.

Currently I'm receiving an error:

 SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: unknown protocol

I'm not terribly familiar with SSL as regards the SMTP protocol, so this is all lost on me. Unfortunately the Net::SMTP documentation only covers the bases and doesn't provide a full list of the various potential OpenSSL::SSL contexts either so I can't try various ones.

Anyway, if anyone has any quality info on getting this to work with Gmail it would be most appreciated.

Best.

A: 

Are you connecting to smtp.gmail.com port 465 I am assuming? .

openssl s_client -connect smtp.gmail.com:587

CONNECTED(00000003) 8298:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:s23_clnt.c:601:

The error looks very similar to yours. The following command does work:

 openssl s_client  -starttls smtp -connect smtp.gmail.com:587

So I think what is happening is that you do not have STARTTLS support enabled. I am not sure how to do it in ruby buy what I did find out is that the action_mailer_tls plugin allows this by patching Net::SMTP. As of Ruby 1.8.7, Net::SMTP has this support built-in.

If you are using Ruby < 1.8.7 here is the patch.

Sean A.O. Harney
Actually Gmail appears to be an odd beast. Port 465 works just fine, but the need to work on port 587 *and* use STARTTLS causes issues. The latter is the combination I need to work. Any ideas?
humble_coder
So you're saying that SSL/STARTTLS isn't even possible on 587?
humble_coder
I edited my post. STARTTLS command after HELO without SSL to request the server to start it appears to be working. I am not certain.
Sean A.O. Harney
From what I hear, you must contact the server *then* negotiate the SSL session, but I have *NO* idea how to go about that. That's part of the reason I'm using the Ruby module. Hrm... =\
humble_coder
Look and see if there is a STARTTLS option for your ruby module. I edited my post again.
Sean A.O. Harney
+2  A: 

I actually just got this working. Wrote a quick script to test it.

I was getting a different error than you were (requiring STARTTLS), I also found I had to use port 587 instead of 465.

I found the trick to get it working in a Rails plugin I found. (agilewebdevelopment.com/plugins/net_smtp_tls_support)

if you 'eval' this file (it adds tls support to the standard Net::SMTP library):

http://happiness-is-slavery.net/wp-content/rails-plugins/smtp_add_tls_support/lib/smtp_add_tls_support.rb

then run 'Net::SMTP.enable_tls()'

everything seems to work fine.

Here's my code:

require 'rubygems'
require 'net/smtp'

eval File.read("smtp_tls.rb")
Net::SMTP.enable_tls() 
FROM_EMAIL = "REMOVED"
PASSWORD = "REMOVED"
TO_EMAIL = "REMOVED"

msgstr = <<END_OF_MESSAGE
From: Your Name <#{FROM_EMAIL}>
To: my phone <#{TO_EMAIL}>
Subject: text message
Date: Sat, 23 Jun 2001 16:26:43 +0900
Message-Id: <[email protected]>

This is a test message.
END_OF_MESSAGE

Net::SMTP.start('smtp.gmail.com', 587, 'gmail.com',
                      FROM_EMAIL, PASSWORD, :plain) do |smtp|
  smtp.send_message msgstr, FROM_EMAIL, TO_EMAIL

end

obviously, i downloaded the above mentioned file to the same directory and named it 'smtp_tls.rb'

Hope this helps!

Jeremy
looks like there's a smtp_tls gem that would probably work too...
Jeremy
+1  A: 

Actually the below works for gmail without a plugin or a gem, at least with Ruby 1.9.1p376, but good luck finding documentation that'll tell you so:

    require 'net/smtp'

    @msg = "Subject: Hi There!\nThis works."
    smtp = Net::SMTP.new 'smtp.gmail.com', 587
    smtp.enable_starttls
    smtp.start(YourDomain, YourAccountName, YourPassword, :login)
      smtp.send_message(@msg, FromAddress, ToAddress)
    end

YourAccountName looks like '[email protected]' & YourDomain can probably be anything you like, but I use the actual domain name.

David