ActionMailer 3 error - undefined method `encode!' for "Welcome":String - ruby-on-rails

I'm getting this error while sending mail to the registered user in rails 3:
undefined method 'encode!' for "Welcome":String
I have the following code
#content = content
mail(:to => content[:email], :subject => "test")
If there is a subject then above error message displaying, if I remove the subject content
#content = content
mail(:to => content[:email], :subject => "") no error message sending with out subject
I'm using:
Rails version 3.0.1
action mailer 3.0.1

mail gem checks for Encoded global constant. If its defined by any gem or your code then it calls encode! on the mail object. Here is this call from UnstructuredField mail gem class:
def encode(value)
value.encode!(charset) if defined?(Encoding) && charset
(value.not_ascii_only? ? [value].pack("M").gsub("=\n", '') : value).gsub("\r", "=0D").gsub("\n", "=0A")
end
For me it was mail subject, a String, so I monkey patched String:
class String
def encode!(value)
#Do any encoding or simply return it
value
end
end

Try using ruby version 1.9
I got this error while using devise with rails 3.0.3 and ruby 1.8.7.
I migrated to ruby 1.9 and it worked like a charm.

Related

NoMethodError Ruby 1.9.3

I am using Ruby 1.9.3 and getting the following error on the following line while trying to use the SendGrid API.
ERROR [on this line below "mailer.mail(mail_defaults)"]:
NoMethodError (undefined method `to_h' for #<Hash:0x00000005da0958>):
CODE:
assuming some users
recipients = []
recipient = SendGrid::Recipient.new('jn#geo.com')
recipient.add_substitution('name', 'Billy Bob')
recipient.add_substitution('number', 1234)
recipient.add_substitution('time', '10:30pm')
recipients << recipient
# then initialize a template
template = SendGrid::Template.new('blahblah7bef2-d25b00')
# create the client
# see client above
# set some defaults
mail_defaults = {
:from => 'no-reply#geo.com',
:html => '<h1>I like email tests</h1>',
:text => 'I like email tests',
:subject =>'Test Email is great',
}
mailer = SendGrid::TemplateMailer.new(client, template, recipients)
# then mail the whole thing at once
mailer.mail(mail_defaults)
I thought it might be my mail_defaults array so I tried this (see below) and received the same error on the same line.
mail_defaults = {
from: 'no-reply#geo.com',
html: '<h1>I like email tests</h1>',
text: 'I like email tests',
subject: 'Test Email is great',
}
Do I have an error in my code or is their an error in SendGrids mailer.mail method?
This problem is with mail.mailer. This uses the to_h method internally, which was implemented in Ruby 2.1. Effectively, the sendgrid sdk requires ruby 2.1 now. I had the same issue with Ruby 1.9.3 and solved it by upgrading to 2.1.
This is what I used to upgrade to Ruby 2.1 on CentOS 6 (not my gist):
https://gist.github.com/mustafaturan/8290150
Hope this helps.

rails saving recognized link from text to database with rinku

