problem with Actionmailer "Timeout::Error"? - ruby-on-rails

im trying to send a email with action mailer and it gives me a Timeout::Error (execution expired): even though in the console it says that the e mail is sent:
it shows
Sent mail to aldeirm2#gmail.com
then displayes the e mail that was sent then it shows the following error:
Timeout::Error (execution expired):
/usr/lib/ruby/1.8/timeout.rb:60:in `open'
/usr/lib/ruby/1.8/net/smtp.rb:551:in `do_start'
/usr/lib/ruby/1.8/net/smtp.rb:551:in `do_start'
/usr/lib/ruby/1.8/net/smtp.rb:525:in `start'
app/models/appointment.rb:10:in `tomorrows_appointments'
app/models/appointment.rb:8:in `each'
app/models/appointment.rb:8:in `tomorrows_appointments'
app/controllers/show_appointments_controller.rb:11:in `send_email'
-e:2:in `load'
-e:2
Rendered rescues/_trace (35.8ms)
Rendered rescues/_request_and_response (0.3ms)
Rendering rescues/layout (internal_server_error)
here is my settings:
config.cache_classes = false
config.whiny_nils = true
config.action_controller.consider_all_requests_local = true
config.action_view.debug_rjs = true
config.action_controller.perform_caching = false
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:enable_starttls_auto => true,
:address => "smtp.gmail.com",
:port => 587,
:domian => "gmail.com",
:authentication => :login,
:user_name => "username",
:password => "blablabla",
}
i also tried setting authentication to :plain and using username#gmail.com as the user_name with no hope.
any ideas

I saw a typo there: you wrote
:domian => "gmail.com",
instead of
:domain => "gmail.com",

SMTP requests seem to time out occasionally, probably depending on how long you've set for timeouts. The other problem you'll get is a delay in the web-app while the user waits for your server to communicate with Gmail's SMTP server.
I know gmail is a popular option for new rails apps, but I don't think it's a long-term solution since you have to send the mail through a particular gmail account which has daily sending limits. And even with other accounts, I have found that SMTP timeouts are a problem.
Now I am using SendGrid to send emails and have found that using sendgrid as a relayhost via postfix is the favourable option. This means the user gets a response from the web-app faster and the mail is queued through postfix and then sent via sendgrid (so no more timeouts!).
See here for sendgrid's postfix setup instructions:
http://wiki.sendgrid.com/doku.php?id=postfix
Then, in your rails environment, you just need something like the following:
config.action_mailer.delivery_method = :sendmail
config.action_mailer.sendmail_settings = {
:location => '/usr/sbin/sendmail',
:arguments => '-i -t'
}

In case anyone else has the same problem:
make sure that your firewall allows outgoing connections to port 587
For iptables, you can list all existing rules with:
sudo iptables -L
have a look here for the necessary rules.
If you're using an AWS instance, have a look at your security groups.

Related

Emails send from rails with O365 being rejected as spam

I have a Rails 5 app deployed on Heroku. I'm using devise for email and have setup everything correctly to send password reset emails. This works perfectly in my dev environment. However, when I send from production I get an error in my 0365 inbox that says:
Generating server: CO2PR13MB0140.namprd13.prod.outlook.com
myemail#gmail.com
Remote Server returned '550 5.7.708 Service unavailable. Access denied, traffic
not accepted from this IP. For more information please go to
http://go.microsoft.com/fwlink/?LinkId=526653 AS(8561)
[CO2PR13MB0124.namprd13.prod.outlook.com]'
Original message headers:
Received: from CO2PR13MB0140.namprd13.prod.outlook.com
([fe80::c872:9c6:9d6a:8b3]) by CO2PR13MB0140.namprd13.prod.outlook.com
([fe80::c872:9c6:9d6a:8b3%4]) with mapi id 15.20.1339.019; Wed, 14 Nov 2018
02:42:20 +0000
MIME-Version: 1.0
Content-Type: text/plain
Date: Wed, 14 Nov 2018 02:42:20 +0000
Message-ID:
<5beb8b87e888a_42b06292aba70609bd#01184e4c-2116-478b-a773-fcc26ac206aa.mail>
Subject: Reset password instructions
In looking into this, and talking to support, it appears that the it's being rejected because a third party server is (my app on Heroku I'm assuming) is trying to send out the email with 0365 settings.
Here are my development.rb settings that work perfectly:
# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = true
config.action_mailer.perform_caching = true
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => 'smtp.office365.com',
:port => '587',
:authentication => :login,
:user_name => ENV['365_USERNAME'],
:password => ENV['365_PASSWORD'],
:domain => 'mysite.com',
:enable_starttls_auto => true
}
Here are my production.rb settings that cause O365 to reject the email. I've tried playing with these quite a bit. And I've ensured that the "from" email matches the login email. i.e. I'm not trying to send from no-reply#mysite.com or similar.
config.action_mailer.raise_delivery_errors = true
config.action_mailer.perform_caching = false
config.action_mailer.default_url_options = { :host => 'www.mysite.com' }
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => 'smtp.office365.com',
:port => '587',
:authentication => :login,
:user_name => ENV['365_USERNAME'],
:password => ENV['365_PASSWORD'],
:domain => 'mysite.com',
:enable_starttls_auto => true
}
From discussions with support. I may need to add an SPF TXT record to allow emails to be sent from a remote server. The problem is, I have no idea what to add to the SPF record. My current spf record is:
v=spf1 include:spf.protection.outlook.com -all
Their response just says they have blacklisted your IP, so it’s not down to your message content.
If you are sending from Heroku, you may need to list them in your SPF as well. Also ensure that your host name resolves backwards as well as forwards - that should be possible in Heroku’s control panel.
Once you’ve done that, check your SPF record gives a pass to your message source using kitterman.com or mxtoolbox testing services.
O365’s spam filter and blocking policy is pretty bad anyway, however I have had success in asking their support to remove blocks, though you need to persevere because they reject all such requests by default. This is poor service, but it’s still far better than you will get from gmail.

SMTP connection timing out

I'm pulling my hair out trying to debug an 'execution expired' error while sending email through Rails' ActionMailer, and having no luck. I don't think that it's a Rails problem as the connection also times out when executing telnet smtp.gmail.com 587 from the terminal as well.
The output when executing the telnet command is:
Trying 2607:f8b0:400d:c07::6c...
telnet: connect to address 2607:f8b0:400d:c07::6c: Operation timed out
Trying 74.125.192.108...
Connected to gmail-smtp-msa.l.google.com.
Escape character is '^]'.
220 smtp.gmail.com ESMTP z32sm7598799qtz.0 - gsmtp
My settings are in config/development.rb as follows:
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "gmail.com",
:user_name => ENV['GMAIL_USERNAME'],
:password => ENV['GMAIL_PASSWORD'],
:authentication => "plain",
:enable_starttls_auto => true
}
The stack trace is as follows:
Completed 500 Internal Server Error in 30095ms (ActiveRecord: 1.0ms)
Net::OpenTimeout - execution expired:
/Users/yawn/.rbenv/versions/2.1.2/lib/ruby/2.1.0/timeout.rb:114:in `timeout'
/Users/yawn/.rbenv/versions/2.1.2/lib/ruby/2.1.0/net/smtp.rb:550:in `do_start'
/Users/yawn/.rbenv/versions/2.1.2/lib/ruby/2.1.0/net/smtp.rb:520:in `start'
mail (2.6.4) lib/mail/network/delivery_methods/smtp.rb:113:in `deliver!'
mail (2.6.4) lib/mail/message.rb:2149:in `do_delivery'
mail (2.6.4) lib/mail/message.rb:237:in `block in deliver'
...
/Users/yawn/.rbenv/versions/2.1.2/lib/ruby/2.1.0/webrick/server.rb:295:in `block in start_thread'
I have also tried turning on "Allow access for less secure apps" in Gmail, and have tried my personal gmail address as well as a custom domain Google Apps domain. I initially tried it with only the custom domain Google Apps address and thought that maybe Namecheap blocks SMTP connections the same way that I've read that Digital Ocean does, but the problem persisting with a simple #gmail address seems to rule that out.
When I was going down that path, I also tried adding:
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
to /etc/sysctl.conf, but to no avail.
My thinking is now that maybe it's just my ISP blocking SMTP connections and if I were to deploy this to production that maybe it would just work? But I really don't know.
Thanks in advance.

