ask.discourse.org sortie un bon point de départ, sous forme de script Rails :
MAX_MESSAGES = 1000 # Limite facultative pour les tests
SECONDS_BETWEEN_MESSAGES = 3 # Intervalle de 3 secondes
Rails.logger.info "Démarrage du script de messagerie en masse..."
# Définir le contenu de votre message
message_title = "Bienvenue dans notre communauté"
message_body = "Bonjour ! Nous sommes ravis de vous accueillir ici. N'hésitez pas à nous faire savoir si vous avez des questions !"
# Récupérer les utilisateurs triés par dernière connexion
users = User.where(active: true)
.where.not(staged: true) # Exclure les utilisateurs staged
.order(last_seen_at: :desc)
.limit(MAX_MESSAGES)
Rails.logger.info "Trouvé #{users.count} utilisateurs actifs à qui envoyer un message."
users.each_with_index do |user, index|
begin
Rails.logger.info "Mise en file d'attente du message pour #{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 "Message mis en file d'attente avec succès pour #{user.username}."
# Attendre l'intervalle spécifié avant de traiter l'utilisateur suivant
sleep(SECONDS_BETWEEN_MESSAGES)
rescue => e
Rails.logger.error "Échec de l'envoi du message à #{user.username} : #{e.message}"
end
end
Rails.logger.info "Script de messagerie en masse terminé !"
Je n’ai fait aucune modification, et l’utilisateur system a envoyé le MP à tous mes utilisateurs sur mon instance de test :
@Canapin, premièrement, c’est un pseudo incroyable… mais votre réponse l’est encore plus ! C’est vraiment dans la lignée de ce que nous voulons faire. Quelques détails supplémentaires.
Nous avons 3,5 millions d’utilisateurs. Nous ne prévoyons pas de leur envoyer à tous en même temps, l’idée serait d’exécuter ce script, peut-être par lots de 10 000, puis de s’arrêter pendant quelques jours, de voir quel type d’activité nous avons, de vérifier la réputation des e-mails, puis de recommencer, et ainsi de suite.
Nous aimerions cependant l’envoyer depuis un administrateur avec un profil plutôt que « système », je suppose que c’est possible ?
Oui, remplacez simplement system par le nom d’utilisateur souhaité dans le script.
Désolé, j’ai survolé le code, il n’y a pas de system à remplacer, donc cela doit être fait autrement.
Vous voudrez probablement utiliser un gestionnaire de session comme screen ou tmux afin que votre script puisse s’exécuter en arrière-plan.
Je suppose que vous voudrez également pouvoir arrêter le script quand vous le souhaitez et le redémarrer plus tard à partir de l’utilisateur où il s’est arrêté.
Comme je ne suis pas programmeur (je veux dire, à part imprimer hello world…), je laisserai d’autres donner des conseils sur la façon de configurer cette fonctionnalité correctement, ainsi que sur la gestion sécurisée de l’envoi à des millions d’utilisateurs
@Canapin Tout à fait sensé, et merci. Oui, je pense qu’il existe un moyen de simplement compter le nombre d’enregistrements que le système parcourrait, donc en gros, il s’arrêterait lui-même, mais j’ai compris pour les autres options.
Si quelqu’un d’autre a des idées sur la façon de rendre cela plus automatisé (par exemple, exécuter pour des lots de 10 000 utilisateurs), ce serait formidable.
Ouais. Si je devais créer ce genre de script, je mettrais en place quelque chose qui me permettrait de redémarrer à partir du dernier utilisateur au cas où le script serait interrompu de force par quelque chose (redémarrage du serveur, crash…, etc.).
Voici le script mis à jour avec le nom d’utilisateur de l’expéditeur :
MAX_MESSAGES = 1000 # Limite optionnelle pour les tests
SECONDS_BETWEEN_MESSAGES = 3 # Intervalle de 3 secondes
SENDER_USERNAME = "coco"
message_sender = User.find_by(username: SENDER_USERNAME)
if message_sender.nil?
Rails.logger.error "Utilisateur expéditeur '#{message_sender_username}' introuvable !"
exit
end
Rails.logger.info "Démarrage du script de messagerie en masse..."
# Définir le contenu de votre message
message_title = "Bienvenue dans notre communauté"
message_body = "Bonjour ! Nous sommes ravis de vous accueillir. N'hésitez pas à nous faire savoir si vous avez des questions !"
# Récupérer les utilisateurs triés par dernière connexion
users = User.where(active: true)
.where.not(staged: true) # Exclure les utilisateurs staged
.order(last_seen_at: :desc)
.limit(MAX_MESSAGES)
Rails.logger.info "Trouvé #{users.count} utilisateurs actifs à qui envoyer un message."
users.each_with_index do |user, index|
begin
Rails.logger.info "Mise en file d'attente du message pour #{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 mis en file d'attente avec succès pour #{user.username}."
# Attendre l'intervalle spécifié avant de traiter l'utilisateur suivant
sleep(SECONDS_BETWEEN_MESSAGES)
rescue => e
Rails.logger.error "Échec de l'envoi du message à #{user.username} : #{e.message}"
end
end
Rails.logger.info "Script de messagerie en masse terminé !"
Une autre question ici. Quelqu’un a-t-il une idée de la façon de suivre la progression du script ? Par exemple, nous envoyons 10 000 e-mails et nous arrêtons. Ensuite, nous voulons recommencer, comment saurions-nous à partir de quel enregistrement commencer ?