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