Sending or receiving email with Rails? Easy
Mar34
Sending emails from Rails can be a pain, receiving them even more so. You have to set up queues, pollers, smtp servers etc – it’s a hassle.
There is another way though. Remail is a project I’ve just released that brings REST to email.
Remail proxies emails through Google App Engine:
- To send an email – just send a POST request to your Remail Google App Engine.
- To receive an email – Remail will send a POST request to a callback URL.
It’s that simple. App Engine gives you 2000 free emails a day, and if you need more – the prices are very reasonable.
It’s worth mentioning, that at the moment, Remail only works with Rails 3.
Step 1 – App Engine
So, firstly create a App Engine project:
Next, install the Python developer SDK.
Clone the remail-engine git repository:
git clone git://github.com/maccman/remail-engine.git
Configure the remail-engine application.yaml file, by adding the name of your App Engine project (the yaml key is called application).
Then, you’ll need to configure the settings.yaml file. Specify the public url of your site as outbound_url, and a random string as api_key (you can generate one using uuidgen).
Add the remail-engine to the App Engine SDK and deploy.
Step 2 – ActionMailer
Install the remail gem:
sudo gem install remail
Add add it to your Gemfile:
gem "remail"
Now configure Remail, either in application.rb, or in the environment files:
config.action_mailer.delivery_method = :remail config.action_mailer.remail_settings = { :app_id => "remit-yourappname", :api_key => "changeme" }
Right, so now we can send email. How about receiving them? We need to specify a callback controller like this:
class EmailsController < ApplicationController skip_before_filter :verify_authenticity_token def create if request.headers["Authorization"] != "yourapikey" return head(:unauthorized) end UserMailer.receive(params[:email][:raw]) head :ok end end
Remail will send a POST request to that controller when it receives any emails.
If your Rails app isn’t available – Remail will try again and again – backing off as time goes by.
Right, so those are the two steps to using Remail in your application. You can now generate mailers as usual – everything should just work.
There’s a good Railscast on using ActionMailer with Rails 3, and a good Rails Guide on the subject.
Enjoy this article?
Consider subscribing to our RSS feed!
34 Comments
Leave a comment
Tweets
- We're currently processing millions of tweets! 2010-06-28
- We're doing the BET.com awards moderation tonight: http://betawards.bet.com/extras/twitter 2010-06-28
- #cashgordon should have used http://socialmod.com :) 2010-03-23
- More updates...
Powered by Twitter Tools.
12:55 am on March 23rd, 2010
Stupid question, but does the application need to be on App Engine? Or can I use the App Engine email facility with Remail on Heroku, for example.
6:37 am on March 23rd, 2010
Jason,
remail-engine is specific to Google App Engine, however your Rails application can be anywhere. In fact it doesn’t even need to run Rails.
Alex
4:43 am on March 24th, 2010
What a spiffingly good solution! Nice. I’ll be using this on future projects for sure.
To save anyone a few clicks, here’s the info on google to do with quotas and costs:
http://code.google.com/appengine/docs/quotas.html#Mail
http://code.google.com/appengine/docs/billing.html#Billable_Quota_Unit_Cost
($0.0001/recipient with first 2000 free)
Thanks
10:28 am on March 24th, 2010
Can you send ‘on behalf of’ emails using this? As in, my app sending emails on behalf of you using your email. Something similar to any popular site (eg. LinkedIn) does.
1:56 pm on March 24th, 2010
You can’t send message from their email address, but you can use their name. For example, you could set the from value to this: “Alex M”
To the recipient, it would seem like Alex sent you that message, even though the from address is not actually the users real address. You can then set the reply-to to the users real address. Does that make sense?
8:01 pm on March 24th, 2010
After following these instructions , when I run UserMailer.deliver(..) , i get the error :
Errno::EAFNOSUPPORT: Address family not supported by protocol – socket(2)
Any idea what’s up?
8:15 pm on March 24th, 2010
You have missed “config.action_mailer.delivery_method = :remail” from the above instructions!
11:04 pm on March 24th, 2010
Any idea how much of a pain would this be to fork and configure to work with Rails 2.3’s?
6:09 am on March 25th, 2010
Chris, thanks – fixed.
Darren,
Not much. Most of the code you need for ActionMailer is here:
http://github.com/maccman/restful_email/blob/master/restful_mailer.rb
4:20 pm on March 25th, 2010
Does this work for attachments as well?
1:41 am on March 26th, 2010
This trick doesn’t work with gmail and gmail for apps. Even if we set reply-to, gmail just ignores it. But I don’t know how some applications manage to do that. For example if I send an invitation to a colleague from linkedin, that colleague receives the email as if I sent him. The ‘from’ address displays my email id.
11:51 am on April 11th, 2010
Anybody had a luck to get it work with 2.3’s? I would like to use it but have not enough experience to fork it by myself. Or is there another good e-mail solution for Rails/Heroku?
2:39 am on April 15th, 2010
I usually don’t post in Blogs but your blog forced me to, amazing work.. beautiful ?
2:39 pm on May 12th, 2010
The thing I hate with action mailer in a rails app is that when sending an email your application waits/delays until the mail is send before proceeding to the next action.
(There are solutions for this like ar_mailer. But it requires running a cron_job or daemon. Those cost server memory so…..)
So does Remail provide a solution for the delay?
And how about mass emailing. Will it work with Remail like ar_mailer does?
1:25 am on July 6th, 2010
What if I just need to send email and I’m not using rails?
Thank you
7:28 am on August 11th, 2010
For “delay” issue, I used to use delay job trick (rabbitmq). You can find the tutorial @ railscasts.com
7:12 pm on August 12th, 2010
How do you Clone the remail-engine git repository? I’m not clear in what application I should execute the command:
git clone git://github.com/maccman/remail-engine.git
I’m using a MAC. I tried Terminal, but that didn’t work.
7:56 pm on August 12th, 2010
In step 2, where am I Installing the remail gem (sudo gem install remail
)? Is this on my MAC or in Google App Engine or somewhere else?
Also what’s a GEM file and where is it located? Does the above program line install a program that uses this GEM file?
Obviously all this is new to me.
8:00 pm on August 12th, 2010
Scott216: To be honest Scott, I’d try to get a bit more experience with the basics of Ruby first before trying this tutorial. But, to answer your questions: To install git, just google git osx – there’s an installer binary. To install a gem, just type sudo gem install remail inside the osx terminal – RubyGems is a Ruby package manager.
Hope that was useful. Alex
9:25 pm on August 12th, 2010
Thanks for your help Alex. I’m not really interested in learning Ruby, but I do have a particular need and I think remail is my best option. I put together an Arduino microcontroller to measure temperature and some other things, this data is pushed out to a website called Pachube. Pachube has HTTP Post triggers that you can set if certain conditions are met. I want to use pachube triggers to post to remail so I can get an email alert.
10:09 pm on August 12th, 2010
I got this error when trying to install gem:
scotts-mac-pro:~ Scott$ sudo gem install remail
Password:
ERROR: While executing gem … (Gem::RemoteSourceException)
HTTP Response 301 fetching http://gems.rubyforge.org/yaml
1:30 am on August 24th, 2010
How do you test receiving emails locally?
What email address to i send it to? Do i have to mess with hosts.
Great work but so many thanks
11:45 am on August 29th, 2010
I’ve installed this into one of my rails 3 sites, but I am now unable to send any mails. There is an error occurring in the python code in the remail-engine in outbound.py on line 22. Any ideas what is causing this? I can paste the whole log entry if you like.
08-29 08:39AM 05.516 ‘EmailMessage’ has no attribute ‘email’ Traceback
File “/base/data/home/apps/salesflip/1.344426892063585378/outbound.py”, line 22, in email
mail.EmailMessage(**safe_dict(email)).send()
Thanks, Matt
11:51 am on August 29th, 2010
Can you log the dict that’s causing the issue – I need to see its attributes. Are you using the github version of the Ruby gem – it includes some Rails 3 fixes. I’ve just released those fixes into the gem, should propagate soon. If you have further trouble email me (email on about page).
1:49 pm on August 29th, 2010
I just changed to the github version in my Gemfile and redeployed and now everything is working fine, thanks!
1:05 am on September 7th, 2010
I am getting the same problem as Matt,
How is it fixed?
gem ‘remail’, :git => ‘git://github.com/maccman/remail-engine.git’
Does not seem to fix it for me.
4:47 am on September 7th, 2010
Peter,
I pushed the updated gem, so you shouldn’t have this problem. You’re also pulling from the wrong git repo. Should be:
gem ‘remail’, :git => ‘git://github.com/maccman/remail.git’
9:32 am on September 8th, 2010
This looks like a really awesome solution I had seen smtp2web do something like this but this looks way better. I love the way app engine makes it so easy to receive mail.
If anyone wants to try the beta of a product I’m developing called CloudMailin (http://cloudmailin.com) then please give me a shout.
7:56 am on September 12th, 2010
Cheers for the help Alex,
I am trying to receive incoming mail with attachments. I seem to be getting a few errors on the app.
http://pastie.org/1153609
The attachment size is around 2mb so I cant see that being the problem?
Any idea? Again, thankyou.
8:43 am on September 12th, 2010
Looks like that attachment size is too big then. You may have to remove the queues to get it to work.
8:27 am on December 23rd, 2010
hi…it is not working for me…when i tried to send a mail im getting Connection refused – connect(2). This is what i did. Please correct me If i ve done anything wrong.
1) I created a new GAE app, replaced the contents of the GAE app(app.yaml,index.yaml, main.py) with the contents of the remail engine git repo.
2)In the settings.yaml, I changed api_key to a random key, and set the outbound url to localhost(i just want to send mails and not receive them).
3)I changed the app.yaml’s application name to the name of my GAE app(without the .appspot.com).
4) I deployed it and checked the task queues in the GAE console, which showed inbound and outbound task queues.
5)Now I added remail gem to my gemfile and installed it.
6)Then I set the following:
config.action_mailer.delivery_method = :remail
config.action_mailer.remail_settings = {
:app_id => “app name without .appspot.com”,
:api_key => “random key from step 2″
}
Thats all I did. When I tried to send a mail now, It throws an error. Can you please help me to solve this problem.