2010-04-18 17 views
14

ho visto questo post, ma la mia è leggermente diversa:Come inviare email con multipla, smtp dinamico usando ActionMailer/Ruby on Rails

Rails ActionMailer with multiple SMTP servers

sto permettendo agli utenti di inviare posta utilizzando le proprie credenziali SMTP così effettivamente viene da loro.

Ma verranno inviati dall'app Rails, quindi significa che per ciascun utente devo inviare le loro e-mail utilizzando il proprio server SMTP.

Come posso farlo?

+1

Aiutateci ottenere questo PR unita in binari. (https://github.com/rails/rails/pull/7397) Questo fa esattamente ciò a cui stai pensando. –

risposta

3

Basta impostare i valori di configurazione ActionMailer :: Base prima di ogni azione di invio.

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

Come faccio? Le configurazioni di ActionMailer sono nel file di configurazione ... Crea una variabile locale chiamata smtp_config e poi passa i rispettivi metodi? – Angela

+2

Quindi ho appena perso la mia risposta precedente, quindi riprovo con una nota più breve. Stai solo impostando le variabili di classe ActionMailer in quelle chiamate. Tipicamente sono definiti nelle configurazioni, ma puoi cambiarli ogni volta che vuoi. Nel tuo caso, devi impostarli prima del metodo deliver_XXX della classe child ActionMailer che devi chiamare. – simianarmy

+2

La risposta di jcalvert è il modo corretto di farlo. –

55

Fare ciò che è descritto nell'altra risposta non è sicuro; qui stai impostando le variabili di classe, non le variabili istanziate. Se il tuo contenitore Rails sta biforcandosi, puoi farlo, ma ora la tua applicazione dipende da un dettaglio di implementazione del contenitore. Se non stai creando un nuovo processo Ruby, puoi avere una condizione di gara qui.

Si dovrebbe avere un modello che estende ActionMailer :: Base e quando si chiama un metodo, verrà restituito un oggetto Mail :: Message. Questo è il tuo oggetto istanza ed è dove devi modificare le tue impostazioni. Le impostazioni sono anche solo un hash, quindi puoi metterlo in linea.

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

Dove nelle mail_settings di cui sopra torna un po 'di hash con tasti appropriati IE

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

L'Interceptor di ActionMailer (delivering_email) potrebbe essere utile in alcuni casi. –

+6

Si prega di aiutare a ottenere questo PR unito in rotaie. (https://github.com/rails/rails/pull/7397) Questo fa esattamente ciò che l'OP sta pensando facilmente. –

+6

La richiesta di pull menzionata da @AdityaSanghi è stata unita a Rails 4+ ma non verrà applicata alle patch nelle versioni precedenti. – plainjimbo

12

Ecco una soluzione che mi è venuta sulla base delle risposte e commenti precedenti. Questo utilizza 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

Questa è una soluzione ideale e funziona bene su Rails 3. –

9

Per Rails 3.2.x

È possibile includere AbstractController :: callback nella classe mailer e fare un "after_filter: set_delivery_options" all'interno del programma di posta.

Il metodo set_delivery_options avrebbe accesso alle variabili di istanza impostate dall'utente nella propria azione di mailer e sarà possibile accedere all'oggetto di posta come "messaggio".

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

nel caso in cui qualcuno ha bisogno di impostare il metodo di consegna in modo dinamico con credenziali SMTP, u possibile utilizzare Mail::Message instance method per impostare il metodo di consegna insieme con i suoi variabili in modo mio addapted Aditya Sanghi versioni:

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 è una costante di classe, quindi, perché è necessario utilizzarlo? – danmaz74

+0

non devi farlo, il mio punto qui è che puoi usare qualche condizione per decidere se devi unire (riscrivere) il metodo di consegna della posta o no, io non sto usando costante qui, gli altri miei mailer stanno ereditando dalla classe MainMailer e se sono soddisfatte alcune condizioni, sto usando una configurazione smtp diversa, che è il punto principale di tutto ciò nel mio caso. –

Problemi correlati