Topic: Sending E-mail Using Gmail SMTP

Hey guys, I did not write this tutorial, but I think it should be shared here.

I was having issues with ActionMailer and Gmail. I had my configurations looking about like this:

ActionMailer::Base.smtp_settings = {
  :address => "smtp.gmail.com",
  :port => "587",
  :domain => "oursite.com",
  :authentication => :plain,
  :user_name => "info@oursite.com",
  :password => "*******"
}

Obviously that didn't work right out of the box, though it would have been plain sexy if it did.

Now, the messages were getting processed gorgeously. I know this because they came up in my logs. I then did a little bit of googling and found this link:
http://godbit.com/forum/viewtopic.php?id=876

Which basically says " 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. "

So, he tells us to roll our own itty bitty plugin. It was a process of creating two files and one folder.

Here is a zip of the files so you don't have to recreate them: http://lakedenman.com/files/action_mailer_tls.zip

Here is the source:

 #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


Then, your environment file should look like this:
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"
}

I really hope this helps some people. Thanks.


Lake

Re: Sending E-mail Using Gmail SMTP

Sounds good, have been struggling to get ActionMailer working, but this didn't work for me either, i get an error:

Timeout::Error in EmailerController#notify
execution expired

?

Pj.

Re: Sending E-mail Using Gmail SMTP

can you post your notify action?

or actually, all relevant code.

Last edited by Lake (2007-12-04 18:53:27)

Re: Sending E-mail Using Gmail SMTP

Hi,

It's based on this tutorial i found and was working through:

http://www.tutorialspoint.com/ruby-on-r … -email.htm

Here are the files:

controller/emailer_controller.rb

class EmailerController < ApplicationController
   def index
      render :file => 'app\views\emailer\index.rhtml'
   end
   
   def notify
      email = params["email"]
      recipient = email[recipient]
      subject = email[subject]
      message = email[message]
      Emailer.deliver_contact(recipient, subject, message)
      return if request.xhr?
      render :text => 'Message sent successfully'
   end
end

model/emailer.rb:

class Emailer < ActionMailer::Base
   def contact(recipient, subject, message, sent_at = Time.now)
      @subject = subject
      @recipients = recipient
      @from = 'info@*******.com'
      @sent_on = sent_at
      @body["title"] = 'Welcome to ******'
      @body["email"] = 'info@*******.com'
      @body["message"] = message
      @headers = {}
   end
end

views/emailer/contact.rhtml:

Hi!

You are having one email message from <%= @email %> with a title

<%= @title %>
and following is the message:
<%= @message %>


views/emailer/index.rhtml:

<h1>Send Email</h1>
<%= form_tag :action => 'notify' %>
<p><label for="email_subject">Subject</label>:
<%= text_field 'email', 'subject' %></p>
<p><label for="email_recipient">Recipient</label>:
<%= text_field 'email', 'recipient' %></p>
<p><label for="email_message">Message</label><br/>
<%= text_area 'email', 'message' %></p>
<%= submit_tag "Send" %>
<%= end_form_tag %>

Many thanks,

PJ.

Re: Sending E-mail Using Gmail SMTP

Hey pj.
I just tried to follow the guide and i'm not sure that's the best guide out there. I got several deprecation warnings, leading me to believe it's a little old. See if this helps at all.

http://railscasts.com/episodes/61

Re: Sending E-mail Using Gmail SMTP

Ok, thanks Luke. I will try the Railscast episode.

Best,

Pj.

Re: Sending E-mail Using Gmail SMTP

sure, pj.

-Lake.

Last edited by Lake (2007-12-05 11:33:27)

Re: Sending E-mail Using Gmail SMTP

I just want to give you a big THX!!!
I was stuggling with Rails and TLS for a long time now, but your tutorial worked like a charm

Great work!

Re: Sending E-mail Using Gmail SMTP

Sure thing!

Re: Sending E-mail Using Gmail SMTP

Lake,

It's a beautiful fix and your solution saved my life! smile

Works PERFECTLY! THANK YOU VERY MUCH!

