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 رسالة خاصة إلى جميع مستخدمي في نسختي التجريبية:
@Canapin أولاً، هذا اسم مستخدم مذهل… ولكن ردك مذهل أكثر! هذا حقًا يتماشى مع ما نريد القيام به. بعض التفاصيل الإضافية.
لدينا 3.5 مليون مستخدم. لا نخطط لإرسال رسائل إلى جميعهم دفعة واحدة، الفكرة ستكون تشغيل هذا البرنامج النصي، ربما لدفعات من 10 آلاف، ثم التوقف لبضعة أيام، ورؤية نوع النشاط الذي لدينا، والتحقق من سمعة البريد الإلكتروني، ثم البدء مرة أخرى، وهكذا.
نود إرسال هذا من مسؤول لديه ملف شخصي بدلاً من “النظام”، أفترض أن هذا ممكن؟
نعم، فقط استبدل system باسم المستخدم المطلوب في البرنامج النصي.
عذرًا، لقد ألقيت نظرة سريعة على الكود، لا يوجد system للاستبدال، لذلك يجب القيام بذلك بطريقة أخرى.
ستحتاج على الأرجح إلى استخدام مدير جلسات مثل screen أو tmux حتى يتمكن البرنامج النصي الخاص بك من العمل في الخلفية.
أفترض أنك سترغب أيضًا في أن تكون قادرًا على إيقاف البرنامج النصي عند الرغبة وإعادة تشغيله لاحقًا من المستخدم الذي توقف عنده.
نظرًا لأنني لست مبرمجًا (أعني، بخلاف طباعة hello world…)، سأترك الآخرين يقدمون المشورة حول كيفية إعداد هذه الميزة بشكل صحيح، وكذلك إدارة الإرسال بأمان لملايين المستخدمين
@Canapin كل شيء منطقي، وشكراً لك. نعم، أفكر في وجود طريقة لإجراء نوع من العد للسجلات التي سيمر بها النظام، لذا سيتوقف عن العمل بنفسه، ولكنني أتفهم الخيارات الأخرى.
إذا كان لدى أي شخص آخر أي أفكار حول كيفية جعل هذا الأمر أكثر آلية (على سبيل المثال، تشغيله لمجموعات من 10 آلاف مستخدم)، فسيكون ذلك رائعًا.
نعم. إذا كنت سأقوم بإنشاء هذا النوع من البرامج النصية، فسأقوم بإعداد شيء يسمح لي بإعادة التشغيل من آخر مستخدم في حالة مقاطعة البرنامج النصي قسرًا بسبب شيء ما (إعادة تشغيل الخادم، تعطل… إلخ).
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 "اكتمل البرنامج النصي للرسائل المجمعة!"
سؤال آخر هنا. هل لدى أي شخص أي فكرة عن كيفية تتبع مكان وجود البرنامج النصي في العملية؟ على سبيل المثال، نرسل 10 آلاف بريد إلكتروني ونتوقف. ثم نريد البدء مرة أخرى، كيف سنعرف السجل الذي نبدأ به؟