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
Related
I am using Active Merchant gem to handle payments through the site. But now i want to make these payments recurring, on a monthly basis. Is there a way using active merchant or?
subscription_controller.rb
class SubscriptionsController < ApplicationController
def new
#home_page = true
#white = true
#subscription = Subscription.new(token: params[:token])
if !logged_in?
redirect_to signup_url
end
end
def create
#subscription = Subscription.new(subscription_params)
#subscription.remote_ip = request.remote_ip
#subscription.user_id = current_user.id
if #subscription.save
if #subscription.purchase
#subscription.send_thank_you_email
redirect_to thankyou_path
else
raise ActiveRecord::Rollback
flash[:notice] = "It seems something went wrong with the paypal transaction. Please check that your credit card is valid and has credit in it and try again."
redirect_to :back
end
else
flash[:notice] = "Something went wrong with marking your purchase as complete. Please contact support to check it out."
redirect_to :back
end
end
def purchase
response = GATEWAY.setup_purchase(999,
ip: request.remote_ip,
return_url: new_subscription_url,
cancel_return_url: root_url,
currency: "USD",
items: [{name: "Order", description: "Recurring payment for ******", quantity: "1", amount: 999}]
)
redirect_to GATEWAY.redirect_url_for(response.token)
end
def thank_you
#home_page = true
#white = true
end
private
def subscription_params
params.require(:subscription).permit(:token)
end
end
subscription.rb model
def purchase
response = GATEWAY.purchase(999, express_purchase_options)
response.success?
end
def token=(token)
self[:token] = token
if new_record? && !token.blank?
# you can dump details var if you need more info from buyer
details = GATEWAY.details_for(token)
puts details.params["PayerInfo"]["PayerName"].inspect
self.payer_id = details.payer_id
self.first_name = details.params["PayerInfo"]["PayerName"]["FirstName"]
self.last_name = details.params["PayerInfo"]["PayerName"]["LastName"]
end
end
# send thank you email
def send_thank_you_email
UserMailer.thank_you(self).deliver_now
end
private
def express_purchase_options
{
:ip => remote_ip,
:token => token,
:payer_id => payer_id
}
end
production.rb environment
config.after_initialize do
ActiveMerchant::Billing::Base.mode = :production
::GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(
:login => ENV['PAYPAL_LOGIN'],
:password => ENV['PAYPAL_PASSWORD'],
:signature => ENV['PAYPAL_SIGNATURE']
)
end
I think ActiveMerchant used to have something like this:
subscription = PAYPAL_EXPRESS_GATEWAY.recurring(#subscription.price_in_cents, nil,
:description => 'blah',
:start_date => Date.tomorrow,
:period => 'Year',
:frequency => 1,
:amount => price,
:currency => 'USD'
)
See this answer Does ActiveMerchant support Subscription Based transaction
Also see this: https://github.com/activemerchant/active_merchant/blob/master/lib/active_merchant/billing/gateways/paypal_express.rb
https://github.com/activemerchant/active_merchant/blob/master/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb
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 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 }
I am sending an email in my Rails 2 app and after a bit of hacking and learning about emails in Rails it now works fine.
Now I am just trying to add an attachment which in theory should probably be straightforward but I seem to be having issues with it.
I am using mailcatcher to preview the emails in the development environment and I can see the attachment headers in the email source but nothing is shown in mailcatcher (docs say it supports attachments)
emailer.rb
class Emailer < ActionMailer::Base
def quotation_notification(q)
#recipients = q.recipient_email
#from = q.partner_name + "<#{q.partner_email}>"
#subject = "New Quotation from " + q.partner_name
#sent_on = Time.now
#quote_id = q.quote_id
#customer_id = q.customer_id
#customer_name = q.customer_name
#recipient_email = q.recipient_email
#partner_name = q.partner_name
#partner_email = q.partner_email
#partner_ref = q.partner_ref
#version_no = q.version_no
#line_items = q.line_items
#quotation_date = q.quotation_date
content_type "multipart/alternative"
part "text/html" do |p|
p.body = render_message("quotation_notification.text.html.rhtml", :message => q)
end
attachment :content_type => "application/pdf",
:body => File.read(RAILS_ROOT + '/pdfs/' + q.quote_id + '.pdf')
#body[:q] = q
end
end
The email is being sent in a controller like so
q = QuotationEmail.new(quote_id, customer_id, customer_name, recipient_email, partner_name, partner_email, partner_ref, version_no, line_items, quotation_date)
# send email
Emailer.deliver_quotation_notification(q)
Just for completeness, my view is app/views/emailer/quotation_notification.text.html.rhtml
quotation_email.rb
class QuotationEmail
attr_accessor :quote_id, :customer_id, :customer_name, :recipient_email, :partner_name, :partner_email, :partner_ref, :version_no, :line_items, :quotation_date
def initialize(quote_id, customer_id, customer_name, recipient_email, partner_name, partner_email, partner_ref, version_no, line_items, quotation_date)
#quote_id = quote_id
#customer_id = customer_id
#customer_name = customer_name
#recipient_email = recipient_email
#partner_name = partner_name
#partner_email = partner_email
#partner_ref = partner_ref
#version_no = version_no
#line_items = line_items
#quotation_date = quotation_date
end
end
In the source of the email, after the closing html tag I can see
--mimepart_522da7e7e5959_a0885cd9314396
Content-Type: application/pdf
Content-Transfer-Encoding: Base64
Content-Disposition: attachment
*base 64 encoded stuff*
--mimepart_522da7e7e5959_a0885cd9314396--
If I have done anything bonkers then it is because I haven't sent any emails in Rails yet so still figuring things out.
I can only assume this was a problem with mailcatcher, by setting up development emails to be sent to a gmail account, the emails were sent correctly with attachments.
environments/development.rb
config.action_mailer.raise_delivery_errors = true
config.action_mailer.perform_deliveries = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "domain.co.uk",
:user_name => "gmailaddress#domain.co.uk",
:password => "accountpassword",
:authentication => :plain,
:enable_starttls_auto => true #This line is must to ensure the tls for Gmail
}
I used an existing app email address hosted on gmail, so not strictly an username#gmail.com / username#googlemail.com but I would think that those addresses would also work with the above.
I used to have this code for sending mails:
class MailTimerMailer < ActionMailer::Base
def mail_schedule(from, to, cc, bcc, subject, message, files=[], sent_at = Time.now)
#subject = subject
#recipients = to
#from = from
#cc = cc
#bcc = bcc
#sent_on = sent_at
#body["message"] = message
#headers = {}
# attache files
files.each do |file|
attachment file.mimetype do |a|
a.body = file.binarydata
a.filename = file.filename
end
end
end
end
It no longer works. I do not have a view for my mails, as the complete message comes from outside my method. I have tried to modify my code to Rails 3 like this:
class ScheduleMailer < ActionMailer::Base
def mail_schedule(from, to, cc, bcc, subject, message, files=[], sent_at = Time.now)
#subject = subject
#recipients = to
#from = from
#cc = cc
#bcc = bcc
#sent_on = sent_at
#body["message"] = message
#headers = {}
# attache files
files.each do |file|
attachments[file.filename] = File.read("public/data/" << file.id.to_s() << "." << file.extension)
end
end
end
This code sends a mail with the attachements, but there are no actual message in the mail. It also gives me a deprecation warning "Giving a hash to body is deprecated, please use instance variables instead". I have tried with "body :message => message" but no luck.
How can I get this working again?
Thank you
This is how:
class MyMailer < ActionMailer::Base
def mail_schedule(from, to, cc, bcc, subject, message, files=[], sent_at = Time.now)
# attache files
files.each do |file|
attachments[file.filename] = File.read("public/data/" << file.id.to_s() << "." << file.extension)
end
mail(:from => from, :to => to, :cc => cc, :bcc => bcc, :subject => subject) do |format|
format.text { render :text => message }
end
end
end