Send Devise E-mails using Mandrill in Production

I'm trying to send the Devise e-mails from my Rails 4 app. I don't want to change the templates or anything, I just want to use Mandrill to deliver the messages in the production environment.
My production.rb is like this:
config.action_mailer.raise_delivery_errors = true
config.action_mailer.perform_deliveries = true
config.action_mailer.default_url_options = {:host => 'sociedadeavalia.com.br'}
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => "smtp.mandrilapp.com",
:port => 587,
:user_name => ENV['MANDRILL_USERNAME'],
:password => ENV['MANDRILL_APIKEY'],
:authentication => 'login',
:enable_starttls_auto => true,
:domain => 'sociedadeavalia.com.br'
}
I have this in my devise.rb
config.mailer_sender = 'no-reply#sociedadeavalia.com.br'
config.mailer = 'MyDeviseMailer'
And I created the following mailer:
class MyDeviseMailer < Devise::Mailer
helper :application
include Devise::Controllers::UrlHelpers
default template_path: 'devise/mailer'
end
Now Whenever i try to send an email in production (the confirmation email for creating a new user account) my app just crashes and this appears in the log:
31 <190>1 2014-12-03T22:17:07.987969+00:00 app web.1 - - Net::OpenTimeout (execution expired):
What should I do in this case?
It looks like you might be having an issue with the port being blocked. We'd recommend the troubleshooting steps here. More specifically, try changing the port you're using - 2525 is often not blocked, or use 465 with SSL enabled. Many hosts block 25 and 587 to help prevent spam.
Try changing the authentication to 'plain'. That is what is working for me.
:authentication => 'plain',

