Подтвердить что ты не робот

Как отправлять электронные письма с несколькими динамическими smtp с помощью Actionmailer/Ruby on Rails

Я видел этот пост, но мой немного отличается:

Rails ActionMailer с несколькими SMTP-серверами

Я разрешаю пользователям отправлять почту с использованием собственных учетных данных SMTP, поэтому она действительно приходит от них.

Но они будут отправлены из приложения Rails, поэтому для каждого пользователя мне нужно отправить свои письма с помощью собственного SMTP-сервера.

Как я могу это сделать?

4b9b3361

Ответ 1

Просто установите значения конфигурации ActionMailer:: Base перед каждым действием отправки.

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

Ответ 2

Выполнение того, что описано в другом ответе, небезопасно; вы устанавливаете здесь переменные класса, а не инстантируемые переменные. Если ваш контейнер Rails разворачивается, вы можете это сделать, но теперь ваше приложение зависит от детали реализации контейнера. Если вы не открываете новый рубиновый процесс, вы можете иметь условия гонки здесь.

У вас должна быть модель, расширяющая ActionMailer:: Base, а при вызове метода она вернет объект Mail:: Message. Это ваш экземпляр объекта, и вы должны изменить свои настройки. Настройки также являются просто хешем, поэтому вы можете его встроить.

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

Если в вышеуказанных mail_settings возвращается некоторый хеш с соответствующими ключами IE

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

Ответ 3

Вот решение, которое я придумал, основываясь на предыдущих ответах и ​​комментариях. Это использует класс перехватчика 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

Ответ 4

Для Rails 3.2.x

Вы можете включить AbstractController:: Callbacks в свой почтовый класс и сделать "after_filter: set_delivery_options" внутри почтовой программы.

Метод set_delivery_options будет иметь доступ к переменным экземпляра, установленным вами в вашем действии почтовой программы, и вы можете получить доступ к почтовому объекту как "сообщение".

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

Ответ 5

если кому-то нужно динамически устанавливать способ доставки вместе с учетными данными smtp, вы можете использовать Mail:: Message instance method для установки способа доставки вместе с ним переменные, поэтому моя добавленная версия Aditya Sanghi:

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