Ruby : case expressions - ruby-on-rails

I'm using gmail to send out emails from my application. Anticipating very low traffic but maybe more than enough that I might hit gmail mail limits so I'm setting it up (in my application controller) to use two different accounts depending on the time of day.
I've used this set up before successfully but now that I've introduced the "greater than" or "less than" symbols I'm getting an error message about the "when." In another application I did
when Time.now == 1
....
when Time.now == 2
...etc
and it worked fine.
Can anyone tell me what's wrong with this?
case
when Time.now.hour > 12
ActionMailer::Base.smtp_settings = {
:user_name => "blahblahblah#gmail.com",
:password => ENV['GMAIL_PASS'],
:address => "smtp.gmail.com",
:port => 587,
:tls => true
}
when Time.now.hour < 12
ActionMailer::Base.smtp_settings = {
:user_name => "blahblah#gmail.com",
:password => ENV['GMAIL_PASS'],
:address => "smtp.gmail.com",
:port => 587,
:tls => true
}
end

Why use a case statement with only 2 options? A very simple and more elegant way of accomplishing what you want to do is:
username = ["email1#gmail.com", "email2#gmail.com"].sample
Then you will get a random distribution that over time will be 50/50. I think using gmail in general though for bulk mailing is bad. Any decent host can give you a SMTP server.

I can't answer why the error is occurring. I've tested it and like #summea said, it seems to work without else (although using else is better - your example would do nothing when Time.now.hour == 12)
However, I think dividing accounts on hours is a bad idea.
I doubt that usage will be evenly spread; because different parts of the world will sleep at different times.
So you might find 80% of mails are sent via one account.
If you split by seconds, you would get a more even distribution.
To make subsequent modification simpler, you might also want to set a variable for user_name, and avoid repeating the other server settings:
case
when Time.now.sec > 29
user_name = "blahblahblah#gmail.com"
else
user_name = "blahblah#gmail.com"
end
ActionMailer::Base.smtp_settings = {
:user_name => user_name,
:password => ENV['GMAIL_PASS'],
:address => "smtp.gmail.com",
:port => 587,
:tls => true
}

The second "when" should be an "else"

Related

Action Mailer Configuration for Gmail

I'm trying to add e-mail delivery with Gmail SMTP to my app. I've already done the "less secure apps" way before but I don't want to use this option in this project.
I've tried to look into Google's documentation or some gem to make it work, but to no avail. Everyone just sends some code (like below, which is usually the same I have) or tells me to try 'less secure app'.
My current action mailer configuration on production.rb is:
config.action_mailer.perform_caching = false
config.action_mailer.delivery_method = :smtp
config.action_mailer.default_url_options = { :host => ENV['DOMAIN_NAME'] }
config.action_mailer.asset_host = ENV['DOMAIN_NAME']
config.action_mailer.smtp_settings = {
:address => 'smtp.gmail.com',
:port => 587,
:authentication => :plain,
:user_name => ENV['USERNAME'],
:password => ENV['PASSWORD'],
:enable_starttls_auto => true
}
Some people say I'd need ":domain => 'gmail.com'" but with the 'less secure app' option it works, so my guess is that the problem is not that simple. Also, people talk about changing 'authentication: :plain' to :login.
Also, I realize that in the official Rails documentation it says:
Note: As of July 15, 2014, Google increased its security measures and now blocks attempts from apps it deems less secure. You can change your gmail settings here to allow the attempts. If your Gmail account has 2-factor authentication enabled, then you will need to set an app password and use that instead of your regular password. Alternatively, you can use another ESP to send email by replacing 'smtp.gmail.com' above with the address of your provider.
(From http://guides.rubyonrails.org/action_mailer_basics.html#action-mailer-configuration-for-gmail)
But I'm not sure if this solution still requires enabling the 'less secure app' option, which is not what I need.
Has anyone solved this problem without resorting to 'less secure app'?
Thanks in advance!
Okay, so after some time I finally did it.
What I had to do is:
1) Make a 2-step verification on my gmail account, which you can enable here: https://myaccount.google.com/security
2) Create an app-specific password here: https://support.google.com/accounts/answer/185833
It is a string with a format of 16 small case letters. They appear separated in groups of 4 but it's all in the same string. All you have to do is add this app password in the password field inside the block.
...
:user_name => 'my#gmail.com',
:password => 'abcdefghijklmnop',
...
All other settings worked without change.
config.read_encrypted_secrets = true
config.action_mailer.default_url_options = { :host =>
"domain.com" }
config.action_mailer.perform_deliveries = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:user_name => "username",
:password => "password",
:enable_starttls_auto => true
}
Try this config.

