Rails 3 + devise: как изменить метод почтовой программы для подтверждения писем, чтобы добавить второй адрес электронной почты пользователя

Фон: В нашем приложении у нас часто есть представитель по продажам, который делает настройку для нашего клиента, используя компьютер продавца (часто клиенты не имеют доступа к своей электронной почте в то время, когда мы их настраивали). Поэтому мы собираемся добавить поле в форму регистрации для адреса электронной почты продавца и подтвердить ссылку ALSO на этот адрес электронной почты.

Вопрос: Есть ли способ сообщить разработчику bcc (или cc) адрес электронной почты с подтверждением (только адрес электронной почты с подтверждением) на (необязательный) "backup_email" адрес электронной почты, который также указан в новой регистрационной форме пользователя?

В качестве альтернативы существует ли способ "отключить" процесс электронной почты подтверждения, но ТОЛЬКО, когда определенный код вводится в поле регистрации?

Я знаю, как добавить другое поле в форму регистрации разработки, но я не вижу, как и где можно изменить код почтовой программы разработки, поэтому, когда электронное письмо с подтверждением отправляется на адрес электронной почты, он также отправляется на страницу "backup_email" (если он есть, иногда он пуст).


Благодаря Джонни Грасу!

Я сделал rails generate mailer CustomerUserMailer и добавил

#config/initializers/devise.rb
config.mailer = "CustomUserMailer"

Моя пользовательская почтовая программа выглядит следующим образом:

# app/mailers/customer_user_mailer.rb
class CustomUserMailer < Devise::Mailer
  def headers_for(action)
    headers = {
      :subject       => translate(devise_mapping, action),
      :from          => mailer_sender(devise_mapping),
      :to            => resource.email,
      :cc            => resource.backup_user_email(action),
      :template_path => template_paths
    }
  end
end

Затем я переместил 3 шаблона почтовой рассылки FROM views/devise/mailer в views/customer_user_mailer (в противном случае электронные письма пустые)

Затем я добавил метод в мою модель User под названием backup_user_email(), которая возвращает адрес электронной почты "резервной копии" (если таковой имеется) на основе данных в пользовательской записи и действии. Единственный "трюк" в том, что при тестировании action он не action == "confirmation_instructions" равен action == :confirmation_instructions.

Ответы

Ответ 1

Один из способов сделать это - переопределить действие headers_for в Devise:: Mailer

class MyMailer < Devise::Mailer
  backup_email = "..."
  def headers_for(action)
    headers = {
     :subject       => translate(devise_mapping, action),
     :from          => mailer_sender(devise_mapping),
     :to            => resource.email,
     :bcc           => backup_email
     :template_path => template_paths
  }
end

И расскажите, как использовать свою почтовую программу:

#config/initializers/devise.rb
config.mailer = "MyMailer"

Ответ 2

На всякий случай, если кто-то попадет сюда через Google - в последней версии Devise, header_for принимает два параметра. Таким образом, ваш код должен быть:

class MyMailer < Devise::Mailer
  backup_email = "..."
  def headers_for(action, opts)
    headers = {
      :subject       => subject_for(action),
      :to            => resource.email,
      :from          => mailer_sender(devise_mapping),
      :bcc           => backup_email,
      :reply_to      => mailer_reply_to(devise_mapping),
      :template_path => template_paths,
      :template_name => action
    }.merge(opts)
  end
end

Это может быть не лучший способ сделать это, но, по крайней мере, это позволяет избежать ошибок.

Ответ 3

Вы можете использовать этот код, который намного чище и проще

# app/mailers/my_mailer.rb
class MyMailer < Devise::Mailer
  def headers_for(action, opts)
    backup_email = "..."
    super.merge!({bcc: backup_email})
  end
end

# config/initializers/devise.rb
...
config.mailer = MyMailer
...

Когда хэш перешел к методу merge!, вы можете добавить или изменить любые заголовки электронной почты, которые вы хотите.

Ответ 4

Ваш ответ сработал у меня. Большое вам спасибо.

У меня был сценарий, в котором я должен был настроить devise для: 1) отправлять сообщения подтверждения подтверждения в BCC на разные электронные письма на основе среды. 2) электронные письма должны быть добавлены в BCC только для сообщений подтверждения подписки.

Чтобы достичь этого, я сравнил значения для аргумента действия, как показано в фрагменте кода ниже:

def headers_for(action)
  if action == :confirmation_instructions
    if Rails.env.production?
        recipient_email = "[email protected]"
    else
        recipient_email = "[email protected]"
    end

    headers = {
      :subject => translate(devise_mapping, action),
      :from => mailer_sender(devise_mapping),
      :to => resource.email,
      :bcc => recipient_email,
      :template_path => template_paths
    }
  else
    super
  end
end