Discourse plugin - sending email - ruby-on-rails

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.

Related

ActionMailer sends emails even though it failed with ArgumentError: A sender required to send a message

Looks like my emails raising errors and sending.
I'm receiving emails and also I get this error on "rake jobs:work" console:
Class#deliver_and_save failed with ArgumentError: A sender (Return-Path, Sender or From) required to send a message - 1 failed attempts
But when I step through my debugger, I can see that there is a from:
> email.from
=> ["my#email.com"]
> email_draft.From
=> Me <my#email.com>
> email_draft.sender
=> nil
> email_draft.Sender
=> nil
> email_draft.reply_to
=> ["my#email.com"]
Is it possible that ActionMailer is throwing the error and still sending? Is this a known issue? The problem I have is that delayed_job keeps sending the email repeatedly.
UPDATE:
def EmailEngine < ActionMailer::Base
# Called with EmailEngine.delay.deliver_and_save(template)
def deliver_and_save(template)
# This appears to be raising the error
email_draft = EmailEngine.send(template) # this will invoke 'mail'
# Saved here to have a better record than the logs provide
Email.create(...
# Yet this still sends
email_draft.deliver
Found the problem!
delayed_job doesn't play super well with rails 3.1 and you have to use this new syntax:
EmailEngine.delay.deliver_and_save(template) # I was already doing this.
which it automatically tries to calls .deliver on the Mail::Message object that deliver_and_save returns. (So there's my problem: trying to call .deliver myself.)
SOLUTION: I rearranged my code and to call Email.create(.. somewhere outside of EmailEngine and then I called EmailEngine.delay.send(template) directly and completely removed deliver_and_save.
Woo!
Btw, any method invoked on a class that inherits from ActionMailer will return a Mail::Message object. ActionMailer does some black magic to make this happen (overwriting Ruby's method_missing so it can render views just like a controller, even though it behaves like a model in many ways).
This is about delayed_job and rails-3-mailer: https://github.com/collectiveidea/delayed_job#rails-3-mailers

NoMethodError: undefined method 'index' when calling deliver on rails 3.1 mailer

I have set up a staging instance of a rails 3.1 application on Heroku and everything seems to work fine except I'm getting a strange error when I try to send emails. I am using the sendgrid starter addon for email delivery. The full error is below:
NoMethodError: undefined method `index' for #<Mail::Message:0x000000048daf28>
/app/.bundle/gems/ruby/1.9.1/gems/mail-2.3.0/lib/mail/message.rb:1289:in `method_missing'
/app/.bundle/gems/ruby/1.9.1/gems/mail-2.3.0/lib/mail/encodings.rb:117:in `value_decode'
/app/.bundle/gems/ruby/1.9.1/gems/mail-2.3.0/lib/mail/encodings.rb:101:in `decode_encode'
/app/.bundle/gems/ruby/1.9.1/gems/mail-2.3.0/lib/mail/fields/unstructured_field.rb:74:in `do_decode'
if I just generate the message object without calling deliver on it and inspect it everything seems fine. I am not seeing this error on my production app. Can you tell me what this error means and how to resolve it? Thanks.
Got the same error on my local machine using Rails 3.0.11. It happened after I passed some object instead of a string to the mail :to attribute. So be sure that the :to attribute is a string!
mail(to: object.to_s)
A new version of Mail, Mail 2.4.0, was released this weekend. I would recommend upgrading to this latest version and seeing if that has fixed your issue.
This error was the result of using Class instead of Module when defining a mail helper I'd created.
This error happened because I was setting custom headers to an integer value. Using to_s on these values resolved the issue for me.
I had a similar problem. However, the error I received was:
NoMethodError (undefined method `ascii_only?' for nil:NilClass)
My problem was I had:
mail(to: emails,....)
And my variable "emails" was actually an array, instead of being one single string of emails.

Can't get ActiveMerchant to respond using rails 3 server

I'm using Rails 3.1 and ActiveMerchant 1.17
I'm calling the PaymentExpress gateway, using the correct test credit card details. However, it keeps giving some form of invalid response.
The most I can make out is that the response.params array contains
{"re_co"=>"Zz", "response_text"=>"Error in getting response.", "success"=>"0"}
This is using the local rails server.
I have a hunch that it may be to do with the SSL verify_peer option, though I have no way of proving that, and I have no idea how to configure that option.
This is my code, fairly standard stuff:
credit_card = ActiveMerchant::Billing::CreditCard.new(params[:credit_card])
gateway = ActiveMerchant::Billing::PaymentExpressGateway.new(:login => APP_CONFIG[:dps_username], :password => APP_CONFIG[:dps_password])
response = gateway.authorize total_cents, credit_card
Interestingly, it seems to work fine from the rails console. Are there any steps I should be taking to debug this?
Ok, it turns out the problem wasn't to do with ActiveMerchant at all.
I should have been using
APP_CONFIG['dps_username']
instead of
APP_CONFIG[:dps_username]
Ahh, the simple problems

Sending emails in test mode with ActionMailer in rails 3

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

Problems with ActionMailer: 501 <>: missing or malformed local part

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

Resources