I am using mailgun-ruby to send emails in my rails app.
I have activated a number of domains on my Mailgun account and for each ActionMailer I wish to choose a specific domain to send emails from.
The gem's documentation only explains a global way of setting mailgun_settings:
config.action_mailer.delivery_method = :mailgun
config.action_mailer.mailgun_settings = {
api_key: 'api-myapikey',
domain: 'mydomain.com'
}
Any suggestion how this can be done per ActionMailer?
I came up with a self crafted design for this:
class ApplicationMailer < ActionMailer::Base
before_action do
#layout = 'mailer'
#from = 'default#domain.com'
#to = 'default_to#domain.com'
#subject = 'Default Subject'
#domain = 'default.domain.com'
#params = {}
end
after_action do
ac = ActionController::Base.new()
mg = Mailgun::Client.new 'key-xxxxxxxxx'
message_params = {
from: #from,
to: #to,
subject: #subject,
text: ac.render_to_string("#{self.class.to_s.underscore}/#{action_name}.text", layout: #layout, locals: #params),
html: ac.render_to_string("#{self.class.to_s.underscore}/#{action_name}.html", layout: #layout, locals: #params)
}
mg.send_message #domain, message_params
end
end
class UserMailer < ApplicationMailer
before_action do
#from = 'Domain <updates#domain.com>'
#domain = 'updates.domain.com'
end
def test
#to = "yourself#gmail.com"
#subject = "Test"
#params = {}
end
end
Customize user_mailer/test.txt.erb and user_mailer/test.html.erb and send the email:
UserMailer.test
Related
I'm using Rails 4.2, sidekiq, rubyzip, axlsx and axlsx-rails
What I need to do:
I need to export file in a mail, but as a link and not as attachment.
I want an email send with a url to the download for it
Problem:
I don't know how to do it with this gem, in the git documentation there's nothing about it and every url I use don't work. I need to know how to create a download link for it and not as attachment to the mail
Code:
controller:
def export
export_args = {account_id: current_account.id}
ExportReportJob.perform_later(export_args)
redirect_to action: :index
end
job:
def perform(export_args)
begin
export_failed = false
account = Admin::Account.find_by(id: export_args[:account_id])
account.connect_to_target_db
#accounts = Admin::Account.active_accounts
file_name = "#{Time.now.strftime("%d_%m_%Y_at_%I_%M%p")}_export.xlsx"
dir_path = "#{Rails.root}/public/exports"
FileUtils.mkdir_p(dir_path) unless File.directory?(dir_path)
file_location = "#{absolute_path}/#{file_name}"
Admin::Mailer.export(account.pi, #accounts, file_location).deliver
rescue => e
export_failed = true
Airbrake.notify(e, environment_name: Rails.env, error_message: "export account failed #{e.message}")
ensure
ActiveRecord::Base.clear_active_connections!
end
end
template:
wb = xlsx_package.workbook
wb.add_worksheet(name: "Accounts") do |sheet|
sheet.add_row ["Account id", "Account name", "Organization"]
accounts.each do |account|
sheet.add_row [account.id, accoount.name, account.organization_id]
end
end
xlsx_package.to_stream.read
mailer:
def export(member, accounts, file_location)
#member = member
#title = "Export"
#header = subject = "Your Export is Ready"
#link = file_location
xlsx = render_to_string(layout: false, handlers: [:xlsx], template: "export.xlsx.axlsx", locals: {accounts: accounts})
# attachment = Base64.encode64(xlsx)
# attachments["export_#{DateTime.now.strftime("%d_%m_%Y_%HH%MM")}.xlsx"] = {mime_type: Mime::XLSX, content: attachment, encoding: 'base64'}
# ^ this is not what I want, I want to get the url for it and insert to #link
mail(:to => member.email, :subject => subject) do |format|
format.html
end
end
mail template:
= render partial: 'header'
= h_tag 'The export you requested has been completed'
= button 'Download the file', #link, { download: true }
= p_tag '(the file download will expire after <b>2</b> days)'
= render partial: 'footer'
Given that my RewardMailer has the following preview:
class RewardMailerPreview < ActionMailer::Preview
#mailman = 'mailman#mailman.ninja'
#alice = User.create(email: 'ali#example.com')
#bob = User.create(email: 'ali#example.com')
#subject = 'I Vooshed my website'
#btc_address = '1BitcoinKKKKKKKK'
#amount = 0.004
# Preview this email at http://localhost:3000/rails/mailers/reward_mailer/invoice_due
def invoice_due
RewardMailer.invoice_due(
alice: #alice,
subject: #subject,
btc_address: #btc_address
)
end
end
I get the following error:
NoMethodError in Rails::MailersController#preview
undefined method `email' for nil:NilClass
Extracted source (around line #13):
11 #alice = invoice_info[:alice]
12 #subject = invoice_info[:subject]
13 mail to: #alice.email, subject: #subject
14 end
my RewardMailer has the action:
def invoice_due(invoice_info)
#btc_address = invoice_info[:btc_address]
#alice = invoice_info[:alice]
#subject = invoice_info[:subject]
mail to: #alice.email, subject: #subject
end
and is tested with:
test 'invoice_due' do
mail = RewardMailer.invoice_due(
alice: alice,
subject: subject,
btc_address: btc_address
)
assert_equal subject, mail.subject
assert_equal [alice.email], mail.to
assert_equal [mailman], mail.from
assert_match btc_address, mail.body.encoded
end
You set #alice at a class level, but you're trying to read it from an instance. I suppose you do that to share variable initialization code across different emails? You could do this way:
class RewardMailerPreview < ActionMailer::Preview
def set_defaults
#mailman = 'mailman#mailman.ninja'
#alice = User.create(email: 'ali#example.com')
#bob = User.create(email: 'ali#example.com')
#subject = 'I Vooshed my website'
#btc_address = '1BitcoinKKKKKKKK'
#amount = 0.004
end
def invoice_due
set_defaults
RewardMailer.invoice_due(
alice: #alice,
subject: #subject,
btc_address: #btc_address
)
end
end
I have included given code
def send_help_enterprise
p '-----------------'
p params
Mailer.help_enterprise_issue(params[:app], params[:version], params[:name], params[:description][:text])
respond_to do |format|
format.js {
render :layout => false
}
end
end
and fetch parameters
{"utf8"=>"✓", "app"=>"test", "version"=>"1.1", "name"=>"faltuz", "description"=>{"text"=>"dcdfwedfed"}, "remotipart_submitted"=>"true", "authenticity_token"=>"rAykheNgAcEZF/M36i+hkpMzs+X1QZA+56hFoXAdQfXyDkGQU7K441nDylKKvj4cuxs/bfJgg7SEM0k9Kr+IGQ==", "X-Requested-With"=>"IFrame", "X-Http-Accept"=>"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01", "file"=>#<ActionDispatch::Http::UploadedFile:0xb483c5d4 #tempfile=#<Tempfile:/tmp/RackMultipart20150916-3796-okttg1.jpeg>, #original_filename="images1.jpeg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"file\"; filename=\"images1.jpeg\"\r\nContent-Type: image/jpeg\r\n">, "controller"=>"enterprises", "action"=>"send_help_enterprise"}
and in my mailer I have included given code
def help_enterprise_issue(app,version,name,description)
#app = app
#version = version
#name = name
#description = description
#email = 'test#gmail.com'
mail :to => #email,
:subject => I18n.t('mailer.info.help_enterprise_issue')
end
Please guide how I can attach file in this mail I want to attach given file which I am fetching in params[:file]. Please help me out in solving this. Thanks in advance
use attachment attribute
attachments['file-name.pdf'] = File.read('file-name.pdf').
def welcome(user)
attachments['file-name.pdf'] = File.read('path/to/file-name.pdf')
mail(:to => user, :subject => "Welcome!")
end
refer this (2.3) :
http://guides.rubyonrails.org/action_mailer_basics.html
Modify your code to this:
def send_help_enterprise
p '-----------------'
p params
Mailer.help_enterprise_issue(params[:app], params[:version], params[:name], params[:description][:text], params[:file])
respond_to do |format|
format.js {
render :layout => false
}
end
end
in your mailer
def help_enterprise_issue(app,version,name,description,file)
#app = app
#version = version
#name = name
#description = description
#email = 'test#gmail.com'
attachments['attachment.extension'] = file
mail :to => #email,
:subject => I18n.t('mailer.info.help_enterprise_issue')
end
Thisshould work
Based on http://guides.rubyonrails.org/action_mailer_basics.html, you have to add attachments['file-name.jpg'] = File.read('file-name.jpg'). So, you can put in this method.
def help_enterprise_issue(app,version,name,description)
attachments['file-name.jpg'] = File.read('file-name.jpg')
#app = app
#version = version
#name = name
#description = description
#email = 'test#gmail.com'
mail :to => #email,
:subject => I18n.t('mailer.info.help_enterprise_issue')
end
I hope it can help you.
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 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