ask.discourse.org gibt einen guten Ausgangspunkt aus, als Rails-Skript:
MAX_MESSAGES = 1000 # Optionale Grenze für Tests
SECONDS_BETWEEN_MESSAGES = 3 # 3 Sekunden Intervall
Rails.logger.info "Starte Bulk-Nachrichten-Skript..."
# Definiere den Inhalt deiner Nachricht
message_title = "Willkommen in unserer Community"
message_body = "Hallo! Wir freuen uns sehr, dich hier zu haben. Lass uns wissen, wenn du Fragen hast!"
# Rufe Benutzer ab, sortiert nach zuletzt gesehen
users = User.where(active: true)
.where.not(staged: true) # Schließe staged Benutzer aus
.order(last_seen_at: :desc)
.limit(MAX_MESSAGES)
Rails.logger.info "Habe #{users.count} aktive Benutzer gefunden, denen Nachrichten gesendet werden sollen."
users.each_with_index do |user, index|
begin
Rails.logger.info "Warte auf Nachricht für #{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 "Nachricht erfolgreich für #{user.username} in die Warteschlange gestellt."
# Warte für das angegebene Intervall, bevor der nächste Benutzer verarbeitet wird
sleep(SECONDS_BETWEEN_MESSAGES)
rescue => e
Rails.logger.error "Fehler beim Senden der Nachricht an #{user.username}: #{e.message}"
end
end
Rails.logger.info "Bulk-Nachrichten-Skript abgeschlossen!"
Ich habe keine Änderungen vorgenommen, und der Benutzer system hat die PM an alle meine Benutzer auf meiner Testinstanz gesendet:
@Canapin, erstens ist das ein fantastischer Benutzername… aber deine Antwort ist noch fantastischer! Das ist wirklich genau das, was wir tun wollen. Ein paar mehr Details.
Wir haben 3,5 Millionen Nutzer. Wir planen nicht, sie alle auf einmal anzuschreiben. Die Idee wäre, dieses Skript vielleicht für 10.000er-Batches laufen zu lassen, dann ein paar Tage zu pausieren, zu sehen, welche Art von Aktivität wir haben, die E-Mail-Reputation zu überprüfen und dann wieder von vorne zu beginnen und so weiter.
Wir würden das gerne von einem Administrator mit einem Profil senden und nicht von “System”, ich nehme an, das ist möglich?
Ja, ersetzen Sie einfach system durch den gewünschten Benutzernamen im Skript.
Entschuldigung, ich habe den Code überflogen, es gibt kein system zum Ersetzen, daher muss es auf andere Weise geschehen.
Sie möchten wahrscheinlich einen Sitzungsmanager wie screen oder tmux verwenden, damit Ihr Skript im Hintergrund laufen kann.
Ich gehe davon aus, dass Sie das Skript auch stoppen möchten, wenn Sie es wünschen, und es später von dem Benutzer, bei dem es gestoppt wurde, neu starten möchten.
Da ich kein Programmierer bin (ich meine, abgesehen vom Drucken von hello world…), überlasse ich anderen Ratschläge, wie diese Funktion richtig eingerichtet wird, sowie die sichere Verwaltung des Sendens an Millionen von Benutzern
@Canapin Alles sinnvoll, und danke. Ja, ich denke, es gibt eine Möglichkeit, einfach eine Art Zählung der Datensätze durchzuführen, durch die das System laufen würde, sodass es sich im Grunde selbst stoppen würde, aber ich verstehe die anderen Optionen.
Wenn jemand andere Ideen hat, wie man dies automatisierter gestalten kann (z. B. für Stapel von 10.000 Benutzern), wäre das großartig.
Ja. Wenn ich diese Art von Skript erstellen würde, würde ich etwas einrichten, das es mir ermöglicht, vom letzten Benutzer aus neu zu starten, falls das Skript durch etwas (Serverneustart, Absturz usw.) zwangsweise unterbrochen wird.
Hier ist das aktualisierte Skript mit dem Absender-Benutzernamen:
MAX_MESSAGES = 1000 # Optional limit for testing
SECONDS_BETWEEN_MESSAGES = 3 # 3 second interval
SENDER_USERNAME = "coco"
message_sender = User.find_by(username: SENDER_USERNAME)
if message_sender.nil?
Rails.logger.error "Sender user '#{message_sender_username}' not found!"
exit
end
Rails.logger.info "Starting bulk message script..."
# Define the content of your message
message_title = "Welcome to Our Community"
message_body = "Hello! We're so excited to have you here. Let us know if you have any questions!"
# Fetch users ordered by last seen
users = User.where(active: true)
.where.not(staged: true) # Exclude staged users
.order(last_seen_at: :desc)
.limit(MAX_MESSAGES)
Rails.logger.info "Found #{users.count} active users to message."
users.each_with_index do |user, index|
begin
Rails.logger.info "Queuing message for #{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 "Message successfully queued for #{user.username}."
# Wait for the specified interval before processing the next user
sleep(SECONDS_BETWEEN_MESSAGES)
rescue => e
Rails.logger.error "Failed to send message to #{user.username}: #{e.message}"
end
end
Rails.logger.info "Bulk message script completed!"
Das ist ein Bonus @Canapin - wir werden dies wahrscheinlich morgen durchführen. Wenn wir weitere Anpassungen vornehmen, werden wir hier mit Updates zurückschreiben…
Noch eine Frage. Hat jemand eine Idee, wie man verfolgen kann, wo sich das Skript im Prozess befindet? Wir versenden zum Beispiel 10.000 E-Mails und stoppen. Dann wollen wir wieder von vorne anfangen, woher wissen wir, mit welchem Datensatz wir beginnen sollen?