Do the initializers in a Rails app run each time someone visits the site?
For example, if my server is started in Texas at 10 a.m. , and someone visits my site from New York at 1 p.m. and someone visits from Los Angeles at 10 p.m, do the the initializers in a rails application run when the people from New York and Los Angeles visit, or do the initializers only run once I start the server in Texas?
The reason I'm asking is because I was using a case expression in an initializer file to change email settings depending on the time of day that app is visited. This would only make sense of course if the initializers ran when someone visited the site. If they ran only when the server was started then it would only be one case...
If that's not the right place to do it, or if the initializers only run once the server is started in Texas (for example) then where would you put this code?
case
when Time.now.hour == 0
ActionMailer::Base.smtp_settings = {
:user_name => "blahblah#example.com",
:password => "blahblah",
:address => "smtp.examplel.com",
:port => 25,
:tls => true
}
when Time.now.hour == 1
ActionMailer::Base.smtp_settings = {
:user_name => "blah#example.com",
:password => "eatshit",
:address => "smtp.example.com",
:port => 25,
:tls => true
}
end
A very simple and straight answer is: Just once, when your server kicks up.
You may be intrested in this article The Rails Initialization Process
Initializers get loaded whenever you start up passenger / mongrel or whatever you are using.
To set these settings at runtime take a look at Rails: Runtime configuration of ActionMailer?
Related
I've recently set up the devise gem for authentication and all is working well excluding the forgot my password function. My smtp is currently pointed towards a yahoo email address. Yet, I get a EOF end of file extension error. In development it delivers message just fine ,but to no avail in production. Also, I initialized the ENV variables for username and password with Heroku Config:set .Addtionally, I tried port 587. Any help would be much appreciated! I'm fairly new to rails and searched for similar log issues, but most varied significantly in similarity to this issue. Thank you!
config.action_mailer.perform_caching = false
config.action_mailer.default_url_options = {:host => 'https:app.herokuapp.com' }
config.action_mailer.delivery_method = :smtp
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
ActionMailer::Base.smtp_settings = {
:user_name => ENV['example#yahoo.com'],
:password => ENV['examplepass'],
:domain => 'https://example.herokuapp.com/',
:address => 'smtp.mail.yahoo.com',
:port =>465,
:authentication => "plain",
:enable_starttls_auto => true,
}
My first think:
I think your file have non visible characters, try to clean your file. https://alvinalexander.com/blog/post/linux-unix/how-remove-non-printable-ascii-characters-file-unix
Erase the file and create a new one an rewrite the config, avoid the copy paste. maybe works if you do a copy paste without format to note bloc, word something like that and then copy that back to your file.
Also read more What is an EOFError in Ruby file I/O?
https://airbrake.io/blog/ruby-exception-handling/eof-error
Continue searching i found this
EOFError in Devise::PasswordsController#create
Devise mailer EOF error
a user comment this
Ah classic. My config/secrets.yml isn't tracked in git (naturally) and >looks like it was overwritten and lost those entries for the email >provider smtp/username/password at some point. Thanks
Another one Rails EOFError (end of file reached) when saving a devise user
The resolution to my issue was two fold. I didn't have the heroku config vars properly set up and initialized.My .gitignore file didn't have the exclusions as well to prevent uploading to repository. In conclusion, I added the figaro gem, bundle exec install figaro , and it created the application.yml needed to store that actual user/pass information. https://railsapps.github.io/rails-environment-variables.html ----> quite useful in explaining the options for setting the vars.
:user_name => ENV['SENDGRID_USERNAME'],
:password => ENV['SENDGRID_PASSWORD'],
:domain => 'heroku.com',
:address => 'smtp.sendgrid.net',
:port =>587,
:authentication => :plain,
:enable_starttls_auto => true,
Also in the above code , I didn't have domain specified to heroku.com but my application domain on Heroku. For production.rb you do need the default url set to your applications name. If you kept the default url "heroku.com" in production.rb it would 404 error when the emailed link was clicked on.
config.action_mailer.default_url_options = {:host => 'https://exampleapp.herokuapp.com/' }
Thanks for the help! I also hope this can be of help to other new rails devs.
I have just started learning ruby on rails and this was one of the tutorials i followed:
http://railscasts.com/episodes/206-action-mailer-in-rails-3
I followed it to a T and I have yet to receive anything in my gmail account. Is it fair to assume some updates to ruby have changed how you do things?
My best guess from reading everything over the net, the tutorial is missing actually setting the mailer to use smtp setting.
Here are my smtp settings:
ActionMailer::Base.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "alexei.herokuapp.com",
:user_name => "mygmailaccount",
:password => "mygmailpassword",
:authentication => "plain"
:enable_starttls_auto => true
}
Could it be that i am still in local environment when testing this?
In that Railscast, Ryan has a line in there that doesn't send any email in development:
Mail.register_interceptor(DevelopmentMailInterceptor) if Rails.env.development?
Did you put that in? If so, then no email will go out when you run your app locally in development.
Try removing it.
Also open myapp/logs/development.log to see if what shows up there when you try to send an email.
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.
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"
I am on heroku so am not clear where and how to set it up so that devise can send out emails.
I actually have two directions to go:
I am using sendgrid, so am wondering how it works with that.
For my hand-rolled mailers, I use PostageApp, which I'd prefer because it allows me to see what's going on with my email. The way I use PostageApp is my Mailers are a class of PostageApp's mailer.
Thanks.
In Rails 3 I used the following settings in config/environments/production.rb
# Disable delivery errors, bad email addresses will be ignored
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.default_url_options = { :host => '##YOUR_PROJECTNAME##.heroku.com' }
ActionMailer::Base.smtp_settings = {
:address => "smtp.sendgrid.net",
:port => 25,
:user_name => ENV['SENDGRID_USERNAME'],
:password => ENV['SENDGRID_PASSWORD'],
:domain => ENV['SENDGRID_DOMAIN'],
:authentication => :plain
}
Note: you'll need to substitute in your project name - but all those ENV variables are populated for you automatically by heroku.
I just wanted to let you guys know that with the help of one of our customers, we have been able to add integration instructions for Devise with Postage to our documentation. He has also told us that he is updating the code to work with the newer, modularized version of Devise, and he will give us the code as soon as it is ready.