I'm having trouble sending mail using SMTP from a Rails app. I have a Mailer class:
class Mailer < ActionMailer::Base
def newsletter_confirmation(subscription)
recipients "my-valid-email#gmail.com" # this is set to my email
# just for testing purposes and will
# be changed to subscription.email
from "\"my-valid-helo-domain.net\" <noreply#my-valid-helo-domain.net>"
subject "Confirm your subscription"
body :subscription => subscription
end
end
When I try to send the mail, I get a Net::SMTPSyntaxError:
501 <["noreply#my-valid-helo-domain.net"]>: missing or malformed local part
If I comment out the from field, the mail gets delivered ok, but with the from information missing (obviously). Any ideas on what I'm doing wrong?
Thanks.
Edit: I'm using Rails 2.3.2 and Ruby 1.9.1
The error code and the description of the error states that this is an error on the mail server.
I suggest you check the mail servers to pinpoint the error.
When it comes to ActionMailer it is supposed to raise an exception if the configuration parameter raise_delivery_errors is set (default in Production but not in Development I believe), so you can check that one and try to resend if it triggers.
EDIT:
Here is the solution (it's a Ruby/Rails 1.9 bug):
https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/2340-action-mailer-cant-deliver-mail-via-smtp-on-ruby-191
and the patch:
https://rails.lighthouseapp.com/projects/8994/tickets/2340/a/104008/action_mailer-ruby-1.9-from-address-fix.patch
It is a known bug. https://rails.lighthouseapp.com/projects/8994/tickets/2340
Related
When I try to send e-mails with Sidekiq (5.1.3) and Rails (5.1.6) in production using ActiveJob's deliver_later, e-mails are not being sent (deliver_now works fine). The job gets processed and Sidekiq reports it as such. The logs show a successful start & done:
2018-09-14T14:12:18.031Z 14029 TID-mncgx ActionMailer::DeliveryJob JID-665575b056e61ef84a434c97 INFO: done: 0.84 sec
The only thing missing is the delivery of the actual e-mail. I've enabled 'raise_delivery_errors', but nothing is being raised. I'm sending my email through Mailgun.
I'm inclined to think something's going wrong with Sidekiq, because I had ActiveJob configured before (with the default adapter, :async) and deliver_later worked properly. Only after adding Sidekiq it stopped working. I've tried it with many different e-mails and in the end I created an extremely simple mailer, just for debugging this issue.
Here's the code of my 'job':
SimpleMailer.test.deliver_later
And here's the code of my mailer:
class SimpleMailer < ApplicationMailer
# Subject can be set in your I18n file at config/locales/en.yml
# with the following lookup:
#
# en.simple_mailer.test.subject
#
def test
#greeting = "Hi"
mail to: xx, from: xx, subject: 'Well hello"
end
Thanks a lot in advance! I've been searching for quite some time now and have lost almost all inspiration - any help (on where to look) would be amazing. I could also provide more info, but I don't really know what's more to provide.
In my plugin for Discourse I am trying to send an email to a user.
This works just fine if I hardcode my own API functionality to do so, however in an effort to make this public I was trying to use the built in emailing. I cannot however get an email to send.
I have tried:
def self.send_user_email(address)
message = Mail::Message.new(from: "from#fromEmail.com", to: address, body: "hello")
Email::Sender.new(message, :admin_login).send # I used admin_login as according to the spec it should send even if email is disabled.
end
When I do this however I am getting an error:
NoMethodError - undefined method `deliver_now' for #<Mail::Message:0x007fa1bf157300>
Did you mean? deliver:
mail (2.6.6) lib/mail/message.rb:1379:in `method_missing'
So if I go and update line 184 of sender.rb in Discourse to use #deliver instead of #deliver_now, I am able to get it to kinda try to send an email on my development environment.
Rails 4.2 deprecated deliver / deliver! in favor of deliver_now / deliver_now!. (Pull Request)
http://guides.rubyonrails.org/4_2_release_notes.html#action-mailer-deprecations
Rails 5.0 removed deprecated deliver and deliver! methods. (commit)
http://guides.rubyonrails.org/5_0_release_notes.html#action-mailer-removals
This is the reason why you are getting the error. Rails applications >= 5.0 will have this error until the source code you referred to is updated.
Since upgraded to Ruby 2.2.0 I get the following message in my tests:
invalid salt (BCrypt::Errors::InvalidSalt)
I didn't find any upgrade notice helping me to understand the problem. I'm using Rails 4.1.8 and Sorcery 0.8.6.
Anybody else having this problem?
MORE Details:
I'm using Sorcery and not Devise. The encrypted data is the password.
It all started in Cucumber tests, in 2 cases:
When I used to send the #user to the mailer to prepare the data for the mails. Here was the code:
UserMailer.passphrase_reset_notification(#user).deliver
Which generated the exception with the message I wrote in the initial message. As a workaround instead of sending the #user I sent the fields I needed and it worked. Here's the new code:
UserMailer.passphrase_reset_notification(#user.name, #user.email).deliver
But the second case is the sign up. It failed in dev and I had to add :salt to user_params to fix it. But it does not fix the thing in the test env.
There's no stack trace, just that one liner message with the lines of my scenario leading to the error.
And I press "Sign up"
invalid salt (BCrypt::Errors::InvalidSalt)
./app/controllers/users_controller.rb:66:in block in create'
./app/controllers/users_controller.rb:64:increate'
./app/controllers/application_controller.rb:120:in scope_current_tenant'
./features/step_definitions/web_steps.rb:53:in/^(?:|I )press "([^"]*)"$/'
features/users/sign_up.feature:149:in `And I press "Sign up"'
I removed the "null: false" for the field "salt" in the user table, as suggested by a community member in a post on a more or less similar issue, it didn't help either.
My main question is still the same: what the Ruby new version (2.2.0) has to do with this? And what might be the other surprises if I upgrade the prod?
I just fixed this. Turned out it had to do with serializing an object with has_secure_password (which uses bcrypt-ruby)
More specifically, something like the following was causing the issue with Sidekiq as it tried to serialize arguments into objects for Redis queueing.
#user = User.new(
:firstname => 'Scott',
:lastname => 'Klein',
:password => 'mypass',
:password_confirmation => 'mypass'
)
#user.save!
# broken
# note that #user.password can still be called here
# and sidekiq will attempt to serialize this whole object using YAML
# and this is the serialization issue that barfs (in the depths of YAML)
UserMailer.delay.new_user_signup(#user)
# fixed
# i just passed the id and then recalled the user record in the mailer class
UserMailer.delay.new_user_signup(#user.id)
I've had similar problem. Investigation made me conclude that it's bcrypt not playing well with Psych (that's the Ruby system library for generating and parsing YAML).
There's an open bcrypt issue now. Waiting for gem author to fix it.
** FIXED **
The problem, at least mine, is fixed. I just upgraded the bcrypt gem from 3.1.
9 to 3.1.10 and it was it! Thanks Oleg to have created an issue on bcrypt account.
In my project, I'm using Rails 4.1.1 and Ruby 2.1.1. I was reading the mail gem, but wasn't sure how to check if the deliver failed (for any reason).
result = UserMailer.signup.deliver
if result.action == 'failed' or result.bounced?
# How can you tell if a deliver has failed?
# Do stuff here if failed
end
As described in http://guides.rubyonrails.org/action_mailer_basics.html, you can set
config.action_mailer.raise_delivery_errors = true
this way, Rails will raise an error in case the delivery can't take place
I am having a slightly odd problem with sending mail in test mode with Rails 3
It seems that my mailers are not returning anything. For example I have a mailer called UserMailer. Users can make changes that require approval in the app so this has a method called changes_approved that should send the user an email notifying them that their changes have been approved.class
UserMailer < ActionMailer::Base
default :from => "from#example.com"
def changes_approved(user, page)
#user = user
#page = page
mail(:to => user.email, :subject => "Your changes have been approved")
end
end
In my controller I have the following line
UserMailer.changes_approved(#page_revision.created_by, #page_revision.page).deliver
However my tests fail at this point with the error:
undefined method `deliver' for nil:NilClass
When I trigger the same actions on the development site tho (http://localhost:3000 through a browser), the emails are sent out correctly and everything works quite happily
And to add further confusion, I am using devise for authentication and the emails for that seem to be working correctly both in test and development modes. Certainly I am not getting this same error and according to my email-spec tests, everythings working
So this leads me to believe that I have a problem with my mailers rather than my test mail config per se but I have no idea what. Any suggestions would be much appreciated
Thanks
I used https://gist.github.com/1031144
to convert
# Rails 2 method:
UserMailer.should_receive(:deliver_signup)
to
# Cumbersome Rails 3 method:
mailer = mock
mailer.should_receive(:deliver)
UserMailer.should_receive(:signup).and_return(mailer)
I had a similar problem - probably the UserMailer.changes_approved method is being replaced with a mock method, which returns nil (I wasn't using shoulda for that test, but that's my best guess).
My code looked like this (modified to use your example):
UserMailer.expects(:changes_approved).once
I fixed it with an additional stub:
#mailer = stub(:deliver)
UserMailer.expects(:changes_approved).once.returns(#mailer)
The nil is now replaced with #mailer.
To test the delayed action mailer we need to first change the configuration of delayed_job (in config/initializers/delayed_job_config.rb) to
Delayed::Worker.delay_jobs = !Rails.env.test?
and in your tests the expectation should be set to
mock_mail = mock(:mail)
mock_mail.should_receive(:deliver)
UserMailer.should_receive(:changes_approved).with(user, page).and_return(mock_mail)
Well I have found the answer,
it looks like the problem was in the way I was testing these mailers. In each of the controller tests I had a line similar to
UserMailer.should_receive(:changes_approved).with(user, page)
Whilst this test was passing fine, it appeared to break the mailer itself. I have removed this line from the tests and now they pass ok. Subsequent tests against ActionMailer::Base.deliveries.last to check the details of the sent email are correct appear to be ok so I am happy that this line is not neccessary.
If anyone has an explanation as to why this breaks tho, I would be interested to find out
Thanks anyways