Как отправлять электронные письма с несколькими динамическими smtp с помощью Actionmailer/Ruby on Rails
Я видел этот пост, но мой немного отличается:
Rails ActionMailer с несколькими SMTP-серверами
Я разрешаю пользователям отправлять почту с использованием собственных учетных данных SMTP, поэтому она действительно приходит от них.
Но они будут отправлены из приложения Rails, поэтому для каждого пользователя мне нужно отправить свои письма с помощью собственного SMTP-сервера.
Как я могу это сделать?
Ответы
Ответ 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