Wednesday, October 7, 2009

Deleviring mails from a Rails app to the local mbox and displaying in Evolution

A special thanks to one of my friends because of whom this was completed on time.

Recently I was integrating ActionMailer in a Rails application. I was using Cucumber to test the application. In the test environment the general idea is to ask the ActionMailer not to try to deliver the emails really but assume that those are delivered.

When the integration of the ActionMailer was done, I wished to see how the email actually looked like in a mail reader like Thunderbird or Evolution on my local machine before putting the email templates in the production mode. I did not use my production server for all this testing stuff because of the fear of being blacklisted. I actually wished to test how a email looked like after the delivery.

To accomplish this I asked ActionMailer to use Postfix to deliver those emails to my local GNU/Linux mbox. I then used Evolution mail reader to read my local mbox so that I could see how the actual mail looked like after delivery. I did following things to achieve this.

Install Postfix

I have Ubuntu on my development machine. So to install Postfix you could do just the following.

$ sudo aptitude install postfix

Above will install and configure the postfix on your machine. To check if the postfix was configured correctly on your system try sending a mail to yourself.

$ mail <your_login_name_to_machine>(e.g. waseem on my machine)
Subject: Test mail to local user.
Trying to send a mail to the local user.

Now we test if the mail was actually delivered to the local mailbox.

$ mail
Mail version 8.1.2 01/15/2001. Type ? for help.
"/var/mail/waseem": 1 message 1 new
>N 1 waseem@goodlove Wed Oct 7 15:34 14/460 Test mail to local user.

Looks like the mail was delivered.

Configure Postfix to use virtual email addresses.

I am developing a Rails application which lets some user sign up using their email address. In my user model I have a validation which checks the format of the email address submitted by a user when she signs up. In my tests I used email with format of "user_name@webapp.test". To force Postfix to deliver all the mails send to the email of this format I used its virtual_alias_maps configuration option.

Postfix's virtual_alias_maps lets you create any number of 'virtual' email addresses, that would all end up in one email account. And for the testing purposes I wanted that account to be my local system user's account mailbox.

First we create a file called 'virtual' which will hold the mapping of the aliases of the email formats.

$ sudo vim /etc/postfix/virtual

Put the following lines in that file.

@webapp.test waseem
@test.local waseem

Above tells Postfix that all the mails send to the emails ending in @webapp.test and @test.local domains should be delivered to the mbox of user waseem. :)
Now we hash this file so that postfix can read this file faster.

$ sudo postmap /etc/postfix/virtual

A /etc/postfix/virtual.db file would be created after doing this.

Now we tell Postfix to use this file for virtual alias maps.

$ sudo postconf -e "virtual_alias_maps = hash:/etc/postfix/virtual"

Now we restart Postfix by doing $ sudo /etc/init.d/postfix restart.

Ask Rails to use Postfix for the mail delivery.

In your config/enviroments/test.rb replace config.action_mailer.delivery_method = :test with config.action_mailer.delivery_method = :smtp

Now we test the if the delivery of the mails is taking place by making some actions which cause execution of mail delivery method in the Rails app code. In my case it was just by executing feature definition which tried to signup a user to the application.

When I did the above, I faced following error.

OpenSSL::SSL::SSLError (hostname was not match with the server certificate):
/usr/lib/ruby/1.8/openssl/ssl.rb:123:in `post_connection_check'
/usr/lib/ruby/1.8/net/smtp.rb:582:in `tlsconnect'

I googled for the solution and found out two of them. First was to ask Postfix to not to do any SSL security checks. To do this you should edit the /etc/postfix/ to have smtpd_tls_auth_only=no. Restart the Postfix and you are fine again.

Other solution is to generate good SSL files and force Postfix to use them. I prefered the first solution as it suited my needs.

Now when you tried sending emails with you Rails application to any email address ending in @webapp.test or @test.local, those were actually delivered to the local mbox of user waseem. You could test it by running the mail program in your terminal.

Using Evolution to read your local mailbox.

It is comparatively quite simple. You just create a new account in the Evolution program. Enter any email address and select "Standard mbox spool or directory". Now choose /var/mail/<your_login_name_to_machine> for the path. Choose SMTP as your mail server type and localhost in the server configuration. You are done now.

Now when you check this account in the Evolution, you will find those emails sent by the Rails application in the test environment.



Kazim Zaidi said...

Thanks for the post, it was great! I've configured mail on my local machine for my web application too.

By the way, what's the web application you are working upon?

Waseem Ahmad said...

I am working on the same web application which you are working upon.

Kenneth Lindsey Calamay said...

Hi bro Waseem,

This is the second time I was saved by this post of yours. I thought I'd say thank you for taking the time to write this way back Oct, 2009. It really went a long way.

Kenneth Calamay
The Philippines