批量发送密码重置电子邮件吗?

我已从旧论坛数据库迁移了用户。有没有办法批量发送密码重置邮件?我尝试使用 API,但在请求发送约 3 封重置邮件后收到了“您执行此操作过于频繁,请稍后再试”的错误。(其他 API 操作正常)

如果您能指导如何绕过该速率限制,我很乐意使用 Ruby 控制台或 API。据我调查,这很可能是基于 IP 地址的限制。

[updated]

看来 ‘forgot_password’ 的 RateLimiter 不幸是硬编码的,所以我采用了 Ruby 脚本的方式……

要进行批量重置(向所有用户发送密码重置令牌),您可以执行以下操作:

cd /var/discourse
./launcher enter app

然后使用您喜欢的编辑器创建一个名为 mass-password-reset.rb 的新文件,内容如下:

User.all.each do |u|
  email_token = u.email_tokens.create(email: u.email)
  Jobs.enqueue(:critical_user_email, type: :forgot_password, user_id: u.id, email_token: email_token.token)
  sleep(5)
end

然后使用 rails r mass-password-reset.rb 运行该脚本。

5 个赞

太棒了,谢谢!我最近从旧论坛迁移了数据,在尝试手动重置用户密码(数量不多)时遇到了错误消息。Discourse 日志没有显示任何内容,尝试重建应用也无济于事。然后我尝试了您的脚本,现在通过外包的邮件发送服务(以及 Sidekiq)看到这些邮件正在发送。再次感谢!:slight_smile:

2 个赞

尝试过这个方法,但数据模型现在已更改(我认为是由于次要邮箱功能)。邮箱地址现在似乎位于用户邮箱对象中。

2 个赞

嗨,你有什么办法解决这个问题吗?我正要尝试那个脚本,但看到了你的消息,现在想知道你是否设法解决了这个问题。

我认为最好的办法还是让他们通过重置密码链接来重置密码。你的用户不能这样做有什么原因吗?

不,这仅仅是用户体验的问题。我们一直在迁移我们旧的 vanilla 论坛,我认为对老用户来说最好的体验是收到一封电子邮件,上面写着:“嘿,我们已从论坛迁移到一个新平台。您可以通过此链接登录:{link}”。

在此更正一下——该脚本确实有效。我只需要:

cd /var/discourse
sudo ./launcher enter app

然后创建文件:

// 创建文件
touch password.rb

然后添加以下代码:

email_token = nil

User.all.each do |u|
  email_token = u.email_tokens.create(email: u.email)
  Jobs.enqueue(:critical_user_email, type: :forgot_password, user_id: u.id, email_token: email_token.token)
  sleep(5)
end

最后,运行它:

rails r password.rb

它确实对我有效 :slight_smile:

2 个赞

抱歉,昨天我才意识到您想要进行批量处理而不是单个处理,所以想回来跟进这件事。不过,很高兴您已经解决了。:slight_smile: :+1:
我会将此问题拆分出来,以便将来更容易搜索到。:mag_right:

3 个赞

嘿,我不知道这里是否仍然是问这个问题的最佳地点,但您是否知道忘记密码的电子邮件有效期是多久?我知道它会在 3 或 4 天后过期,但我需要知道,因为我将邀请我旧论坛的用户,并且需要发送一条消息通知他们电子邮件可能在 n 天后过期,所以我需要确切的时间。谢谢。

我们如何针对单个用户或文本文件中的用户列表运行此命令?我大约有 8000 名用户需要迁移。我可以通过 API 顺利创建用户,但由于硬编码的速率限制,电子邮件无法发送。我还将我的 IP 地址设置为“Screened IP”中的“ACCEPT”,但仍然不行。这是否只能在 rails 控制台中完成?

谢谢!

我也想将上面的脚本改编为仅发送给一个用户,这样我就可以在发送给所有人之前对其进行测试。

我认为使用 导入脚本 来创建如此多的用户会是更好的主意,但这跑题了 :upside_down_face:
无论如何,如果你也在脚本中发送电子邮件,你将会达到速率限制。

如果你想减缓发送电子邮件的过程,你可以在 ruby 循环中添加 sleep(x)(x 以秒为单位),并且必须根据速率限制进行调整。

如果你打算让你的脚本运行一段时间,请使用会话管理器,例如 screentmux

user = User.find_by(username: 'alehandrof')

if user
  email_token = user.email_tokens.create(email: user.email)
  Jobs.enqueue(:critical_user_email, type: :forgot_password, user_id: user.id, email_token: email_token.token)
end

没有必要为此创建一个 Ruby 文件;你可以在 Rails 控制台中运行它(./launcher enter app 然后 rails c)。

2 个赞

感谢您的帮助 @Canapin