rails ruby-on-rails smtp actionmailer

Cómo enviar correos electrónicos con smtp dinámico múltiple usando Actionmailer/Ruby on Rails



rails send email sendgrid (5)

Simplemente configure los valores de configuración de ActionMailer :: Base antes de cada acción de envío.

smtp_config = user.smtp_configuration ActionMailer::Base.username = smtp_config.username ActionMailer::Base.password = smtp_config.password ActionMailer::Base.server = .. ActionMailer::Base.port = .. ActionMailer::Base.authentication = ..

Vi esta publicación, pero la mía es un poco diferente:

Rails ActionMailer con múltiples servidores SMTP

Permitiré a los usuarios enviar correos usando sus propias credenciales SMTP para que en realidad provengan de ellos.

Pero se enviarán desde la aplicación Rails, por lo que significa que para cada usuario debo enviar sus correos electrónicos usando su propio servidor SMTP.

¿Cómo puedo hacer eso?


Hacer lo que se describe en la otra respuesta no es seguro; está configurando variables de clase aquí, no variables instanciadas. Si su contenedor de Rails se bifurca, puede hacerlo, pero ahora su aplicación depende de los detalles de implementación del contenedor. Si no está bifurcando un nuevo proceso de Ruby, entonces puede tener una condición de carrera aquí.

Debería tener un modelo que extienda ActionMailer :: Base, y cuando llame a un método, devolverá un objeto Mail :: Message. Ese es su objeto instancia y es donde debe cambiar su configuración. La configuración también es solo un hash, por lo que puede alinearlo.

msg = MyMailer.some_message msg.delivery_method.settings.merge!(@user.mail_settings) msg.deliver

Donde en el mail_settings anterior devuelve algo de hash con las claves apropiadas IE

{:user_name=>username, :password=>password}


Para Rails 3.2.x

Puede incluir AbstractController :: Callbacks en su clase de mailer y hacer un "after_filter: set_delivery_options" dentro del mailer.

El método set_delivery_options tendría acceso a las variables de instancia configuradas por usted en su acción de correo y puede acceder al objeto de correo como "mensaje".

class MyNailer < ActionMailer::Base include AbstractController::Callbacks after_filter :set_delivery_options def nail_it(user) @user = user mail :subject => "you nailed it" end private def set_delivery_options message.delivery_method.settings.merge!(@user.company.smtp_creds) end end


Aquí hay una solución que surgió en base a las respuestas y comentarios anteriores. Esto usa una clase de interceptor ActionMailer .

class UserMailer < ActionMailer::Base default from: proc{ @user.mail_settings[:from_address] } class DynamicSettingsInterceptor def self.delivering_email(message) message.delivery_method.settings.merge!(@user.mail_settings) end end register_interceptor DynamicSettingsInterceptor end


en caso de que alguien necesite establecer el método de entrega de forma dinámica junto con las credenciales smtp, puede usar el método de instancia Mail :: Message para establecer el método de entrega junto con sus variables, por lo que mi versión adaptada de Aditya Sanghi es:

class MainMailer < ActionMailer::Base WHATEVER_CONDITION = true # example only f.e. @ser include AbstractController::Callbacks after_filter :set_delivery_options private def set_delivery_options settings = { :address => ''smtp.mandrillapp.com'', # intentionally :port => 587, # intentionally :domain => ''your_domain'', #insetad of localhost.localdomain'' :user_name => ''smtp_username'', :password => ''smtp_password'', :authentication => ''PLAIN'' # or smthing else } if WHATEVER_CONDITION message.delivery_method(:smtp, settings) end end end