Why is it that this method produces an empty variable and therefore empty body?
custom_email.text.erb
<%=#message%>
user_mailer.rb
default from: "Name <name#domain.com>"
def custom_email(email, subject, message)
mail to: email, subject: "Name || #{subject}"
#message = message
end
While this method works:
mail to: email, subject: "Name || #{subject}", body: message
write this
default from: "Name <name#domain.com>"
def custom_email(email, subject, message)
#message = message
mail to: email, subject: "Name || #{subject}"
end
instead of
default from: "Name <name#domain.com>"
def custom_email(email, subject, message)
mail to: email, subject: "Name || #{subject}"
#message = message
end
then it will consider #message
Related
How can I check the content of a bounced email?
require "rails_helper"
RSpec.describe EventsMailbox do
it "requires a current user" do
expect(mail_processed).to have_bounced
# here I would like to check the content of the bounced email
end
def mail
Mail.new(
from: "dorian#dorianmarie.fr",
subject: "Some subject",
body: "Some body"
)
end
def mail_processed
#mail_processed ||= process(mail)
end
end
Here is how I did it, the key was that perform_enqueued_jobs that allows emails to be retrieved from ActionMailer::Base.deliveries:
require "rails_helper"
RSpec.describe EventsMailbox do
include ActiveJob::TestHelper
around(:each) { |example| perform_enqueued_jobs { example.run } }
it "requires a current user", focus: true do
expect(mail_processed).to have_bounced
expect(last_delivery.from).to eq(["contact#socializus.app"])
expect(last_delivery.to).to eq(["dorian#dorianmarie.fr"])
expect(last_delivery_text).to(
include("You need to be registered on Socializus")
)
end
def mail
Mail.new(
from: "dorian#dorianmarie.fr",
to: "party#events.socializus.app",
subject: "Some subject",
body: "Some body"
)
end
def mail_processed
#mail_processed ||= process(mail)
end
def last_delivery
ActionMailer::Base.deliveries.last
end
def last_delivery_text
return unless last_delivery
text_part = last_delivery.parts.detect { _1.mime_type == "text/plain" }
return unless text_part
text_part.body.to_s
end
end
I have a customer mailer set up with devise as you can see below:
class DeviseMailer < Devise::Mailer
default from: "hello#example.com"
def mandrill_client
#mandrill_client ||= Mandrill::API.new MANDRILL_API_KEY
end
def confirmation_instructions(record, token, opts={})
template_name = "user-confirm-account"
template_content = []
message = {
to: [{email: record.email}],
subject: "Confirm Your account",
merge_vars: [
{rcpt: record.email,
vars: [
{name: "CONFIRM_ACCOUNT_LINK", content: "#{root_url}users/confirmation?confirmation_token=#{token}"},
]
}
]
}
mandrill_client.messages.send_template template_name, template_content, message
end
def reset_password_instructions(record, token, opts={})
template_name = "user-forgot-password"
template_content = []
message = {
to: [{email: record.email}],
subject: "Password Reset",
merge_vars: [
{rcpt: record.email,
vars: [
{name: "PASSWORD_RESET_LINK", content: "#{root_url}users/password/edit?reset_password_token=#{token}"},
]
}
]
}
mandrill_client.messages.send_template template_name, template_content, message
end
def unlock_instructions(record, token, opts={})
# code to be added here later
end
end
This works great. I did this so that I could customise confirmation emails sent by Mandrill. In order to send the confirmation email I call the following:
#user.send_confirmation_instructions
This works but I want to be able to send a different template for confirmation_instructions depending on a parameter I pass to the mailer. Such as source=contactform. How would I include a parameter in my #user.send_confirmation_instructions code and then retrieve it in the mailer? Thanks! :)
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
According to these docs on Rspec matchers, calling an_instance_of is another way of calling instance_of?(Class). When I test in the console, this works fine, but in my spec it fails.
In console:
m = Mail.new
=> #<Mail::Message:70144097437100, Multipart: false, Headers: >
m.instance_of?(Mail::Message)
=> true
Failure:
1) IncomingEmailsController should deliver the email with lead info
Failure/Error: post :create, to: "me#example.com", text: "Content", html: "HTML Content", from: "email#example.com", subject: "Jimmy Bean"
<UserMailer (class)> received :forward_email with unexpected arguments
expected: (#<RSpec::Mocks::ArgumentMatchers::InstanceOf:0x007feff35fd148 #klass=Mail::Message>)
got: (#<Mail::Message:70334278571020, Multipart: true, Headers: <From: email#example.com>, <To: me#example.com>, <Subject: Jimmy Bean>, <Content-Type: multipart/alternative; boundary=--==_mimepart_50c1ffa9e2ba2_2e1e3ff7f8c35ad49574>>, nil)
incoming_emails_controller_spec.rb
describe IncomingEmailsController do
it "should deliver the email with lead info" do
# expect
UserMailer.should_receive(:forward_email).with(an_instance_of(Mail::Message))
# when
post :create, to: "me#example.com", text: "Content", html: "HTML Content", from: "email#example.com", subject: "Jimmy Bean"
end
end
incoming_emails_controller.rb
def create
# create a Mail object from the params sent by Sendgrid
prepare_email(params) #returns #email (instance of Mail::Message)
UserMailer.forward_email(#email).deliver
end
private
def prepare_email(params)
email = Mail.new
email.to = params["to"]
email.from = params["from"]
email.subject = params["subject"]
text_part = Mail::Part.new
text_part.body = params["text"]
html_part = Mail::Part.new
html_part.content_type = 'text/html; charset=UTF-8'
html_part.body = params["html"]
email.text_part = text_part
email.html_part = html_part
#email = email
end
It looks like this was solved: https://github.com/rspec/rspec-mocks/issues/202.
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