Как отправлять электронные письма с несколькими динамическими SMTP, используя Actionmailer / Ruby on Rails - PullRequest
14 голосов
/ 18 апреля 2010

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

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

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

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

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

Ответы [ 6 ]

58 голосов
/ 20 июня 2011

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

У вас должна быть модель, расширяющая 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}
12 голосов
/ 02 февраля 2013

Вот решение, которое я придумал, основываясь на предыдущих ответах и ​​комментариях. При этом используется класс перехватчика 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
9 голосов
/ 08 июля 2013

для рельсов 3.2.x

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

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

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 голосов
/ 02 февраля 2015

В случае, если кому-то нужно динамически установить метод доставки вместе с учетными данными smtp, вы можете использовать Mail :: Метод экземпляра сообщения , чтобы установить метод доставки вместе с его переменными, поэтому мой addapted 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
3 голосов
/ 19 апреля 2010

Просто установите значения конфигурации 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 = ..
0 голосов
/ 22 октября 2018

Начиная с Rails 4+, он работает для предоставления учетных данных напрямую через параметр delivery_method_options :

class UserMailer < ApplicationMailer
  def welcome_email
    @user = params[:user]
    @url  = user_url(@user)
    delivery_options = { user_name: params[:company].smtp_user,
                         password: params[:company].smtp_password,
                         address: params[:company].smtp_host }
    mail(to: @user.email,
         subject: "Please see the Terms and Conditions attached",
         delivery_method_options: delivery_options)
  end
end

См. Отправка электронных писем с опциями динамической доставки (Rails Guides)

...