Sunday, 6 September 2009

Sending Email Using Gmail and Action Mailer

I've used this for a new site, which I'll be mentioning very soon. It took me quite some time to figure out and get right.

The first thing to do is download the smtp_tls.rb file. I saved it in my Sinatra app, under lib.

Next create a file called mailer.rb in the same lib directory with the following contents:
require 'lib/smtp_tls'
require 'action_mailer'

class Mailer < ActionMailer::Base
def my_email(from_email, from_name, message)
recipients "marktucks@gmail.com"
from from_email
subject "Contact from " + from_name

body :name => from_name, :email => from_email, :message => message
end
end

Mailer.template_root = File.dirname(__FILE__)
Mailer.delivery_method = :smtp
Mailer.smtp_settings = {
:address => "smtp.gmail.com",
:port => "587",
:domain => "YOUR_DOMAIN",
:authentication => :plain,
:enable_starttls_auto => true,
:user_name => "YOUR_USERNAME",
:password => "YOUR_PASSWORD",
:raise_delivery_errors => true
}
Mailer.logger = Logger.new(STDOUT)

NB: I did have the from address as from_email "<" + from_name + ">" but it recently gave me a syntax error, so I removed it which fixed this issue.

As our class above is called Mailer, create a directory under lib called mailer, which is where our email template will go. As we have a method called my_email in our Mailer class, we need to call our template my_email.erb with the following simple contents:
Enquiry from <%= h @name %>,
Email: <%= h @email %>
Message:
<%= h @message %>

The variables match the ones we passed in from our Mailer class on this line:
body       :name => from_name, :email => from_email, :message => message

Lastly, we send the email:
begin
Mailer.deliver_my_email(@email, @name, @message)
@sent = true
rescue Exception => e
@sent = false
end

As shown in the ActionMailer docs, we are just calling a dynamically generated method, which simply prefixed deliver_ to to the name of our my_email method from the Mailer class. This method will raise Exceptions if something goes wrong, so we've rescued this if it happens so our lovely users aren't exposed to it.

Comments, better ways of doing this, general discussion welcome just throw me a comment.

No comments: