Getting "Must issue a STARTTLS command first" when trying to send email
I'm getting an error while trying to use the action_mailer_tls
plugin to communicate with Gmail in my Rails app:
Must issue a STARTTLS command first
Others seem to have encountered this same problem:
The problem is that Gmail requires TLS authentication but the standard Ruby net/smtp library doesn't support TLS.
The article recommends following these steps, which I did:
Of course there is a helpful plugin created by Marc Chung to overcome this barrier. You can find it here and manually add it to your project or you can export it to your plugin directory.
$ cd vendor/plugins
$ svn export http://code.openrain.com/rails/action_mailer_tls/
Either way make sure you require 'smtp_tls'
Now all you need is to update your smtp_settings if you haven't done so already.
- ActionMailer::Base.smtp_settings = {
- :address => "smtp.gmail.com",
- :port => 587,
- :domain => "domain.com",
- :user_name => "user@domain.com",
- :passwor开发者_开发技巧d => "password",
- :authentication => :plain
- }
Any suggestions for a better solution to talk to Gmail would be appreciated.
I used Alexander Pomozov's solution to talk to Gmail from my Rails app. I believe the original article is gone but someone has reproduced the Google cache over here.
lib/smtp_tls.rb
require "openssl"
require "net/smtp"
Net::SMTP.class_eval do
private
def do_start(helodomain, user, secret, authtype)
raise IOError, 'SMTP session already started' if @started
check_auth_args user, secret, authtype if user or secret
sock = timeout(@open_timeout) { TCPSocket.open(@address, @port) }
@socket = Net::InternetMessageIO.new(sock)
@socket.read_timeout = 60 #@read_timeout
#@socket.debug_output = STDERR #@debug_output
check_response(critical { recv_response() })
do_helo(helodomain)
if starttls
raise 'openssl library not installed' unless defined?(OpenSSL)
ssl = OpenSSL::SSL::SSLSocket.new(sock)
ssl.sync_close = true
ssl.connect
@socket = Net::InternetMessageIO.new(ssl)
@socket.read_timeout = 60 #@read_timeout
#@socket.debug_output = STDERR #@debug_output
do_helo(helodomain)
end
authenticate user, secret, authtype if user
@started = true
ensure
unless @started
# authentication failed, cancel connection.
@socket.close if not @started and @socket and not @socket.closed?
@socket = nil
end
end
def do_helo(helodomain)
begin
if @esmtp
ehlo helodomain
else
helo helodomain
end
rescue Net::ProtocolError
if @esmtp
@esmtp = false
@error_occured = false
retry
end
raise
end
end
def starttls
getok('STARTTLS') rescue return false
return true
end
def quit
begin
getok('QUIT')
rescue EOFError, OpenSSL::SSL::SSLError
end
end
end
config/environment.rb
(add after everything else)
require “smtp_tls”
ActionMailer::Base.smtp_settings = {
:address => “smtp.gmail.com”,
:port => 587,
:authentication => :plain,
:user_name => “someone@openrain.com”,
:password => ’someonesPassword’
}
Use ActionMailer as normal.
With Ruby 1.8.7 and Rails 2.3.4 (though it's been there for several releases), I've had success without the need for TLS-specific ActionMailer plugins by using the :enable_starttls_auto
option. A sample config (from the production environment) looks like this:
ActionMailer::Base.smtp_settings = {
:enable_starttls_auto => true,
:address => "smtp.gmail.com",
:port => 587,
:domain => "domain.com",
:authentication => :plain,
:user_name => "username@domain",
:password => "secret"
}
I had enabled starttls using :enable_starttls_auto => true
but still got the same error. Finally I was able to solve it without making a single change in the code. If you are using smtp.gmail.com to send mail, you have to first allow less secure apps to use your email to send mails. For that, login with your account from which you want to send mail and go to
this link and turn on the access to less secure apps.
Edit: If you are not allowed to change the settings to less secure apps, then you should contact the admin account holder of that domain to change the settings to allow the users for less secure apps.
If you have the admin rights you can allow users to change their less secure app settings you can change it from https://admin.google.com/domainname.com/AdminHome#ServiceSettings/notab=1&service=securitysetting&subtab=lesssecureappsaccess
PS: Don't forget to change the domainname in the above link.
Hope this heps!!
I'm running rails 2.3.4 and although I thought (from googling around) you didn't require any plugins and only required the line
:enable_starttls_auto => true,
I actually only got it to work when I used the Alexander Pomozov solution posted by ski above (big thankyou to you guys). Any comments as to why? would be great but I'm just happy it works.
精彩评论