Cheers,
Ellils

11

Re: Sending E-mail Using Gmail SMTP

Dear Lake,

      I have done all these step given here. When I try to send mails it didnt show any errors. But the mailes did not delivered to recipients. I dont know whats happening. can u help me?.

Thanks in Advance,
JK

Last edited by JK (2008-02-27 09:24:35)

Re: Sending E-mail Using Gmail SMTP

Check out your log file and see if any errors are thrown.

Add this to your environment.rb :

config.action_mailer.raise_delivery_errors = true



I seem to be running into some problems with this lately. I'm trying to figure it out. Are you guys still successfully connecting?

Re: Sending E-mail Using Gmail SMTP

I've used this guide below to try and get my Google Apps email to send email from Rails:

http://www.danielfischer.com/2008/01/09 … for-rails/

It uses the action_mailer_tls plugin.

When i check my logs it appears as if the mail is being sent, as i can see the text of the email, but it does not actually get delivered...??

Anyone else have experience with this?

Oddly enough, on one occasion i got an email delivered, but i have not been able to repeat this...

PJ.

Re: Sending E-mail Using Gmail SMTP

Hi,
   For me the mails are being delivered correctly... But i have one problem in "From Address" of the email which i receive...  i.e, i want to get the "From Address" as what i have given in "from" field while writing action mailer code in model.  But at present its taking "From Address" as what i have mentioned in the environment.rb file (which is in username field).... Pls Help me.....


Regards,
Yoganand

Re: Sending E-mail Using Gmail SMTP

I'm using the action mailer tls plugin and it works in development mode, but not in production mode. I would debug this myself, but when I look in the production log file (assuming this log file keeps track of ALL the same info as the development log), nothing appears in it. It's like the Mailer.deliver_XXX function never even got called. (in the development log, I'll see the email, as well as a bunch of random code that looks like it's communicating with google MX) My production project is mysql and the development is sqlite. Might that be the problem??? Anyone ever experience this?

My development is on my local machine, and the production is on the slicehost server. Any help would be much appreciated!

Re: Sending E-mail Using Gmail SMTP

Does the code from the log below mean that it worked? I'm not receiving the email but from my noobish eye, it looks like it went through? I'm in development mode if that makes a difference.

Thank you
Jason

Sent mail:
Date: Thu, 29 May 2008 11:24:25 -0700
From: jason@portlandonrails.com
To: schmidtjra@msn.com
Subject: IWalkTheVine - Your password has been reset
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8

schmidtjra, Your password has been reset
-> "250-mx.google.com at your service, [74.92.167.130]\r\n"
-> "250-SIZE 28311552\r\n"
-> "250-8BITMIME\r\n"
-> "250-AUTH LOGIN PLAIN\r\n"
-> "250 ENHANCEDSTATUSCODES\r\n"
<- "AUTH PLAIN AGphc29uQHBvcnRsYW5kb25yYWlscy5jb20AanM2OTY5Njk=\r\n"
-> "235 2.7.0 Accepted\r\n"
<- "MAIL FROM:<jason@portlandonrails.com>\r\n"
-> "250 2.1.0 OK\r\n"
<- "RCPT TO:<schmidtjra@msn.com>\r\n"
-> "250 2.1.5 OK\r\n"
<- "DATA\r\n"
-> "354 Go ahead\r\n"
writing message from String
wrote 319 bytes
-> "250 2.0.0 OK 1212085467 z20sm1996179pod.11\r\n"
<- "QUIT\r\n"
-> "221 2.0.0 mx.google.com closing connection z20sm1996179pod.11\r\n"
  SQL (0.000254)   COMMIT