Rails - using multiple email providers in single app

Anyway I can use multiple email providers within the same Rails 3 app ?
Context
1. Im using postmark for sending out mails currently (using delayed job)
2. Our app also needs to send out some mass emails - for which we will be using a separate provider.
Now I dont want to separate out and create a new app for the mass emailing part. How can I use/choose different email providers at the point of sending email ?
Thanks in advance
You can override ActionMailer settings on a per mailer basis, for example
class BulkMailer < ActionMailer::Base
self.smtp_settings = {...}
end
will cause BulkMailer and its subclasses to use those settings.
The one thing to be wary of is not to change smtp_settings in place, i.e. do not do something like self.smtp_settings[:user_name] = 'blah' as this would be acting on the shared settings rather than creating new settings private to BulkMailer
I'm using mailserver fallback in my application, so when one mail server is down it switches mailserver. Your problem is similar, except you don't need to alias the old Mail::Message.deliver and use Mail::Message.mass_deliver for instance.
This is how you do it:
Mail::Message.class_eval do
def mass_deliver
self.delivery_method.settings = {
:address => "smtp.massdeliverserver.com",
:port => 587,
:domain => 'yourdomain.com',
:user_name => 'mass-email#quadnode.com',
:password => 'yourpassword',
:authentication => 'plain',
:enable_starttls_auto => true
}
deliver
end
end
Then you could use YourMailer.your_method.deliver to use defalt settings you provided in environment.rb for config.action_mailer.smtp_settings and YourMailer.your_method.mass_deliver to use the other server settings.
Put the code inside some file in config/initializers and mass_deliver method will be available for any Mail::Message instance in your application.
You have a mass email list to which you need to send out from say mass-email#email.com and some other emails for other purpose from otheremail#email.com
You need to do these steps if i am getting the question correct ::
Remove the default from default :from if you have written it.
Create an action mailer for mass-email and put up the :from => "mass-email#email.com"
Go to your environment.rb file and fill up the details like this
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => 'yourdomain.com',
:user_name => 'mass-email#quadnode.com',
:password => 'yourpassword',
:authentication => 'plain',
:enable_starttls_auto => true
}
You can create it for as many files as you wish.
Hope it helps.

Net::SMTPAuthenticationError 502 5.5.2 in Rails ActionMailer

