I am trying to send email in Rails.
The code is
class UserMailer < ActionMailer::Base
default :from => "from#example.com"
def send_password_reset(player)
Rails.logger.info "Password email"
#player = player
delivery_options = {
user_name: 'sites.smtp#mymail.com',
password: 'password',
address: 'smtpout.secureserver.net'
}
mail(to: player.email,
subject: "Recover your Password.",
body: "Password email",
delivery_method_options: delivery_options)
end
end
Controller
if player.valid?
player.send_password_reset_token #(Line: 209)
render json: {SENT: 'YES'}
else
render json: {error: "Player does not exist."}, status: :not_found
end
Model
def send_password_reset_token
password_reset_token = SecureRandom.urlsafe_base64(nil, false)
self.update_attribute(:password_reset_token, password_reset_token)
UserMailer.send_password_reset(self).deliver #(line: 25)
end
The logger says
Sent mail to ranasaani#gmail.com (25ms)
Completed in 433ms
NoMethodError (undefined method `encoding' for #<Hash:0x774b2d51>):
app/models/player.rb:25:in `send_password_reset_token'
app/controllers/players_controller.rb:209:in `password_forgot'
But I am not receiving any email and here is not any method encoding. Then what is causing this error
have u setup your mailer.rb like this
ActionMailer::Base.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "your.domain.com",
:user_name => ENV['MY_GMAIL_USER_NAME'],
:password => ENV['MY_GMAIL_PASSWORD'],
:authentication => "plain",
:enable_starttls_auto => true }
Related
I attempted to send reset password email through a namecheap domain. I have reviewed every solution offered within StackOverflow and have not been able to get a viable solution. Let me know if I am missing any details below.
My Rails application is an API only.
It was working via gmail connection/smtp and when I switched it over to the namecheap/privateemail smtp it worked once.
After it worked locally I uploaded the code to heroku and that's when it started to fail.
# config/environments/development.rb
config.action_mailer.delivery_method = :sendmail
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
config.action_mailer.default_options = {from: 'noreply#domainemail.com'}
config.action_mailer.default_url_options = { :host => '587'}
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: 'mail.privatemail.com',
port: 587,
domain: 'domainname.com',
user_name: ENV['EMAIL'],
password: ENV['EMAIL_PW'],
authentication: :plain,
enable_starttls_auto: true,
openssl_verify_mode: 'none',
ssl: true
}
Production:
config.cache_classes = true
config.action_mailer.delivery_method = :sendmail
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
config.action_mailer.default_options = {from: 'noreply#domainname.com'}
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: 'mail.privatemail.com',
port: 587,
domain: 'domainname.com',
user_name: ENV['EMAIL'],
password: ENV['EMAIL_PW'],
authentication: :plain,
enable_starttls_auto: true,
openssl_verify_mode: 'none'
}
NotifierMailer class
class NotifierMailer < ApplicationMailer
default_url_options[:host] = ENV['BACKEND_URL']
default from: 'noreply#domainemail.com'
def create
admin = Admin.find_by(email: params[:email])
admin.generate_password_reset_token!
Notifier.password_reset(admin).deliver
end
def password_reset(admin)
#admin = admin
#url = "#{ENV['BACKEND_URL']}/password/reset?token=#{#admin.reset_password_token}&email=#{#admin.email}"
mail(to: "#{#admin.first_name} #{#admin.last_name} <#{#admin.email}>",
subject: "Ion Portal - Password Reset")
end
end
Password controller
class PasswordController < ApplicationController
protect_from_forgery with: :null_session
# include ActionController::RequestForgeryProtection
# protect_from_forgery with: :exception, unless: -> { request.format.json? }
def forgot
puts params
if params[:email].blank? # check if email is present
render json: {
error: "Email not present"
}
end
admin = Admin.find_by(email: params[:email]) # if present find admin by email
if admin.present?
admin.generate_password_token! #generate pass token
NotifierMailer.password_reset(admin).deliver_now
render json: { status: 'ok' }
else
render json: { error: ["Email address not found. Please check and try again."]}, status: :not_found
end
end
def reset
token = params[:token].to_s
if params[:email].blank?
return render json: {error: "Token not present"}
end
admin = Admin.find_by(reset_password_token: token)
if admin.present? && admin.password_token_valid?
if admin.reset_password!(params[:password])
redirect_to "#{ENV['ION_URL']}"
else
render json: {error: admin.errors.full_messages}, status: :unprocessable_entity
end
else
render json: { error: ["Link not valid or expired. Try generating a new link."]}, status: :not_found
end
end
def update
if !params[:password].present?
render json: {error: 'Password not present'}, status: :unprocessable_entity
return
end
if current_user.reset_password(params[:password])
render json: {status: 'ok'}, status: :ok
else
render json: {errors: current_user.errors.full_messages}, status: :unprocessable_entity
end
end
def successful_reset
render success_path
end
end
These settings worked for me. Turned out I also had left the settings for MailCatcher as well, that was my initial problem. Double check as well that what the domain setting and server address match, which in development, would mean setting the domain to 'localhost:3000'. Good luck!
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => 'mail.privateemail.com',
:port => 587,
:domain => 'localhost:3000',
:user_name => 'email#email.com',
:password => 'xxxxxxxxxxxxxxx',
:authentication => :plain,
:enable_starttls_auto => true,
}
After 24 hours of trial and error I had to remove a couple of lines of code to make it work.
config.action_mailer.smtp_settings = {
# For Gmail
# :address => "smtp.gmail.com",
# :port => "587",
# :domain => "gmail.com",
# :user_name => "noreply#gmail.com",
# :password => "pasword!",
# :authentication => "plain",
# :enable_starttls_auto => true
# For Namecheap
:enable_starttls_auto => true, #this is the important stuff!
:address => 'smtp.privateemail.com',
:port => 587,
:domain => 'privateemail.com',
:authentication => :plain,
:user_name => 'noreply#domainname.com',
:password => 'password!'
}
I removed the following:
enable_starttls_auto: true,
openss
l_verify_mode: 'none'
I am trying to send mail in production environment as follow:
in user-mailer.rb:
class UserMailer < ActionMailer::Base
default to: "a.b#gmail.com"
def feedBack_mail(email,message)
#mess=message
#url = 'http://www.google.com'
mail(from: email, subject: 'new_feedback')
end
end
in feedback_mail.text.erb
<%= #mess %>
in user_controller.rb
def create
respond_to do |format|
#client= params[:client]
if UserMailer.feedBack_mail(params[:email],params[:message]).deliver
format.json { render json: #client, status: :created, location: #client }
else
format.json {render json: #client.errors, status: :unprocessable_entity}
end
end
end
in production.rb I add this configuration:
if config.respond_to?(:action_mailer)
# config.action_mailer.raise_delivery_errors = false
config.action_mailer.default_url_options = { :host => 'monsite.com' }
# ActionMailer Config
# Setup for production - deliveries, no errors raised
config.action_mailer.delivery_method = :smtp
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = false
config.action_mailer.default :charset => "utf-8"
config.action_mailer.smtp_settings = {
address: "smtp.gmail.com",
port: 25,
domain: "monsite.com",
authentication: "plain",
enable_starttls_auto: true,
user_name: ENV["GMAIL_USERNAME"],
password: ENV["GMAIL_PASSWORD"]
}
end
what I got in production.log
I, [2015-02-17T15:38:05.436159 #2003552] INFO -- : Started POST "/feedback/send.json" for 197.14.10.26 at 2015-02-17 15:38:05 +0100
I, [2015-02-17T15:38:05.473826 #2003552] INFO -- : Processing by UsersController#create as JSON
I, [2015-02-17T15:38:05.473943 #2003552] INFO -- : Parameters: {"email"=>"c.d#gmail.com", "message"=>"qerfsertq", "user"=>{"email"=>"c.d#gmail.com", "message"=>"qerfsertq"}}
I, [2015-02-17T15:38:05.524701 #2003552] INFO -- : Rendered user_mailer/feedBack_mail.text.erb (0.5ms)
I, [2015-02-17T15:38:08.673302 #2003552] INFO -- :
Sent mail to a.b#gmail.com (755.5ms)
I, [2015-02-17T15:38:08.674260 #2003552] INFO -- : Completed 201 Created in 3200ms (Views: 0.3ms | ActiveRecord: 0.0ms)
But I do not get any mail sent to a.b#gmail.com not even as spam
I really could not understand where's the problem
I solved the problem by creating a Mandrill account and changing the configuration like follow:
config.action_mailer.smtp_settings = {
:port => '587',
:address => 'smtp.mandrillapp.com',
:user_name => 'xxxxxxxx',
:password => 'xxxxxx',
:domain => 'domain.com',
:authentication => :plain
}
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
config.action_mailer.default_url_options = { host: "monsite.com" }
In order_mailer.rb:
default from: 'notifications#example.com'
def welcome_email(order)
#user = "Uday kumar das"
#url = 'http://example.com/login'
mail(to: 'dasudaykumar017#gmail.com', subject: 'Welcome to My Awesome Site')
end
In orders_conroller:
def delivery
#order1 = Order.where(:orderId=>params[:orderId])
#order = Order.find(#order1)
OrderMailer.welcome_email(#order).deliver
end
In environments/development.rb:
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
I am new to mails in rails.I am referring http://guides.rubyonrails.org/action_mailer_basics.html to learn. I am getting error like:
Net::SMTPAuthenticationError in OrdersController#delivery`
530-5.5.1 Authentication Required. Learn more at`
I did the same using my gmail, following are my configurations, try and see it if works
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
ActionMailer::Base.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:authentication => :plain,
:user_name => "<my gmail>#gmail.com",
:password => "<my gmail password>",
:openssl_verify_mode => 'none' }
Please note the:
:openssl_verify_mode => 'none'
section to skip the ssl errors
I have a Payment mailer class that creates email:
class PaymentMailer < ActionMailer::Base
include LocaleWrapper
helper :application
def payment_notification(payment)
host = payment.try(:host)
#payment = payment
#user = payment.user
using_locale((#user && #user.locale) || I18n.locale) {
attachments["#{set_default_domain_name_from(host)}_receipt_#{Time.now.strftime("%Y_%m_%d")}.pdf"] = WickedPdf.new.pdf_from_string(
render_to_string(pdf: "#{set_default_domain_name_from(host)}_receipt_#{Time.now.strftime("%Y_%m_%d")}.pdf", template: filtre_mail_template_by_host(host), layout: "pdf.html"))
headers['Precedence'] = 'bulk'
mail(:to => #user.email, :subject => I18n.t("mailer_subjects.payment_completed"), :from => "no-reply##{set_default_domain_name_from(host)}") do |format|
format.text(:content_transfer_encoding => "base64")
format.html
end
}
end
I have observer method that saves email in the database:
def delivered_email(email)
Rails.logger.info email.inspect
html_body = (email.multipart? ? email.html_part : email).body.to_s
text_body = (email.multipart? ? email.text_part : email).body.to_s
outgoing_mail = OutgoingMail.new({
:to => email.to.join(', '),
:from => email.from.join(', '),
:subject => email.subject.to_s,
:sent_at => email.date,
:html_body => html_body,
:text_body => text_body,
:multipart => email.multipart?,
})
outgoing_mail.save
save_attachments(email, outgoing_mail)
end
Problem is with multipart email's plain text version, which returns ASCII 8bit string and mysql throws Mysql2::Error: Incorrect string value error.
(rdb:1) text_body
"N\x16\xA7\x93*.~\x8A\xF2\xA2\xEA\xDC\xA2{k\x89\xBB\xAD\x8A\x89\xD2y\xEA]}\xABmi\xC8fz{_\xA2\xBAZ\xCAg\xA7\xB5\xD7\xADj)l"
(rdb:1) text_body.encoding
#<Encoding:ASCII-8BIT>
I have tried using #force_encoding method, but there is no success:
(rdb:1) text_body.force_encoding("UTF-8")
"N\u0016\xA7\x93*.~\x8A\xF2\xA2\xEAܢ{k\x89\xBB\xAD\x8A\x89\xD2y\xEA]}\xABmi\xC8fz{_\xA2\xBAZ\xCAg\xA7\xB5\u05EDj)l"
Why am i getting ASCII 8bit string instead of UTF-8?
I'm just about in the finishing stages of my website, however I am having trouble with the ActionMailer. It prints out the message just fine, I'm just eager to know how to wire it so it can send to gmail account. I'm primary confused how to route it and configure it properly. I have a contact page that has a model that takes parameters like the recipient, subject, message and the time it was sent: Mailer model: Note all this code is on a local machine
class UserEmail < ActionMailer::Base
default from: 'XXX#gmail.com'
def contact(sender, subject, message, sent_at = Time.now)
#sender = sender
#message = message
#sent_at = sent_at.strftime("%B %e, %Y at %H:%M")
mail(:subject => subject)
end
end
Here's the about controller which the contact methods lie in:
class AboutController < ApplicationController
# ...\controllers\home_controller.rb
#----------------------------------------------------
# show contact form
def contact
#title = "Contact"
#sender = ''
#subject = ''
#message = ''
end
def sendmail
#sender = params[:sender]
#subject = params[:subject]
#message = params[:message]
if validate(#sender, #subject, #message)
UserEmail.contact(#sender, #subject, #message).deliver
flash[:success] = "Your message sent sucessfully!"
redirect_to about_index_path
else
flash.now[:error] = "Your message did not send"
redirect_to about_index_path
end
end
private
def validate(sender, subject, message)
#email_regex = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
if sender.blank? || subject.blank? || message.blank?
#error = "Message not sent: Required information not filled"
return false
elsif subject.length >= 50
#error = "Message not sent: Subject must be smaller than 50 characters"
return false
elsif sender[#email_regex].nil?
#error = "Message not sent: Email not valid"
return false
else
return true
end
end
end
Now this is where I am lost.
Here's what my route like to the mailer. Is this routed appropriately?:
match '/contact_email', :to => 'about#sendmail'
When I configure the mailer, does the code rest in the application.rb or the development.rb? Here's what I have in my application.rb:
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:user_name => 'XXX#gmail.com',
:password => 'XXX',
:authentication => 'plain',
:enable_starttls_auto => true,
}
Thanks in advance!
Change
def contact(sender, subject, message, sent_at = Time.now)
#sender = sender
#message = message
#sent_at = sent_at.strftime("%B %e, %Y at %H:%M")
mail(:subject => subject)
end
to
def contact(sender, subject, message, recipient, sent_at = Time.now)
#sender = sender
#message = message
#sent_at = sent_at.strftime("%B %e, %Y at %H:%M")
#recipient = recipient
mail(:subject => subject, :to => #recipient)
end
And don't forget to set recipient in your calling function.
Have you put the following lines in development.rb
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true