Topic: Actionmailer with GMail SMTP server

I've been trying to send emails with my gmail account for a while now, and thought I would share with you the working solution.

Turns out GMail supports only SSL SMTP mailing service, meaning if you cannot create a SSL connection to its SMTP server, you cannot send email through them. My Rails and Ruby (1.84) version do not yet support creating a SSL SMTP connection through Net::SMTP. DHH wrote about how to do so through installing msmtp, but  I'd rather not use another application if I don't have to.

The dynamic nature of Ruby allows me to enhance the functionality of that class.  I found the following answers from Stephen Chu's and a Japanese site, http://d.hatena.ne.jp/zorio/20060416 .

You must paste some files in your vendor/plugins directory...

vendor/plugins/action_mailer_tls/init.rb

require_dependency 'smtp_tls'

vendor/plugins/action_mailer_tls/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)

    raise 'openssl library not installed' unless defined?(OpenSSL)
    starttls
    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)

    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')
  end

  def quit
    begin
      getok('QUIT')
    rescue EOFError
    end
  end
end

And your config/environments/development.rb or test.rb or production.rb, in your ActionMailer::Base's server settings if you have:

ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.server_settings = {
  :address => "smtp.gmail.com",
  :port => 587,
  :domain => "mycompany.com",
  :authentication => :plain,
  :user_name => "username",
  :password => "password"
}

If you call your ActionMailer::Base's deliver method, it will send an email through GMail. That took me a little time to work through yesterday, so hopefully this can save someone some time.

Last edited by zreed20 (2006-07-06 03:09:55)

But they that wait upon the Lord shall renew their strength

Re: Actionmailer with GMail SMTP server

Thank you!!!  Saved me a good bit of time here...

Re: Actionmailer with GMail SMTP server

No problem.  I've asked many questions on this forum and received some great answers.  It's always good to pass on something good  when it works.

Zack

But they that wait upon the Lord shall renew their strength