views:

2603

answers:

4

I'm using my Gmail Apps for Domain account to send email within my rails application for standard automated emails (user signup, forgot password, notify admin of new comment, etc), but I'm worried about the 500 emails per day limit set by Google.

Google suggests one way to overcome the limit is to use multiple user accounts.

So, I've setup 10 additional gmail user accounts (noreply1, noreply2, noreply3, etc) - I'd like to track when any of these accounts has sent 500 emails in a 24 hour period and use the idle account accordingly.

How do I dynamically set the :user_name value in ActionMailer::Base.smtp_settings?

Here's my current setup - NOTE: this sends from "noreply1" every time, even though i'm explicitly setting :user_name and :from to "noreply2":

--- development.rb --- 
    ActionMailer::Base.delivery_method = :smtp
    ActionMailer::Base.smtp_settings = {
        :address => "smtp.gmail.com",
        :port => "587",
        :domain => "mydomain.com",  
        :authentication => :plain,
            :user_name => "[email protected]",
        :password => "password"
    }

--- account.rb --- (MODEL, called via a callback)
after_create :send_welcome_email
...
def send_welcome_email
  #ActionMailer::Base.smtp_settings[:user_name] = '[email protected]'
  ActionMailer::Base.smtp_settings.merge!({:user_name => "[email protected]"})  
  SubscriptionNotifier.deliver_welcome(self)   
end

--- subscription_notifier.rb --- (MODEL) 
class SubscriptionNotifier < ActionMailer::Base
  def welcome(account)    
    @sent_on = Time.now
    @subject = "Welcome to the App"
    @recipients = account.email
    @from = "[email protected]" 
    @body = { :account => account }
  end
end
+3  A: 

Store the available usernames in a table in the database, along with a 'last-modified', 'last-reset' and a sent count. You can then query this when sending an email to find the least used email address currently. Then increment the sent count and last-modified account. The 'last-reset' value can be used for your cleanup code so that you reset the counts each 24 hour period.

This also makes it easy to add new email accounts, retire accounts you aren't using anymore, implement in a different app, etc. as it's all just in a database table that you can change when required.

workmad3
Sounds like a good rails plugin if you write that!
Kyle Boon
thanks, very helpful technique for tracking the email accounts, but I was specifically looking for code to set the :user_name element in a typical rails smtp config hash.
Jim Jones
Oops, didn't read the question properly. I'll add a second response with what I think will work for the actual problem :)@kyle: I may do that then... it seems pretty intuitive to me so surprised there isn't already something available along these lines
workmad3
+2  A: 

You should be able to set the :user_name element in the hash in the mailer in the same fashion as in the configuration, namely by doing:

ActionMailer::Base.smtp_settings[:user_name] = 'new_user_name'

Although this may require some extra code to force a reload of any internal action mailer config (not tested this myself)

workmad3
i finally got around to testing this, but I can't get it to work. setting ActionMailer::Base.smtp_settings[:user_name] = 'new_user_name' in a controller method doesn't affect the hash at all. any idea how to reload the hash?
Jim Jones
+8  A: 

You could also set up an MTA on your server and use that for sending the mail.

That's what we do.

You have to add your server's IP as a valid one for sending email in your domain's SPF record to avoid getting marked as spam.

Another benefit of this is that if you do this, you can set the From: address of the email to be one of your users, which you cannot do with GMail.

Luke Francl
When somebody replies to an email sent out by you with a "from" address that's registered in GMail, you're not experiencing any spam issues from Google?
pbz
Hmm...I haven't seen any problems with it. We registered Google Apps for Your Domain as our mail server in SPF and then also registered another IP address (our server) as a valid sender.
Luke Francl
A: 

The comment box was becoming too restrictive for my questions. Changing the ActionMailer::Base.smtp_settings hash dynamically works as expected for me, so I suspect there is some other factor at play here. Some things to try:

  1. Are you using a TLS plugin? I used action_mailer_optional_tls with Rails 2.3.2 and Ruby 1.8.6.
  2. What is being writing to the log/console?
  3. You're changing the username but not the password: do all the noreply accounts have the same password?

Edit: more things to try

I'd have a good look at that smtp_tls.rb file mentioned in the comments to make sure nothing's hard-coded. Or remove it and try the plugin I linked above. To use it, you just need to add :tls => true to the smtp_settings hash.

Andrew Watt
1. I'm using an smtp_tls.rb in my lib directory, but I honestly don't remember where I got if from, but it sends mail with gmail fine. i'll try action_mailer_optional_tls - yes, Rails 2.3.2, Ruby 1.86 patch lvl 1112.console is logging email sent from noreply13.yes, all the passwords are the same
Jim Jones
are you using similar code to me? someone suggested "reloading" the hash, but I don't know how to do that. are you setting the value directly or using merge!
Jim Jones
Almost identical code. I tried setting the value as well as merge!, and both worked. You shouldn't need to "reload" the hash: ActionMailer uses the same smtp_settings hash you provide--there's no internal cache.
Andrew Watt