I have a rails app with chat. In the chat for the messages I use rinku gem to recognize links which works well. On the top of this I would like to save the links as message.link without the rest of the text around it from the message.body.
So for example in the code below the user sent the message.body "hi there www.stackoverflow.com" and I would like to save only the "www.stackoverflow.com" as message.link. How can I do that?
view
<p><%= find_links(message.body) %></p>
controller
def find_links(message_body)
Rinku.auto_link(message_body, mode=:all, 'target="_blank"', skip_tags=nil).html_safe
end
it will appear in the DOM as:
<p>hey there http://stackoverflow.com/</p>
and will appear in the db as message.body:
"hey there http://stackoverflow.com/"
UPDATE:
messages controller
require "uri"
def create
.....
if message.save
link = URI.extract(message.body)
update_attribute(message.link = link)
end
You need regular expression to identify URLs from text. Try following regular expression:
/(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/
Working demo: http://rubular.com/r/bHQdFHZYFH
2.1.2 :001 > str = "hey hi hello www.google.com https://stackoverflow.com http://tech-brains.blogspot.in"
2.1.2 :002 > regexp = /(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/
2.1.2 :003 > str.scan(regexp)
=> [["www.google.com"], ["https://stackoverflow.com"], ["http://tech-brains.blogspot.in"]]
You can use Ruby code:
2.0.0-p247 :001 > require "uri"
=> true
2.0.0-p247 :002 > URI.extract("hey there http://stackoverflow.com/")
=> ["http://stackoverflow.com/"]
Hope it helps!

ActionMailer::Base::NullMail when trying exception_notification in development

I'd like to add the exception_notification gem to our app, however, this happens when I try to manually trigger a mail:
exception
# => #<ZeroDivisionError: divided by 0>
ExceptionNotifier::Notifier.exception_notification(request.env, exception)
# => #<ActionMailer::Base::NullMail:0x007fa81bc7c610>
ExceptionNotifier::Notifier.background_exception_notification(exception)
# => #<ActionMailer::Base::NullMail:0x007fa81bf58190>
In the above example, the console is at a breakpoint inside rescue_from Exception in the ApplicationController after a deliberate 1/0 in some controller.
I'm using delayed_job as well, but - no surprise - ExceptionNotifier::Notifier.background_exception_notification(exception).deliver does not spool anything.
I've already set config.consider_all_requests_local = false in development, but still exception_notification instantiates NullMail. In other parts of the app, mailers work just fine and use sendmail.
Any ideas what I'm doing wrong here? Thanks for your help!
Likely you are using an old version of the ExceptionNotifier and a newer version of ActiveMailer::Base. Not calling the mail command within the email functionality will result in the ActionMailer::Base::NullMail instance returned rather than a Mail instance.
From documentation:
class Notifier < ActionMailer::Base
default :from => 'no-reply#example.com',
:return_path => 'system#example.com'
def welcome(recipient)
#account = recipient
mail(:to => recipient.email_address_with_name,
:bcc => ["bcc#example.com", "Order Watcher <watcher#example.com>"])
end
end
I had my tests / rspec returning NullMail objects. the solution was simple, my code was:
def my_mail(foo)
mail(
to: to,
from: from,
subject: #sample_item.campaign_market.campaign.translation_for(language_id, 'sample_item_mailer.request_review.subject'),
content_type: "text/html"
)
#sample_item.update_attributes!({feedback_requested: true, review_requested_at: Time.now})
TrackingService::Event.new(#user, #user.market, 'sample_items', "request_review_email #{#sample_item.id}").call()
end
what's not immediately clear from the ruby docs is that you need to return the mail function,not just execute it. If you need to do something after building the mail object make sure you return the mail at the end. like so:
def my_mail(foo)
m = mail(
to: to,
from: from,
subject: #sample_item.campaign_market.campaign.translation_for(language_id, 'sample_item_mailer.request_review.subject'),
content_type: "text/html"
)
#sample_item.update_attributes!({feedback_requested: true, review_requested_at: Time.now})
TrackingService::Event.new(#user, #user.market, 'sample_items', "request_review_email #{#sample_item.id}").call()
return m
end

ActionMailer Observer not working

I defined an ActionMailer Observer and it's not being called. How can I go about troubleshooting this? Rails 3.1.3, Ruby 1.9.2. Alternatively, I want a method called whenever an email is sent form a certain ActionMailer subclass. This is the only clean way I could find to implement this (I could call a method from each mailing method in the ActionMailer subclass, but that's not very DRY). Any other suggestions as to how to accomplish this would be welcome.
config/initializers/mail_observer.rb:
class MailObserver
def self.delivered_email(message)
require 'ruby-debug' ; debugger
user = User.find_by_email(message.to[0])
if user
email_type = caller[1]
UserMailerLogging.create!(user_id: #user.id, email_type: email_type, contents: self.body)
end
end
end
ActionMailer::Base.register_observer(MailObserver)
app/mailers/user_mailer:
class UserMailer < ActionMailer::Base
default from: "no-reply#testing.com"
...
def unfinished_setup(user)
#user = user
mail to: user_email(user), subject: "Testing..."
end
...
end
And, in the Rails Console:
irb(main):001:0> UserMailer.unfinished_setup(User.find(1))
=> #<Mail::Message:70192154395900, Multipart: false, Headers: <From: no-reply#testing.com>, <To: Test User<user#testing.com>>, <Subject: Testing...>, <Mime-Version: 1.0>, <Content-Type: text/plain>>
I believe the observer won't fire until you actually deliver the message. Your code in the rails console is only creating the email, not sending it. Adding .deliver to the end should deliver the message and execute the observer code.

Rails: Amazon aws-ses, missing required header 'From'

Email from Ruby code is sending without any issue. But when I try to send it from Rails console, it gives the Missing required header 'From' error even From is specified in the email (Notifier), see below:
def send_email(user)
recipients "#{user.email}"
from %("Name" "<name#domain.com>")
subject "Subject Line"
content_type "text/html"
end
Here is email sending code from rails console:
ActionMailer::Base.delivery_method = :amazon_ses
ActionMailer::Base.custom_amazon_ses_mailer = AWS::SES::Base.new(:secret_access_key => 'abc', :access_key_id => '123')
Notifier.deliver_send_email
Am I missing something?
GEMS used: rails (2.3.5), aws-ses (0.4.4), mail (2.3.0)
Here is how it was fixed:
def send_email(user)
recipients "#{user.email}"
from "'First Last' <name#domain.com>" # changing the FROM format fixed it.
subject "Subject Line"
content_type "text/html"
end

Resources