用于后台发送欢迎信息的脚本

您好,

我想在后台进程中向我们的庞大用户群发送欢迎消息,所以:

  • 创建消息
  • 排队用户
  • 一次一个地向每个用户发送消息,每秒发送一个,直到完成整个列表
  • 还想按最近登录/访问时间对发送进行排序

有人知道如何做到这一点吗,或者有人可以编写一个脚本来做到这一点吗?

ask.discourse.org 输出一个不错的起点,作为 rails 脚本:

MAX_MESSAGES = 1000 # 可选的测试限制
SECONDS_BETWEEN_MESSAGES = 3 # 3 秒间隔

Rails.logger.info "开始批量消息脚本..."

# 定义你的消息内容
message_title = "欢迎来到我们的社区"
message_body = "你好!我们很高兴你来到这里。如果你有任何问题,请告诉我们!"

# 获取按最后可见时间排序的用户
users = User.where(active: true)
            .where.not(staged: true) # 排除暂存用户
            .order(last_seen_at: :desc)
            .limit(MAX_MESSAGES)

Rails.logger.info "找到 #{users.count} 个活跃用户需要发送消息。"

users.each_with_index do |user, index|
  begin
    Rails.logger.info "正在为 #{user.username} 排队消息 (#{index + 1}/#{users.count})..."

    PostCreator.create!(
      Discourse.system_user,
      title: message_title,
      raw: message_body,
      archetype: Archetype.private_message,
      target_usernames: user.username,
      skip_validations: true
    )

    Rails.logger.info "已成功为 #{user.username} 排队消息。"

    # 在处理下一个用户之前等待指定的时间间隔
    sleep(SECONDS_BETWEEN_MESSAGES)
  rescue => e
    Rails.logger.error "发送消息给 #{user.username} 失败: #{e.message}"
  end
end

Rails.logger.info "批量消息脚本已完成!"

我没有做任何修改,用户 system 向我的测试实例中的所有用户发送了 MP:


你们有多少用户?

5 个赞

@Canapin 首先,你的用户名太棒了……但你的回复更棒!这确实符合我们想要做的。再多说一些细节。

我们有 350 万用户。我们不打算一次性发送给所有用户,而是打算运行这个脚本,也许每次发送 1 万个用户,然后停止几天,看看我们有什么样的活动,检查电子邮件声誉,然后再次开始,以此类推。

我们希望通过管理员的个人资料而不是“系统”来发送这个,我猜这是可能的?

再次感谢,非常有帮助。

2 个赞

是的,只需在脚本中将 system 替换为所需的用户名即可。
抱歉,我草草看了一下代码,没有 system 可以替换,所以必须用另一种方法来完成。

你可能需要使用会话管理器,如 screentmux,这样你的脚本就可以在后台运行。

我猜你还想在需要时停止脚本,并在之后从停止处重新启动它。

由于我不是程序员(我的意思是,除了打印 hello world…),我将让其他人就如何正确设置此功能以及安全地管理向数百万用户发送消息的建议 :smile:

2 个赞

@Canapin 都很合理,谢谢。是的,我正在考虑有一种方法可以计算系统将要处理的记录数,这样它基本上就会自行停止,但我理解其他选项。

如果还有其他人有关于如何使此过程更自动化的想法(例如,运行 10k 用户批次),那就太好了。

是的。如果我要创建这种脚本,我会设置一些东西,以便在脚本被强制中断时(例如服务器重启、崩溃等)能够从最后一个用户处重新开始。

这是更新后的脚本,其中包含发件人用户名:

MAX_MESSAGES = 1000 # 可选的测试限制
SECONDS_BETWEEN_MESSAGES = 3 # 3 秒间隔
SENDER_USERNAME = "coco"

message_sender = User.find_by(username: SENDER_USERNAME)

if message_sender.nil?
  Rails.logger.error "找不到发件人用户 '#{message_sender_username}'!"
  exit
end

Rails.logger.info "正在启动批量消息脚本..."

# 定义消息内容
message_title = "欢迎来到我们的社区"
message_body = "你好!我们很高兴你加入我们。如果你有任何问题,请告诉我们!"

# 按最后登录时间排序获取用户
users = User.where(active: true)
            .where.not(staged: true) # 排除暂存用户
            .order(last_seen_at: :desc)
            .limit(MAX_MESSAGES)

Rails.logger.info "找到 #{users.count} 个活跃用户需要发送消息。"

users.each_with_index do |user, index|
  begin
    Rails.logger.info "正在为 #{user.username} 排队消息 (#{index + 1}/#{users.count})..."

    PostCreator.create!(
      message_sender,
      title: message_title,
      raw: message_body,
      archetype: Archetype.private_message,
      target_usernames: user.username,
      skip_validations: true
    )

    Rails.logger.info "已成功为 #{user.username} 排队消息。"

    # 在处理下一个用户之前等待指定的间隔
    sleep(SECONDS_BETWEEN_MESSAGES)
  rescue => e
    Rails.logger.error "发送消息给 #{user.username} 失败:#{e.message}"
  end
end

Rails.logger.info "批量消息脚本已完成!"
4 个赞

That is bonus @Canapin - we will run this likely tomorrow, if we adjust further we will post back here with updates…

CC: @Abdelrahman_MoHamed

1 个赞

很可能你需要编辑这一行:

我最后的回复已经包含了所需的更改。

3 个赞

这里还有另一个问题。有人知道如何跟踪脚本在过程中的位置吗?例如,我们发送 10,000 封电子邮件然后停止。然后想重新开始,我们如何知道从哪个记录开始?

1 个赞