How to disable console output on Rails 3 development server? - ruby-on-rails

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')

Related

Rails: test mailgun on localhost

I have a Rails app running on Heroku that uses Mailgun to process incoming emails. I haven't been able to figure how I can debug my email processing locally (on localhost) instead of having to push everything up to heroku every time I make a change. (this is just a test app - I'm the only one using it)
Is it possible to work with Mailgun locally? If so, how do I go about it?
Thank you in advance
Mailgun gives you the option to store a message for later retrieval. If you configure it that way, you'll be able to fetch messages from development for processing without having to set up a publicly-accessible webhook for Mailgun to hit.
But I'm assuming you have production configured with an HTTP endpoint, and it's no fun to do things differently between environments. There are a few tools that will let you set up a public endpoint that routes to localhost:
ngrok, which I've used to good effect to test Twilio. You can set up a permanent subdomain so you don't have to constantly change your Mailgun configuration.
UltraHook, which I haven't personally used, but looks the same.
Localtunnel which looks easiest to start up, but like you get a different host at every boot.
If you have a permanent publicly-accessible server, you can also maintain your own tunnel.
mailgun provides a sandbox that you can use for localhost the only downside to this is that you have to add the test email to valid recipient.
using this gem might be another possible solution:
https://github.com/ryanb/letter_opener/ or https://github.com/fgrehm/letter_opener_web for more advanced features
follow installation from repo
mail will open in new tab

Writing a spec for sending a mail via API

I want an E-Mail to be sent using a background process whenever an Invite was generated.
What I currently have is this approach: The Invite model has the method send_mail, which sends an E-Mail using the Mandrill API and gem. It also has the method queue_mail adds InviteMailer with the invite's ID to the queue using Resque.
However… Since I'm having sort of a really hard time writing specs for this, I assume this might not be the best approach to send mails.
What I mainly want and need to test:
was the mail added to the queue?
is InviteMailer working properly?
does the mail contain the correct vital information?
Vital informations are: sent to the correct person, contains a link to a specific site and some specific data/text; also I'm not sure how to get the current host to the link.
I don't think this is a rare thing to do, so I wonder what the best practices are.
My testing environment: rspec, capybara, factory girl. I already added VCR, to cache the API-request.
You can use Mailcatcher to fake your mail server, and check received mail via web API:
Features
Catches all mail and stores it for display.
Shows HTML, Plain Text and Source version of messages, as applicable.
Rewrites HTML enabling display of embedded, inline images/etc and open links in a new window. (currently very basic)
Can send HTML for analysis by Fractal.
Lists attachments and allows separate downloading of parts.
Download original email to view in your native mail client(s).
Command line options to override the default SMTP/HTTP IP and port settings.
Mail appears instantly if your browser supports WebSockets, otherwise updates every thirty seconds.
Growl notifications when you receive a new message.
Runs as a daemon run in the background.
Sendmail-analogue command, catchmail, makes using mailcatcher from PHP a lot easier.
Written super-simply in EventMachine, easy to dig in and change.
How
gem install mailcatcher
mailcatcher
Go to http://localhost:1080/
Send mail through smtp://localhost:1025
API
A fairly RESTful URL schema means you can download a list of messages
in JSON from /messages, each message's metadata with
/messages/:id.json, and then the pertinent parts with
/messages/:id.html and /messages/:id.plain for the default HTML
and plain text version, /messages/:id/:cid for individual
attachments by CID, or the whole message with /messages/:id.source.

Stress test Rails app with mailers

I have a Rails 3.1 app deployed to Heroku. This app makes heavy use of mailers. I'm looking for a way to run a sort of integration-stress test. In other words, I would like to automate integration tests that cover from user action to email receipt (not simply delivery), and I want to use these test to stress-test the app. As Heroku runs everything in production mode, I'm can't run this server-side.
(I'm happy enough to script the actual user interaction, though I'm interested in suggestions. What's really tripping me up is actual email receipt. What would I use to monitor incoming emails? I'd like to not use a separate tool, and I'd prefer not to check that emails were received after testing, as I would like my stress test to also calculate elapsed time between user interaction and email receipt, etc.)
I don't think you can avoid using a separate tool if you actually want to check the messages were received at the end point. I wrote a blog post on a number of options for receiving emails.
Since you're running things locally and don't nessesarily need to be performant it might actually be enough for your tool to connect via pop3 or imap and download the email to check it was delivered.

Receive mail in Ruby/Rails

How would i go about to receive mails in a Ruby on Rails application without going through a mail server like PostFix or to fetch them by pop3 etc.
What i was to do is to catch all mails sent to #mydomain.com and just do something with them in my application. I don't need to store the mails or anything like that.
Is this posible?
I just implemented this for my SAAS to autoprocess mailer-bounce notification messages.
Call me, call you?
You call me
You can set up a local mail server. It would then respond to an incoming email, and start up a rails executable to process the email. This method is NOT recommended since starting up rails is a big task (takes multiple secs and lots of memory). You don't want a Rails bad boy started up just because you received an email. You'd be writing your own DDOS attack. (Attacking yourself.)
I call you
Instead, poll for email on your own schedule by using a single job to process all currently waiting emails. You need to set up a background job handler since stock rails is focused on responding to web requests. I use delayed_job, but there are other alternatives including kicking off a cron job every so in often.
Another benefit is that you don't need to manage a mail server. Leave that headache to someone else. Then use the Ruby library net::imap to read the incoming mail and process it.
If your process doesn't recognize the email format, then forward the msg to a human for processing.
And be sure that if the process sends mail in addition to reading/processing it, that the process uses a different email address as its From address. Otherwise, odds are good that sometime along the way, you'll end up in an email loop and many gigabytes of messages going back and forth. For example, your process receives a message, responds to it, but in the meantime the sender (a human) has switched on vacation response. And your robot then responds to the vacation response..... oops....
Writing your own mail server
Re:
How would i go about to receive mails in a Ruby on Rails application without going through a mail server like PostFix or to fetch them by pop3 etc.
What i was to do is to catch all mails sent to #mydomain.com and just do something with them in my application. I don't need to store the mails or anything like that.
Direct answer: Yes, you could do this by writing an smtp server and setting up dns so your machine will be the mail destination for the domain. Your smtp server would process the messages on the fly, they would not be stored on your system at any point.
Is this a good idea? No, not at all. While appearances may be to the contrary, email is a store and forward system. Trying to avoid storing the messages before your app processes them is not smart. It would be a very very poor "optimization." However, using an access protocol (POP3 or IMAP) is a good way to avoid the costs of installing, configuring and managing a mail server.
You can do this if you write your own mail server, or if your mail server supports hooks to run external programs upon receipt of mail (e.g. procmail).
If you don't have procmail available (or, if on something like Exchange Server, don't feel like writing custom rules or extensions), you're simply better off using a pop3 library to fetch mail.
Obviously, writing a mail server is more difficult than any of the alternatives.
If you're mostly worried about checking potentially hundreds of email accounts, that's solvable by configuring your email server properly. If you're on a hosted provider, ask your server administrator about creating a "catch-all" account that routes all mail to unknown addresses to a single account.
If you're aiming to avoid having to poll a server, consider the IMAP IDLE command. I've successfully written a Ruby client that opens a connection to an IMAP server, and gets told by the server when new mail arrives.

Can I look at Mailer views without actually sending an e-mail?

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 :)

Resources