Rails 3 + Devise:如何修改邮件确认电子邮件的邮件方法以添加用户的第二个电子邮件地址

16

背景:在我们的应用中,我们经常让销售代表使用销售员的计算机为客户进行设置(通常客户在我们设置他们时无法访问他们的电子邮件)。因此,我们考虑在设备注册表单中添加一个字段,用于销售代表的电子邮件地址,并使确认链接也发送到该电子邮件地址。

问题:是否有一种方法可以告诉设备将初始确认电子邮件(仅限初始确认电子邮件)暗送或抄送到提供在新用户注册表单上的“备用电子邮件”电子邮件地址(如果有)?

或者,是否有一种方法可以“禁用”确认电子邮件流程,但仅当输入特定代码时才能禁用?

我知道如何向设备注册表单添加另一个字段,但我不知道/不清楚如何修改设备邮件程序代码,以便在确认电子邮件发送到“电子邮件”地址时,它也会发送到“备用电子邮件”地址(如果有,则有时为空)。


感谢 Johnny Grass!

我执行了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封邮件模板从views/devise/mailer移动到views/customer_user_mailer(否则邮件将为空)

接着,我在我的User模型中添加了一个名为backup_user_email()的方法,该方法基于用户记录和操作返回“备份”电子邮件地址(如果有)。唯一的“技巧”是在测试action时,不是action == "confirmation_instructions",而是action == :confirmation_instructions

4个回答

14

提醒一下,如果有人是通过谷歌搜索进入此处的 - 在最新版本的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

可能这不是最好的做法,但至少可以避免错误。


当我这样做时,最终得到的电子邮件没有正文。所有标题都很好用。我不知道“模板路径”是如何定义的 - 因为我使用生成的视图,它们是否无法工作? - Calciphus
没事了 - 原来如果我把:template_path改成 :template_path => "devise/mailer",我就可以使用我已经创建的模板。 - Calciphus

11

一种方法是重写Devise::Mailer中的headers_for操作。

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

并告诉Devise使用您的邮件程序:

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

一个问题...我应该把新文件保存在哪里?这是非常有帮助的信息。备份电子邮件来自每个用户注册表上的数据,希望我们可以使用类似于:bcc => resource.backup_email的东西。 - jpw
1
您需要创建一个邮件程序,并遵循此指南,但要将其作为Devise :: Mailer的子类。 - David
非常感谢。我已经在原始问题的末尾记录了更改,因为我还需要将邮件 erb 模板移动到新视图中。 - jpw
在 Devise 的最新版本中,这个答案不起作用。我会提交一个新的答案。 - Nick Kugaevsky
我该如何在加载资源的同时完成此操作?即,我想将“from”字段设置为resource.invited_by.full_name。 - cjm2671

11

您可以使用这段代码,它更加简洁清晰。

# 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! 方法的哈希,您可以添加或修改任何您想要的电子邮件头信息。

0

你的答案对我很有帮助。非常感谢。

我遇到了这样一种情况,需要自定义 devise 来实现以下功能: 1)根据环境将注册确认邮件以 BCC 的形式发送到不同的电子邮件地址。 2)仅在注册确认邮件中添加电子邮件地址到 BCC。

为了实现这个目标,我比较了 action 参数的值,就像下面的代码片段所示:

def headers_for(action)
  if action == :confirmation_instructions
    if Rails.env.production?
        recipient_email = "user1@example.com"
    else
        recipient_email = "user2@example.com"
    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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接