i'm trying to send confirmation email to the user.
But i get following error:
Net::SMTPAuthenticationError (502 5.5.2 Error: command not recognized
Configuration in production.rb is following:
# Disable delivery errors, bad email addresses will be ignored
config.action_mailer.raise_delivery_errors = true
# set delivery method to :smtp, :sendmail or :test
config.action_mailer.delivery_method = :smtp
# these options are only needed if you choose smtp delivery
config.action_mailer.smtp_settings = {
:address => 'path_to_address_specified_by_my_hoster',
:port => 25,
:domain => 'my_domain.com',
:authentication => :plain,
:user_name => 'signup#my_domain.com',
:password => 'password'
}
I have created a mailbox in user profile at my hosting provider, named "signup#my_domain.com"
For created mailbox, they issued to me login and password:
login = verbose_login
password = verbose_password
I did't completely understood the exact format of :user_name.
Should i use
:user_name => "signup#my_domain.com"
or:
:user_name => "signup"
or:
:user_name => "verbose_login"
Or this field is specific to the mail server, and i must ask support of hosting provider ?
And what the difference between :authentication => :plain and :login ?
Thanks.
This works well for me:
config.action_mailer.smtp_settings = {
:address => 'smtp.gmail.com',
:port => 587,
:domain => 'gmail.com',
:user_name => 'my_nick#gmail.com',
:password => 'secret_password',
:authentication => 'login',
:enable_starttls_auto => true
}
more info here
Petr
I have got the same error recently, and the reason was incorrect format of recipients
recipient = IO.readlines(emails_filename).first
mail(:to => recipient, :subject => subject)
Don't forget to add strip to get clean email addresses.
I had the same problem, but it is just a google configuration issue.
For some reason Google was blocking access from unknown location (app in production), so to solve this you can go to http://www.google.com/accounts/DisplayUnlockCaptcha and click continue (this will grant access for 10 minutes for registering new apps).
On the other hand, you could login to your gmail account, then go to https://www.google.com/settings/security/lesssecureapps and enable the access to less secure applications, which was the solution for me!
Please try to login with browser once.
There might be some issue with login (it will ask captcha etc).
Once you successfully logged-in, then try with Rails Mailer.
It should work now.
This issue generally happens with test account as we do not login via browser usually.
Then mail providers ask for confirmation like captcha, dob or answer of security question etc.
You've to use ActionMaliler::Base instead of config
ActionMailer::Base.smtp_settings #try this
config.action_mailer.smtp_settings #instead of this
Change your smtp code to below. It should work now.
ActionMailer::Base.smtp_settings = {
:address => 'path_to_address_specified_by_my_hoster',
:port => 25,
:domain => 'my_domain.com',
:authentication => :plain,
:user_name => 'signup#my_domain.com',
:password => 'password'
}

Has anyone successfully set up their email settings on EngineYard?

I am attempting to add email capabilities to my app (forgotten password, notifications, etc.) and I am using EngineYard for hosting. I have successfully configured email in my test environment but upon uploading to EY it seems to error out in Production. I don't pay for their support and the only resource is a bit vague (or beyond me).
I am curious to know if there is any specific file additions, server set up etc. that is needed when using email on EY. I am using Google apps so I thought it would be as easy as adding the same code block for test in production but doesn't seem to be the case.
Here's my config for Google apps, in .../config/environments/production.rb:
require 'tlsmail'
Net::SMTP.enable_tls(OpenSSL::SSL::VERIFY_NONE)
ActionMailer::Base.raise_delivery_errors = true
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
:address => 'smtp.gmail.com',
:port => 587,
:tls => true,
:domain => 'example.com',
:authentication => :plain,
:user_name => "sender#example.com",
:password => 'tr1ckypwd!'
}
Note, for the security minded out there, I actually keep the password in a separate file and have code to patch it into the settings on launch, but I figured that would distract from the meat of the response.
Hope that helps.

how to set up restful_authentication email activation using gmail SMTP?

I have installed restful_authentcation from technoweenie with activation, and so I see the generated UserMailer < ActionMailer::Base.
However, the instructions don't include how to set it up to work with Google SMTP.
I am guessing that environments/development.rb needs to have the SMTP settings, but still not sure given Google (via Google apps) are all TLS.
Anyone set up activation using restful_authentication?
I currently put into environments.rb the following:
ActionMailer::Base.smtp_settings = {
:enable_starttls_auto => true,
:address => "smtp.gmail.com",
:port => "587",
:domain => "mydomain.com",
:authentication => :plain,
:user_name => "xxx#mydomain.com",
:password => "mypassword"
}
Thanks!!
As far as I know, ActionMailer doesn't do TLS out of the box (2.3.2). A couple of months ago I had the same issue and found some code on a Japanese page and integrated that. it appears that code has been wrapped up into a plugin now (with english docs yeah!). That's not exactly what I'm using, but it advertises the same effect.
so add this plugin:
http://github.com/openrain/action_mailer_tls/tree/master
and in environments/development.rb or environements.rb you need something like this:
ActionMailer::Base.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "yourdomain.com",
:user_name => "first.last#gmail.com",
:password => "passwd",
:authentication => :plain
}
I see that :enable_starttls_auto => true is now in the docs, but it wasn't when I started. this at least works for me...
Edit: for some reason that link doesn't work if you follow it, but copy paste in the address bar and it's live...
I've never used SMTP from ruby (I have from python), but that looks right. You have the right domain and port (actually, multiple ports are supported, but that's one of them), and you're using starttls and AUTH PLAIN, which Google does use.

Resources