I think this may be a common situation… I'm working on a password recovery system for a Rails app that sends a link to the user to trigger a new password form. Pretty standard stuff.
On my development server I don't have any mail-sending software enabled or configured (sendmail, SMTP settings, etc.) In config/environments/development.rb I have config.action_mailer.raise_delivery_errors = false to suppress any errors that arise since I don't have a local mail server enabled. This is all good and fine.
However, I would like to view the content of the e-mails while in production without actually sending the mail. I know that it's possible to kind of do this through testing, asserting that the sent (or faux-sent) mail has the correct content. Is there any way to reroute views or something, just temporarily in production, to view an HTTP-served version of the e-mail rather than blindly making assertions?
If you have a UserMailer setup with a "password_reminder" method, you can call create_password_reminder instead of deliver_password_reminder and it will create the message without actually sending. Then you could send the output to the log file:
Where you would have:
UserMailer.deliver_password_reminder
You can replace with:
logger.info UserMailer.create_password_reminder.encoded
Or if you want to send it to a file, you can do that as well.
That being said, the production environment really isn't the place for this sort of thing. I've never had a need to do this, because my mailers have full test coverage. I'd look into that option instead, but I gave the answer you asked for because I don't know your full situation. Happy coding :)
Related
One issue I'm seeing with Devise is that confirmation emails can go to the spam folder. If the user could simply respond to the email, that would serve to confirm the email address and it would train gmail that the sender is not spam.
Any recommendation on if this is worth doing and how would I do it?
Or maybe there's a much easier way to avoid having sent application mails go to spam?
I've been having the exact same issue, and after a long night I believe I have it sorted out.
1) Make sure you have an SPF record set up for your domain.
2) Set up DKIM on your mail server and put your public key in your DNS (TXT record).
3) Make sure your html email is properly formatted ( I had to add the html opening and closing tags to mine, Devise did not do this by default).
4) The last piece of the puzzle was making sure I was sending both plaintext and html MIME parts in my emails. Just creating an additional plaintext 'text.erb' file for each of my mail views seemed to do the trick (Rails auto-magically picked it up and constructed multipart emails for me).
You can verify 1 and 2 are setup right by viewing the 'original' email within Gmail and making sure you see something like "spf=pass" and "dkim=pass" in the headers.
A friend informed me about a service called SendGrid (and I'm sure there are other service providers that do exactly the same thing) after I had spent nearly an entire night going from WTH is DKIM? -- to getting way more familiar with SMTP, DNS, and postfix than I ever wanted to be. But it works now, and I'm probably too cheap to pay for a third party service anyway :)
This is not Devise's fault. Devise actually follows the best practices concerning confirmation of email address.
I believe you fall in the category of bulk email senders, and that you will have to follow quite a few guidelines to sort this out.
I would advise you to go through Google help pages for more information on how to fix this:
Configuration help: https://support.google.com/mail/bin/answer.py?hl=en&answer=81126
Help wizard: https://support.google.com/mail/bin/static.py?hl=en&ts=2696779&page=ts.cs
I'm fairly new to Ruby on Rails and actually entirely new to website mailing. In a lot of example tutorials I see a "from" object assigned to, for example, "new#example.com". When I setup the emailing functionality on a localhost the RoR command prompt says that everything finished fine even when I keep "new#example.com" as the from object. Can I actually mail from a localhost port? What would I have to put as my "from" address in order to actually send mail from the my local web application? Just a regular email I have? How would it be authenticated to ensure that the "from" address is actually the real address?
It seems a really fundamental concept and I understand all the model/view/controller actions that have to be done to make it work but I'm confused I guess as to how it actually works
In general the from field can be anything.
Some mail servers may take action if they think that you are claiming to be someone you are not, such as blocking mail or marking it as spam (via mechanisms such as DKIM or SPF). These are done at the domain level, ie the mail server tries to work out whether the server talking to it is allowed to send email claiming to be from #example.com.
Other mail servers mail just silently rewrite your from field if they know who you are, for example if you are talking to the gmail smtp servers and have authenticated as bob then the from field will be set to bob#gmail.com, unless it is already set to an email address gmail knows you own.
By default, in development rails doesn't try and send email at all. For it to send email you need to configure the deluvery_method, usually this involves either setting it to :sendmail (if you have an appropriately configured instance of sendmail running locally) or setting to :smtp and also providing details of an smtp server to use.
I use ActiveMailer with a 3rd party mailing provider. To develop my app, I want to actually see the emails that come in, as a user would, in my email client.
So in development mode, instead of disabling email, I want my app to send the mails, but change the "to" field so that every email is sent to me. Is that possible?
Update: I want to test the full route my email takes: going through my ESP, arriving in my inbox, viewing it in gmail. I'm not looking to just test that an email is created.
I personally recommend letter_opener by Ryan Bates, however, if you actually want to deliver the mail instead of just viewing it in the browser, there are a number of plugins available that others have already listed. No one, however, has mentioned that you can very easily accomplish this using Interceptors.
Create a new initializer in your config/initializers directory in your Rails app:
# config/initializers/development_mail_interceptor.rb
class DevelopmentMailInterceptor
def self.delivering_email(message)
message.subject = "[#{message.to}] #{message.subject}"
message.to = "YOUR_EMAIL#gmail.com"
end
end
ActionMailer::Base.register_interceptor(DevelopmentMailInterceptor) if Rails.env.development?
This leverages the power of an interceptor on your app. It doesn't configure anything, but rather changes the envelope on the message, altering the to and subject fields. Replace YOUR_EMAIL with the correct value.
The self.delivering_email(message) method is invoked by ActionMailer. You are hooking into that method and override the message envelope.
Finally, you register that interceptor iff we are currently in the development environment.
Be sure to restart your server, and all your mail (in Development) will actually be sent to your email.
Save yourself some trouble and run MailCatcher. MailCatcher is a simple SMTP server that just grabs outbound email and gives it to you in a simple web interface. Install MailCatcher, add this to your environments/development.rb:
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = { :host => 'localhost', :port => 1025 }
Start MailCatcher when you start your Rails server (or use Foreman or something similar to deal with it), and then go to http://localhost:1080/ to see the email that your application is sending out.
You may consider checking out something like MockSMTP (OS X); instead of modifying your "to" fields, you instead set the mail server for dev mode to the "fake" SMTP server created by the app, and from then on ALL emails (sent to anyone) go instead to the app.
I've never used it myself, but I remember seeing that the devs at 37signals use it.
On other operating systems, you may consider one of the following projects:
letter_opener by Ryan Bates - popup a new browser window when an email is sent
MailCatcher (mentioned by mu is too short) - runs a fake SMTP server and a web-based interface for viewing mail sent to it
mailtrap - similar to MockSMTP, has both a mock SMTP server and also a separate viewer program
As much as I like this answer, I went with a different option.
Use the mail_safe gem! As well as providing the functionality from sethvargo's answer, it doesn't require any work other than adding the gem, and it automatically figures out who to email from their .gitconfig.
One important note that I rarely saw mentioned when researching this is that you must use deliver, not deliver!. The latter doesnt call interceptors (though apparently it still calls observers, if that's helpful).
How can I disable the console output on a Rails 3 application?
More specifically, I want to disable at least the Mailer output, that outputs the entire email content, including the pictures, making the action processing much slower (it takes almost 10sec to send an email).
ps: I think the slowdown is because of the output, if it can be from another source, such as slow smtp server (it's gmail atm, so no.) or something else like that please let me know.
By this you mean you want to hide the output shown in the console run you run rails s (or script/server in rails 2)?
Are you on Linux or OSX?
If so, then just do the following
$ rails server 1> /dev/null
this sends all output from stdout into a blackhole.
So right now you are trying to send emails from your dev machine?
I try to avoid this,
as accidents are going to happen
and you'll send clients test data.
Try Mailcatcher
http://mailcatcher.me/
It lets you catch all the emails your app would be sending
shows them off in a nice web interface
and importantly avoids the risk of accidentally sending real emails to customers with random test data.
SMTP server's (even Gmail) response can really take some time. You'd rather use a mail queue that stores all emails in a database and then they are sent by an independent process.
E.g. https://github.com/beam/action-mailer-queue
Concerning logger - make sure that your logging level is :error or :fatal. If not, run:
config.log_level = :error
config.logger = Logger.new('log/development.log')
The default in Ruby on Rails is to have this set to false (in production and development).
config.action_mailer.raise_delivery_errors = false
Seems strange. I'm definitely turning it on in development which has been helpful. But why does no one seem to have this turned on in production? Shouldn't we want to get notified if an email doesn't go through? This seems rather important.
The rails comment in production.rb states
bad email addresses will be ignored
But I have some validation to check incorrect email addresses. It seems like I'd still want to know (via exception notifier or otherwise) how often users aren't getting emails.
the real question is do you want a failed email to throw an error to your end user? Perhaps the mail server is down or a handful of other reasons prevent the email from being sent. Do you want this to throw a 50x error to your user?
Personally, I deliver all email asynchronously so I can monitor this type of stuff (plus it helps greatly in response times)