What causes a End Of File Error when Rails Mailer sends an email?

A Rails 3.2.8 application developed with a gmail account as the "sending address".
When mail sending works my environment.rb file contains this:
ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "gmail.com",
:authentication => :login,
:user_name => "accountname",
:password => "123456789"
}
I get this message in my application log:
EOFError (end of file reached):
when the above code is changed to what is shown below:
ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
:address => "mail.company.com",
:port => 25,
:domain => "company.com",
:authentication => :login,
:user_name => "accountname",
:password => "123456789"
}
I can tell you I -am- able to send a manual email message to the email address
and see it arrive when using a email client such as ThunderBird, thus I know
the accountname#company.com is functional.
I don't understand how an end of file error comes into play.
I also cannot figure out how to get more information to appear in the log.
I look forward to reading a few suggestions of determining the cause of the End Of File.
Started POST "/sendInvites?locale=en&lot_id=18&user_id=17" for 99.99.99.99 at 2013-10-03 08:52:09 -0700
Processing by WaitingListsController#sendInvites as HTML
Parameters: {"authenticity_token"=>"uwz/6pW1rLPXR4gU3m3OwCmU0O3DSJ/haNM2/ai+OR8=", "locale"=>"en", "lot_id"=>"18", "user_id"=>"17"}
=======>>>> Beginning Send Invitation Process <<<<=======
=======>>>> just before the PassEmailer.requestApprovedWL IS called to send the invitation <<<<=======
>>>> Beginning ::: requestApprovedWL(user_info) <<<<=======
Rendered pass_emailer/requestApprovedWL.erb (0.9ms)
>>>> at the end of ::: requestApprovedWL(user_info) <<<<=======
Completed 500 Internal Server Error in 1718ms
EOFError (end of file reached):
app/controllers/waiting_lists_controller.rb:276:in `sendInvites'
For anyone still experiencing this issue, Whenever appears to default to Production. It is using your Production variables (or looking for them) while in your Development or Staging. Also, per the docs it does not load the Rails environment.
While you are in development or staging you must manually let schedule.rb know this. After finding the File.expand_path method here, the following is how I start my schedule.rb file:
require File.expand_path(File.dirname(__FILE__) + "/environment")
set :environment, Rails.env
set :output, Rails.root.join('log','cron.log')
This provides you the Rails environment and allows you to also set the path for logging.

Can't send mail with gmail smtp server (in discourse)

I'm trying to setup discourse, which is a rails3 webapp, but have some problems configuring smtp with gmail smtp server.
I have registered a new gmail account yesterday, and I can logged in browser and email-client software.
Then I configure discourse, in the file config/environments/production.rb:
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
:port => "587",
:user_name => "smtp4shuzu#gmail.com",
:password => "12345678",
:authentication => :plain,
:domain => "shuzhu.org",
:enable_starttls_auto => true
}
Start the sidekiq which is used to sending the mails in the background:
nohup bundle exec sidekiq > log/sidekiq.log 2>&1 &
Then start discourse in production mode:
rails server -e production -d
But it doesn't work. I can see some errors in sidekiq.log:
2013-03-01T03:06:02Z 30687 TID-qib28 WARN: {"retry"=>true, "queue"=>"default", "class"=>"Jobs::UserEmail", "args"=>[{"type"=>"signup", "user_id"=>42, "email_token"=>"b40a21ece2b14586e346abfd96685975", "current_site_id"=>"default"}], "jid"=>"558bb6bd5aa36cfc8d3d1e91", "error_message"=>"Connection refused - connect(2)", "error_class"=>"Errno::ECONNREFUSED", "failed_at"=>2013-03-01 03:06:02 UTC, "retry_count"=>0}
2013-03-01T03:06:02Z 30687 TID-qib28 WARN: Connection refused - connect(2)
2013-03-01T03:06:02Z 30687 TID-qib28 WARN: /home/discourse/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1/net/smtp.rb:540:in initialize'
/home/discourse/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1/net/smtp.rb:540:inopen'
/home/discourse/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1/net/smtp.rb:540:in `tcp_socket'
I have tried all kinds of smtp settings, but none of them works.
UPDATE:
Per #Basil's answer, I just tried:
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:user_name => "smtp4shuzu",
:password => "12345678",
:authentication => "plain",
:enable_starttls_auto => true
}
But it has the same error. The domain shuzu.org is the domain of my site, I was thinking I should passing it to smtp. Now I removed it, but still not working.
At last, I found the (stupid) reason.
I should start sidekiq in production mode:
nohup bundle exec sidekiq -e production > log/sidekiq.log 2>&1 &
Try removing the quotes around the port
:port => 587,
Also, I don't understand why your email address is #gmail but your domain is #shuhzu... smtp settings should show the domain for your email account. If you have a custom gmail, i.e me#custom.com then domain would be custom.com. Here is an example of what smtp settings for your domain should be if you have a custom email address:
{
:address => "smtp.gmail.com",
:port => 587 ,
:domain => "custom.com",
:user_name => "some_email#custom.com",
:password => "some_password",
:authentication => "plain",
:enable_starttls_auto => true
}
Sometimes it is useful to uncomment the following line in /var/discourse/containers/app.yml:
## If you want to set the 'From' email address for your first registration, uncomment and change:
## After getting the first signup email, re-comment the line. It only needs to run once.
- exec: rails r "SiteSetting.notification_email='noreply#YOURDOMAIN.com'"
You should put here the address on behalf of which all Discourse's emails should come. By default Discourse will try to use your forum's domain name, but it may not be allowed by your SMTP. For example, your forum is at forum.example.com, while your Gmail SMTP only allows emails from example.com.
For SMTP without authentication just leave the auth fields like this:
DISCOURSE_SMTP_USER_NAME:
DISCOURSE_SMTP_PASSWORD:
and after everything is saved:
./launcher rebuild app
Once emails are working, you can re-comment this line (with SiteSetting).
You can even just set this SiteSetting via console, but it's more difficult than uncommenting/re-commenting a single line and re-build the container, so I'll not elaborate on this.
On my install, which is one of those pre-made image thingies (Bitnami), I just had to run this:
/opt/discourse-0.9.5-0/ctlscript.sh start discourse_sidekiq
Anyone know how I can automate this so that it happens on startup?
I just set up a new discourse instance in a docker container on my own ubuntu physical on site server and edited the app.yml to contain:
DISCOURSE_SMTP_ADDRESS: 'smtp.gmail.com'
DISCOURSE_SMTP_AUTHENTICATION: 'plain'
DISCOURSE_SMTP_PORT: 587
DISCOURSE_SMTP_USER_NAME: 'my.name#gmail.com'
DISCOURSE_SMTP_PASSWORD: 'myPa$$word'
DISCOURSE_SMTP_ENABLE_START_TLS: true
and it worked. Half the battle was knowing where to put single inverted commas (') and where not to.
Another way was available to me also - my ISP provides a relay smtp for it's static IP customers so I used this in app.yam:
DISCOURSE_SMTP_ADDRESS: mail.myisp.tld
DISCOURSE_SMTP_AUTHENTICATION: none
DISCOURSE_SMTP_PORT: 25
and it works for me also.

Resources