バックグラウンドでウェルカムメッセージを送信するスクリプト

こんにちは。

大規模なユーザーベースにウェルカムメッセージをバックグラウンドプロセスとして送信することに興味があります。そのため、以下の手順を実行したいと考えています。

  • メッセージを作成する
  • ユーザーをキューに入れる
  • リスト全体が完了するまで、ユーザーごとに1秒に1通ずつメッセージを送信する
  • 最近のログイン/訪問順に送信を整理したい

これを実行する方法について、何かアイデアはありますか?または、誰かがこれを実行するスクリプトを作成できますか?

ask.discourse.org は、レールスクリプトとして良い出発点を提供します。

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 すべて理にかなっており、ありがとうございます。はい、システムが処理するレコードの数をカウントするような方法があると考えています。基本的に、システムが停止するだけですが、他のオプションについては理解しています。

誰かがこれをより自動化する方法(たとえば、10,000ユーザーのバッチで実行するなど)についてのアイデアがあれば、それは素晴らしいでしょう。

ええ。もし私がこの種のスクリプトを作成するなら、スクリプトが強制的に中断された場合(サーバーの再起動、クラッシュなど)に最後のユーザーから再開できるように何かを設定します。

送信者ユーザー名を含む更新されたスクリプトはこちらです。

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

それはボーナスです、@Canapin。明日実行する予定です。さらに調整する場合は、ここで更新情報をお知らせします。

CC:@Abdelrahman_MoHamed

「いいね!」 1

おそらく、この行を編集する必要があります。

私の最後の返信には、すでに必要な変更が含まれています。

「いいね!」 3

スクリプトがプロセスのどこにあるかを追跡する方法について、何かアイデアはありますか?例えば、1万通のメールを送信して停止し、再度開始したい場合、どのレコードから開始すればよいかわかるでしょうか?

「いいね!」 1