rails generate ruby-on-rails smtp actionmailer

ruby on rails - generate - Rails ActionMailer con mĂșltiples servidores SMTP



rails generate email (11)

Tengo la necesidad de usar dos servidores smtp diferentes en una aplicación Rails. Parece que la forma en que se construye ActionMailer, no es posible tener diferentes smtp_settings para una subclase. Podría volver a cargar la configuración de smtp para cada clase de correo cada vez que se envíe un mensaje, pero eso confunde el complemento ExceptionNotifier que está fuera de mi control (a menos que yo también lo haga). ¿Alguien tiene una solución / plugin para algo como esto?

Idealmente me gustaría tener

class UserMailer < ActionMailer::Base; end

y luego establecer en environment.rb

ActionMailer::Base.smtp_settings = standard_smtp_settings UserMailer.smtp_settings = user_smtp_settings

Por lo tanto, la mayoría de mis correos, incluido ExceptionNotifier, retomaría la configuración predeterminada, pero UserMailer usaría un servicio de retransmisión pagado.


Aquí hay otra solución que, si bien parece ridícula, creo que es un poco más limpia y más fácil de reutilizar en diferentes clases de AM :: Base:

module FTTUtilities module ActionMailer module ClassMethods def smtp_settings dict = YAML.load_file(RAILS_ROOT + "/config/custom_mailers.yml")[self.name.underscore] @custom_smtp_settings ||= HashWithIndifferentAccess.new(dict) end end module InstanceMethods def smtp_settings self.class.smtp_settings end end end end

ejemplo de correo:

class CustomMailer < ActionMailer::Base extend FTTUtilites::ActionMailer::ClassMethods include FTTUtilites::ActionMailer::InstanceMethods end


Basado en el artículo de Oreilly, se me ocurrió la solución que escribí aquí: http://transfs.com/devblog/2009/12/03/custom-smtp-settings-for-a-specific-actionmailer-subclass

Aquí está el código relevante:

class MailerWithCustomSmtp < ActionMailer::Base SMTP_SETTINGS = { :address => "smtp.gmail.com", :port => 587, :authentication => :plain, :user_name => "[email protected]", :password => ''password'', } def awesome_email(bidder, options={}) with_custom_smtp_settings do subject ''Awesome Email D00D!'' recipients ''[email protected]'' from ''[email protected]'' body ''Hope this works...'' end end # Override the deliver! method so that we can reset our custom smtp server settings def deliver!(mail = @mail) out = super reset_smtp_settings if @_temp_smtp_settings out end private def with_custom_smtp_settings(&block) @_temp_smtp_settings = @@smtp_settings @@smtp_settings = SMTP_SETTINGS yield end def reset_smtp_settings @@smtp_settings = @_temp_smtp_settings @_temp_smtp_settings = nil end end


Cuando quise una prueba rápida en la consola (Rails 5) hice lo siguiente:

settings = { username: "" } # etc mailer = MyMailer.some_method mailer.delivery_method.settings.merge!(settings) mailer.deliver


Intenté usar la opción de jkrall con Rails 3.2.1, pero por alguna razón no anularía la configuración predeterminada, pero si lo hacía:

class UserMailer < ActionMailer::Base def welcome_email(user, company) @user = user @url = user_url(@user) delivery_options = { user_name: company.smtp_user, password: company.smtp_password, address: company.smtp_host } mail(to: @user.email, subject: "Please see the Terms and Conditions attached", delivery_method_options: delivery_options) end end

Similar a http://www.scottw.com/multiple-smtp-servers-with-action-mailer , lo hizo funcionar.




Rieles-2.3. *

# app/models/user_mailer.rb class UserMailer < ActionMailer::Base def self.smtp_settings USER_MAILER_SMTP_SETTINGS end def spam(user) recipients user.mail from ''[email protected]'' subject ''Enlarge whatever!'' body :user => user content_type ''text/html'' end end # config/environment.rb ActionMailer::Base.smtp_settings = standard_smtp_settings USER_MAILER_SMTP_SETTINGS = user_smtp_settings # From console or whatever... UserMailer.deliver_spam(user)


Solución para Rails 3.2:

class SomeMailer < ActionMailer::Base include AbstractController::Callbacks after_filter :set_delivery_options private def set_delivery_options settings = { :address => ''smtp.server'', :port => 587, :domain => ''your_domain'', :user_name => ''smtp_username'', :password => ''smtp_password'', :authentication => ''PLAIN'' # or something } message.delivery_method.settings.merge!(settings) end end

Solución inspirada en Cómo enviar correos electrónicos con múltiples smtp dinámicos usando Actionmailer / Ruby on Rails


Solución para Rails 4.2+:

config / secrets.yml :

production: gmail_smtp: :authentication: "plain" :address: "smtp.gmail.com" :port: 587 :domain: "zzz.com" :user_name: "[email protected]" :password: "zzz" :enable_starttls_auto: true mandrill_smtp: :authentication: "plain" :address: "smtp.mandrillapp.com" :port: 587 :domain: "zzz.com" :user_name: "[email protected]" :password: "zzz" :enable_starttls_auto: true mailgun_smtp: :authentication: "plain" :address: "smtp.mailgun.org" :port: 587 :domain: "zzz.com" :user_name: "[email protected]" :password: "zzz" :enable_starttls_auto: true

config / environment / production.rb :

config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = Rails.application.secrets.gmail_smtp

app / mailers / application_mailer.rb :

class ApplicationMailer < ActionMailer::Base default from: ''"ZZZ" <[email protected]>'' private def gmail_delivery mail.delivery_method.settings = Rails.application.secrets.gmail_smtp end def mandrill_delivery mail.delivery_method.settings = Rails.application.secrets.mandrill_smtp end def mailgun_delivery mail.delivery_method.settings = Rails.application.secrets.mailgun_smtp end end

app / mailers / user_mailer.rb :

class UserMailer < ApplicationMailer # after_action :gmail_delivery, only: [:notify_user] after_action :mandrill_delivery, only: [:newsletter] after_action :mailgun_delivery, only: [:newsletter2] def newsletter(user_id); ''...'' end # this will be sent through mandrill smtp def newsletter2(user_id); ''...'' end # this will be sent through mailgun smtp def notify_user(user_id); ''...'' end # this will be sent through gmail smtp end


https://github.com/AnthonyCaliendo/action_mailer_callbacks

Encontré que este complemento me ayudó a resolver el problema con bastante facilidad (como en <5 minutos). Simplemente cambio el @@ smtp_settings para un correo en particular en el before_deliver y luego lo cambio de nuevo a los valores predeterminados en el after_deliver. Usando este enfoque, solo tengo que agregar las devoluciones de llamada a los correos que necesitan @@ smtp_settings diferente al predeterminado.

class CustomMailer < ActionMailer::Base before_deliver do |mail| self.smtp_settings = custom_settings end after_deliver do |mail| self.smtp_settings = default_settings end def some_message subject "blah" recipients "[email protected]" from "[email protected]" body "You can haz Ninja rb skillz!" attachment some_doc end end


MyMailer.my_email.delivery_method.settings.merge!(SMTP_SETTINGS).deliver

Rails 4 permite opciones de entrega dinámicas. El código anterior proviene directamente de la guía básica de Action Mailer, que puede encontrar aquí: http://guides.rubyonrails.org/v4.0/action_mailer_basics.html#sending-emails-with-dynamic-delivery-options

Con esto, es posible tener diferentes configuraciones de smtp para cada correo electrónico que envíe, o, como en su caso de uso, para diferentes subclases como UserMailer, OtherMailer, etc.