Jak wysyłać e-maile z wieloma, dynamicznymi smtp za pomocą Actionmailer / Ruby on Rails

Widziałem ten post ale mój jest nieco inny:

Rails ActionMailer z wieloma serwerami SMTP

Pozwalam użytkownikom wysyłać pocztę za pomocą własnych poświadczeń SMTP, więc faktycznie pochodzi od nich.

Ale będą one wysyłane z aplikacji Rails, więc dla każdego użytkownika muszę wysyłać ich e-maile za pomocą ich własnego serwera SMTP.

Jak mogę to zrobić?

Author: Community, 2010-04-18

5 answers

Po prostu ustaw wartości konfiguracji ActionMailer:: Base przed każdą wysyłaną akcją.

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 = ..
 3
Author: simianarmy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-18 20:31:39

Robienie tego, co jest opisane w drugiej odpowiedzi, nie jest bezpieczne; ustawiasz tutaj zmienne klasy, A Nie zmienne instancyjne. Jeśli twój kontener Rails jest rozwidlony, możesz to zrobić, ale teraz Twoja aplikacja zależy od szczegółów implementacji kontenera. Jeśli nie rozwidlasz nowego procesu Ruby, możesz mieć tutaj warunek rasy.

Powinieneś mieć model rozszerzający metodę ActionMailer:: Base, a gdy wywołasz metodę, zwróci ona obiekt Mail:: Message. To jest obiekt wystąpienia i jest miejscem, w którym należy zmienić ustawienia. Ustawienia są również po prostu hash, więc można go wbudować.

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

Gdzie w powyższym mail_settings zwraca jakiś hash z odpowiednimi kluczami IE

{:user_name=>username, :password=>password}
 56
Author: jcalvert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-20 15:26:44

Oto rozwiązanie, które wymyśliłem na podstawie poprzednich odpowiedzi i komentarzy. W tym celu używa się klasy actionmailer interceptor.

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
 12
Author: Mitch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-06 17:13:04

Dla Rails 3.2.x

Możesz dołączyć AbstractController::Callbacks do swojej klasy Mailera i wykonać "after_filter: set_delivery_options" wewnątrz Mailera.

Metoda set_delivery_options będzie miała dostęp do zmiennych instancji ustawionych przez Ciebie w akcji mailer i możesz uzyskać dostęp do obiektu mail jako "wiadomość".

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
 9
Author: Aditya Sanghi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-08 02:06:29

W przypadku, gdy ktoś musi dynamicznie ustawić metodę dostawy wraz z poświadczeniami smtp, możesz użyć Mail:: message instance method aby ustawić metodę dostawy razem ze zmiennymi, więc moja addaptowana Aditya Sanghi Wersja to:

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
 3
Author: Saulius Morkevicius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:46:34