Send email from my domain using SendGrid on Heroku - ruby-on-rails

I have a Rails 4 app which is being hosted by Heroku on my_domain.com. I'm using free SendGrid to send emails, but no matter what settings I use all the emails are sent from my_app#heroku.com. How can set the settings so that emails are sent from automated#my_domain.com?
Thanks.

Try control-shift-F (which will pull up a search for your entire codebase). Search for "my_app#heroku.com" and you may be able to find where this variable is being set. Let me know if this doesn't work and I will try something else.

Go to app/mailers/your_mailer.rb and add the following line under class YourMailer < ActionMailer::Base
default from: "automated#my_domain.com"

Set in your production.rb,
config.action_mailer.default_options = {from: 'no-reply#example.com'}

Related

Getting full URL as displayed in browser URL bar

I have a rails app where I want to send people an email when they sign up. The email has a link to their photos portal so they can get started adding photos, etc..
class MyMailer < ActionMailer::Base
def welcome_email
# ...
link = photos_url # => www.myapp.com/photos
# ...
end
end
The problem is that when I push my code to Heroku and run it live, that link doesn't generate as expected.
The photos_url returns the URL relative to the localhost and ends up generating myapp.herokuapp.com/photos, which is incorrect.
What's even stranger is that if I pause the code at that point with binding.pry and try to see what photos_url is returning, it correctly returns www.myapp.com/photos as expected.
Any thoughts on how to resolve this? I'd hate to have to construct the URL myself from scratch, because that means I have to do it for every environment (localhost, staging, production, etc...)
Thanks!
ActionMailer isn't tied to the request/response cycle, thus it doesn't know what's the host the app is currently running on. Actually, emails are typically sent by some background worker processes which know nothing about the current request URL.
So to make it work you need to set the ActionMailer default_url_options.host option.
Add this into you config/environments/production.rb:
config.action_mailer.default_url_options = { host: 'www.yourapp.com' }

sending emails using templates in Mandrill

I've read through the docs and still am unclear on how to actually use these templates in mandrill.
Currently I have a rails app with the standard Rails mailers (located in: App > views > welcome_mailer > welcome_email.html.erb) being sent through the Mandrill SMTP setup. This is working fine.
Now, I have a template in Mandrill ready to go, now what?
How do I actually use this template, do I need to adjust the code on my app to make a different call, or do I need to do something on the mandrill dashboard to tell it to use the new template instead of the rails version being sent now.
How do I actually use this template?
Thank you in advance.
You can use mandrill_mailer gem, inherit your mailer from MandrillMailer::TemplateMailer and then send it as usual InvitationMailer.invite(invitation).deliver.
Without any gems :
To use mandrill template you first need to create one in your mandrill account and then in your mailer add a correct header which tells the name of the template. Then mandrill will by magic automatically call that template.
Example:
# app/mailers
class CardMailer < ActionMailer::Base
default from: "admin#domain.ch"
def welcome(card)
mail to: card.responsable.email,
from: "\"Andrey\" <admin#domain.ch>",
subject: 'Welcome in my website'
headers['X-MC-MergeVars'] = "{\"TYPE\":\"#{card.card_type.name}\"}" # variables
headers['X-MC-Template'] = "welcome" # template
headers['X-MC-AutoText'] = 1 # generate text version
headers['X-MC-InlineCSS'] = "true" # inline css
end
end
In my case, it uses my "welcome" template. Just use the name of your mandrill template.
As you can see, there are many other headers available. See the full-list here.
Note : even if you don't use rails template any more, you still need one in your view.

How to use Rails mailer settings when creating a custom Mail?

I'm creating a Mail object in a Rails app and want it to pick the mailer settings:
original = UserMailer.new_registration
original.deliver# Does the job
custom = Mail.new(original.to_s)
custom.deliver # Fails: OpenSSL::SSL::SSLError: hostname does not match the server certificate
Apparently the custom Mail object isn't picking up the Rails settings.
Looking at the code, we can pick up the config from the mailer the following way:
custom = ::Mail.new(raw_email)
key = Rails.application.config.action_mailer.delivery_method
delivery_method = ActionMailer::Base.delivery_methods.fetch(key)
delivery_settings = ActionMailer::Base.send("#{key}_settings")
custom.delivery_method(delivery_method, delivery_settings)
custom.deliver
To send custom mails using rails please read this.
http://mdushyanth.wordpress.com/2011/08/06/custom-mail-delivery-method-in-rails-3/

In Rails 3, can we restrict which domains receive emails from our staging server?

We want to test email functionality on our staging server, but we don't want to accidentally email customers.
So, I'd like emails sent to "anything#corporation.com" to work, but emails sent to "anything#customer.com" to be suppressed.
I could just go into all of my controllers and put in code that only fires the "deliver" method if the email contains our domain or the environment is prod. But, that seems kinda kludgey. I'd like to do it app wide.
Applications that use the Mail gem (including rails >= 3.0 projects) can use the safety_mailer gem. Specify a domain (or set of domains, or magic word in email address) email is allowed to go to, and email to all other domains is silently dropped.
https://github.com/cluesque/safety_mailer
Add the gem to your Gemfile, specifying groups (probably not production) to include it in.
gem "safety_mailer", :group => :development
Don't forget to bundle install to install
In your environment file config/environments/development.rb configure it, and some regular expressions.
config.action_mailer.delivery_method = :safety_mailer
SafetyMailer::Config.allowed_matchers = [ /mydomain.com/, /mytestacct#gmail.com/, /super_secret_test/ ]
... and now, email to anyone#mydomain.com, mytestacct#gmail.com, bob+super_secret_test#yahoo.com all get sent
and email to other recipients (like the real users in the production database you copied to a test server) is suppressed.
Here is an example with an interceptor:
Create an initializer /config/initializers/mailer_config.rb :
require 'staging_mail_interceptor'
ActionMailer::Base.register_interceptor(StagingMailInterceptor) if [test here if on staging server]
The file /lib/staging_mail_interceptor.rb contains the interceptor, where you can modify the message before it is sent. In my case I tag the subject and redirect all mails to my personal email. You can put here the code to filter the domains:
class StagingMailInterceptor
def self.delivering_email(message)
message.subject = "TEST #{message.to} - #{message.subject}"
message.to = 'test#corporation.com'
end
end
Modify the delivery_method option for your staging environment - this is a lot less messy than putting in code in your controllers, and then having to rip it back out, because you simply modify a setting, and change it back.
delivery_method - Defines a delivery method. Possible values are :smtp
(default), :sendmail, :test, and :file.
In this case you probably want to use :test, or :file. :file will dump the contents of the email to a file so you can be sure that the email is being rendered the way you expect it to be, with the proper names inserted, etc., without actually sending an email out on the interwebs.
Typically, you don't need to make sure that ActionMailer will actually send email - it does, and it's a well tested module all its own.
An alternative solution, if you really need a full-stack test, is to modify the recipient list for staging only. If you're sending the email to a distribution list, then point it to a different distribution list for staging. If you're sending to a list of emails from the database, then temporarily remove (or mark as inactive) the email addresses you don't want to send to.

Devise and mailers - How to get current URL

When sending emails (for example for 'Reset password instructions') using Devise, i need to know current domain URL, and set that value into mailer's template.
request.url doesn't work for me.
Assuming, this Rails application is accessibly from multiple URLs.
Any ideas?
Request object is not available in the mailers. You will need to set up the host in the environment configuration file with something like:
ActionMailer::Base.default_url_options[:host] = 'myhost.com'

Resources