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.
Related
I want to send emails with sendgrids API from a google cloud platform instance. They have a short tutorial on how to do this but it has the email message, who its from, who to send to, and other info all in app.rb which isnt the normal way messages are sent in rails apps.
I looked at the sendgrid ruby docs and they also dont have very good information. All the info in in one place and they dont state what files to put them in or even mention any smtp settings to use.
Here is what I have so far
development.rb
config.action_mailer.delivery_method = :smtp
# SMTP settings
config.action_mailer.smtp_settings = {
:address => "smtp.sendgrid.net",
:port => 465,
:domain => "mydomain.com",
:user_name => ENV['sendgrid_username'],
:password => ENV['sendgrid_password'],
:authentication => :plain,
:ssl => true,
:enable_starttls_auto => true
}
gemfile
gem "sendgrid-ruby"
The email views are in app/views, the mailer methods are in app/mailer the same as normal rails 4 apps have it setup.
So I guess here are my main questions:
Where do I call the environment variables holding the sendgrid api key?
Where do I tell Action Mailer to use sendgrid or SendGrid::Mail as I've seen in a couple of places?
Do I even need the sendgrid gem?
Are the smtp settings correct for sending over SSL with sendgrid?
I'm new to sending emails like this in a rails app and would really appreciate the help.
Put apikey as the name and the actual apikey as password:
config.action_mailer.smtp_settings = {
address: "smtp.sendgrid.net",
port: 587,
domain: "yourwebsite.com",
authentication: :plain,
user_name: 'apikey',
password: Rails.application.secrets.sendgrid_api_key
}
Source
Use Figaro gem: https://github.com/laserlemon/figaro
It will generate an application.yml file for you, where you can store your sendgrid_username and sendgrid_password.
Have you generated your mailer? For example, generate mailer user_notifier where you can define your a default-from email, and some methods like this:
r
# send a signup email to the user, pass in the user object that contains the
user email address
default :from => 'hello#yourdomain.com'
def send_signup_email(user)
#user = user
mail( :to => #user.email,
:subject => 'Thanks for signing up!'
)
end
No, you don't need it.
https://sendgrid.com/docs/Classroom/Basics/Email_Infrastructure/smtp_ports.html
In my environment.rb file I have:
ActionMailer::Base.smtp_settings = {
:address => "smtp.example_host.com",
:port => '25',
:domain => "example_send_from.com",
:authentication => :plain,
:user_name => "send_account_name",
:password => ENV['MY_EMAIL_SEND_PWD']
}
It works fine.
However, now my app has a new class of emails that need to be sent via a different email account... perhaps gmail in some low-volume cases, sendgrid in other high volume cases.
I'm sure it's pretty simple -- but how do I override the default Base.smtp_settings setting on an email-by-email basis?
do you have separate actionmailers for each email account? then you could set the smtp settings per action mailer-class:
class Mailer1 < ....
self.smtp_settings = { .... }
end
etc.
I am trying to understand how to properly configure Action Mailer for Rails 3 to work with Gmail. Read the article by Ryan Bates and also read the edge Rails page article. Ryan's article said to put the config details in /config/initializers/setup_mail.rb initializer file
ActionMailer::Base.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "asciicasts.com",
:user_name => "asciicasts",
:password => "secret",
:authentication => "plain",
:enable_starttls_auto => true
}
But the edge Rails article said put it in the config/environments/$RAILS_ENV.rb, anyone know which is the preferred way of doing it?
Put it wherever it makes sense for your particular project. If you need different settings for different environments then do that, otherwise you can put it into an initializer.
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.
I would like to send a small amount of email from my app through Gmail. Now, the SMTP settings will be determined at runtime (ie: from the db), can this be done?
--- edit ---
I can set the ActionMailer subclass (named Notifier) smtp settings in one of the class' methods. This way I can set the username and password for sending the email dynamically. The only thing is that you have to set ALL the smtp_settings. Is it possible to set just the username & password settings in the class method?
This is the code I'm using right now, it is sending:
class Notifier < ActionMailer::Base
def call(user)
Notifier.smtp_settings = {
:enable_starttls_auto => true,
:address => "smtp.gmail.com",
:port => "587",
:domain => "mydomain.com",
:authentication => :plain,
:user_name => "fabian#mydomain.com",
:password => "password"
}
recipients user.email
subject "Test test"
body "Test"
end
end
I would like to just set the username and pw here.
(Rails 3)
Since I call mailer like this:
CustomerMailer.customer_auto_inform(#form).deliver
In CustomerMailer class I have private method:
def init_email_account(shop_mail)
ActionMailer::Base.raise_delivery_errors = true
ActionMailer::Base.smtp_settings = {
:address => shop_mail.address,
:port => shop_mail.port,
:domain => shop_mail.domain,
:user_name => shop_mail.user_name,
:password => shop_mail.password,
:authentication => shop_mail.authentication.name,
:enable_starttls_auto => shop_mail.enable_starttls_auto
}
end
Before calling mail() which sends email you need to call private method init_email_account to populate smtp_settings from database. shop_mail is model which stores the data about mail account settings.
HTH
Since the configuration files are all Ruby, then the settings can easily be fetched from a configuration file or the like at runtime.
Here's a post I wrote a while back on getting ActionMailer working with GMail SMTP.
NOTE: If you're using rails 2.3 and Ruby 1.87, you don't need the plugin and can simply use the settings in this comment
Assuming you've configured the smtp_settings in your environment or initializers, you can just set the username like so:
Notifier.smpt_settings.merge!({:user_name => "x", :password=> "y"})
You can do that in the controller:
class ApplicationController < ActionController::Base
...
private
def set_mailer_settings
ActionMailer::Base.smtp_settings.merge!({
username: 'username',
password: 'yoursupersecretpassword'
})
end
end