2010-04-18 11 views
14

vi este post pero la mía es un poco diferente:¿Cómo enviar mensajes de correo electrónico con SMTP múltiple, dinámico utilizando ActionMailer/Ruby on Rails

Rails ActionMailer with multiple SMTP servers

estoy permitiendo a los usuarios enviar correo utilizando sus propias credenciales SMTP por lo que realmente proviene 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?

+1

Por favor, ayudar a conseguir este PR se fusionó en rieles. (https://github.com/rails/rails/pull/7397) Esto hace exactamente lo que estás pensando fácilmente. –

Respuesta

3

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 = .. 
+0

¿Cómo hago eso? Las configuraciones de ActionMailer están en el archivo de configuración ... ¿Crear una variable local llamada smtp_config y luego pasar los métodos respectivos? – Angela

+2

SO acaba de perder mi respuesta anterior, así que intentarlo de nuevo con una nota más corta. Usted solo está configurando las variables de la clase ActionMailer en esas llamadas. Por lo general, están definidos en las configuraciones, pero puede cambiarlos en cualquier momento que desee. En su caso, usted desea configurarlos antes de cada clase infantil de ActionMailer, método deliver_XXX que necesite llamar. – simianarmy

+2

La respuesta de jcalvert es la forma correcta de hacerlo. –

55

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í.

Debe 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 

Cuando en las mail_settings anterior devuelve un poco de hash con claves apropiadas es decir

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

El Interceptor de ActionMailer (delivering_email) podría ser útil en algunos casos. –

+6

Ayúdenos a obtener este PR fusionado en rieles. (https://github.com/rails/rails/pull/7397) Esto hace exactamente lo que OP está pensando fácilmente. –

+6

La solicitud de extracción mencionada por @AdityaSanghi se fusionó en Rails 4+, pero no se aplicará el parche en versiones anteriores. – plainjimbo

12

Aquí es una solución que se me ocurrió sobre la base de las respuestas y comentarios anteriores. Esto usa un ActionMailer interceptor class.

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 
+0

Esta es una solución ideal y funciona bien en Rails 3. –

9

para los carriles 3.2.x

Puede incluir AbstractController :: devoluciones de llamada en tu clase de anuncio publicitario y el hacer un "after_filter: set_delivery_options" dentro del gestor de correo.

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 
3

en caso de que alguien tiene que establecer el método de entrega dinámicamente junto con credenciales SMTP, u puede utilizar Mail::Message instance method para establecer el método de entrega, junto con las variables es tan mi addapted versión 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 
+0

WHATEVER_CONDITION es una constante de clase, entonces, ¿por qué necesita usarlo? – danmaz74

+0

no tiene que hacer esto, mi punto aquí fue que puede usar alguna condición para decidir si necesita combinar (reescribir) el método de entrega de correo o no, yo mismo no estoy usando constante aquí, mis otros correos están heredando de la clase MainMailer y si se cumplen algunas condiciones, estoy usando una configuración smtp diferente, que es el punto principal de todo esto en mi caso. –

Cuestiones relacionadas