Redirected to http://localhost:3000/login
Completed in 1.90491 (0 reqs/sec) | DB: 0.00681 (0%) | 302 Found [http://localhost/passwords/update/72fca0b53a3c367af2d1940d58f3f294dea80959]

Re: Sending E-mail Using Gmail SMTP

I'm having a similar problem, in that everything works great in my local development environment, but when I try in the production environment the emails never get sent, and I see something like this in the log:

-> "220 mx.google.com ESMTP f45sm9565579pyh.24\r\n"
<- "EHLO \r\n"
-> "250-mx.google.com at your service, [67.207.129.71]\r\n"
-> "250-SIZE 28311552\r\n"
-> "250-8BITMIME\r\n"
-> "250-STARTTLS\r\n"
-> "250 ENHANCEDSTATUSCODES\r\n"
<- "STARTTLS\r\n"
-> "220 2.0.0 Ready to start TLS\r\n"
<- "EHLO \r\n"
-> "250-mx.google.com at your service, [67.207.129.71]\r\n"
-> "250-SIZE 28311552\r\n"
-> "250-8BITMIME\r\n"
-> "250-AUTH LOGIN PLAIN\r\n"
-> "250 ENHANCEDSTATUSCODES\r\n"
<- "AUTH PLAIN AG5vcmVwbHlAYWN0cy1hcy1ibG9nci5jb20AcGFzc3dvcmQ=\r\n"
-> "535-5.7.1 Username and Password not accepted. Learn more at         \r\n"
-> "535 5.7.1 http://mail.google.com/support/bin/answ … swer=14257 f45sm9565579pyh.24\r\n"

Also, here's my mailer.yml file with username/password changed:
---
  :address: smtp.gmail.com
  :port: 587
  :user_name: blah@blah.com
  :password: blah
  :authentication: :plain

Re: Sending E-mail Using Gmail SMTP

I get this error message when trying to send mail, only in production mode though.

Did anybody figure this out?
Thanks

ActionController::RoutingError (No route matches "/AZenv/azenv.php" with {:method=>:get}):
    /vendor/rails/actionpack/lib/action_controller/routing/recognition_optimisation.rb:67:in `recognize_path'
    /vendor/rails/actionpack/lib/action_controller/routing/route_set.rb:384:in `recognize'
    /vendor/rails/actionpack/lib/action_controller/dispatcher.rb:163:in `handle_request'
    /vendor/rails/actionpack/lib/action_controller/dispatcher.rb:105:in `dispatch'
    /vendor/rails/actionpack/lib/action_controller/dispatcher.rb:102:in `synchronize'
    /vendor/rails/actionpack/lib/action_controller/dispatcher.rb:102:in `dispatch'
    /vendor/rails/actionpack/lib/action_controller/dispatcher.rb:118:in `dispatch_cgi'
    /vendor/rails/actionpack/lib/action_controller/dispatcher.rb:11:in `dispatch'
    /usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/rails.rb:76:in `process'
    /usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/rails.rb:74:in `synchronize'
    /usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/rails.rb:74:in `process'
    /usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:159:in `process_client'
    /usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:158:in `each'
    /usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:158:in `process_client'
    /usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:285:in `run'
    /usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:285:in `initialize'
    /usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:285:in `new'
    /usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:285:in `run'
    /usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:268:in `initialize'
    /usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:268:in `new'

Last edited by haries (2008-06-10 15:57:50)

Re: Sending E-mail Using Gmail SMTP

That doesn't really look related to sending mail.  It seems to be an issue with the ProxyJudge script that you're using.  ProxyJudges are unfamiliar territory to me, but based on a few minutes of Googling, I'm guessing that you're using azenv.php to retrieve data about the client for whatever purpose.  If this is the case, perhaps the script is not setup/configured properly.  A permissions issue maybe...  I dunno.

Re: Sending E-mail Using Gmail SMTP

action_mailer_tls has a problem with ruby 1.8.7. The code you posted in smtp_tls.rb produces
ArgumentError: wrong number of arguments (3 for 2) from
Line9. check_auth_args user, secret, authtype if user or secret.

You can get fix for this issue by removing authtype parameter from check_auth_args method call

    #check_auth_args user, secret, authtype if user or secret # This is for ruby 1.8.6
    check_auth_args user, secret if user or secret # This is for ruby 1.8.7

Details from http://blog.inspired.no/smtp-error-whil … -rails-271

Last edited by fattah.uign (2009-06-08 01:55:06)