Test / forward_bot.py
mrwabnalas40's picture
Upload 10 files
498f51d verified
import os
import asyncio
from telethon import TelegramClient, events
from telethon.tl.types import Channel, Chat, User
from telethon.tl.functions.channels import GetParticipantRequest
from telethon.errors import ChannelInvalidError, ChannelPrivateError
# تحميل المتغيرات من البيئة
def load_config():
"""تحميل الإعدادات من ملف .env"""
from dotenv import load_dotenv
load_dotenv() # تحميل القيم من ملف .env
api_id = os.getenv('API_ID')
api_hash = os.getenv('API_HASH')
bot_token = os.getenv('BOT_TOKEN')
# إذا لم تكن القيم موجودة، نطلب من المستخدم إدخالها
if not api_id:
api_id = input("🔑 أدخل API_ID: ")
os.environ['API_ID'] = api_id
if not api_hash:
api_hash = input("🔑 أدخل API_HASH: ")
os.environ['API_HASH'] = api_hash
if not bot_token:
bot_token = input("🔑 أدخل BOT_TOKEN: ")
os.environ['BOT_TOKEN'] = bot_token
try:
return int(api_id), api_hash, bot_token
except ValueError:
print("❌ خطأ: API_ID يجب أن يكون رقماً صحيحاً")
exit(1)
# تحميل الإعدادات
api_id, api_hash, bot_token = load_config()
print(f"✅ تم تحميل الإعدادات:")
print(f" API_ID: {api_id}")
print(f" API_HASH: {api_hash}")
print(f" BOT_TOKEN: {bot_token}")
# إنشاء العميل
client = TelegramClient('forward_bot_session', api_id, api_hash).start(bot_token=bot_token)
# قائمة لحفظ القنوات/المجموعات التي البوت مشرف فيها
admin_channels = []
async def get_admin_channels():
"""الحصول على جميع القنوات والمجموعات التي يكون البوت مشرفاً فيها"""
global admin_channels
# إذا كانت القائمة محفوظة بالفعل، نعيدها
if admin_channels:
return admin_channels
admin_chats = []
try:
# بدلاً من iter_dialogs، سنستخدم طريقة بديلة للبوتات
# البوتات يمكنها فقط رؤية الدردشات التي تمت إضافتها إليها
# جلب الدردشات التي البوت عضو فيها (هذه تعمل مع البوتات)
async for dialog in client.iter_dialogs():
if isinstance(dialog.entity, User):
continue
try:
# التحقق إذا كان البوت مشرفاً في هذه الدردشة
if isinstance(dialog.entity, (Channel, Chat)):
try:
participant = await client(GetParticipantRequest(
dialog.entity,
await client.get_input_entity('me')
))
if hasattr(participant.participant, 'admin_rights'):
if participant.participant.admin_rights.post_messages:
admin_chats.append(dialog.entity.id)
print(f"✅ البوت مشرف في: {dialog.name} (ID: {dialog.entity.id})")
elif hasattr(participant.participant, 'rank'):
# بعض أنواع المشرفين
admin_chats.append(dialog.entity.id)
print(f"✅ البوت مشرف في: {dialog.name} (ID: {dialog.entity.id})")
except (ChannelInvalidError, ChannelPrivateError, ValueError):
continue
except Exception as e:
# إذا فشل التحقق، قد يكون البوت مشرفاً لكن مع صلاحيات محدودة
continue
except Exception as e:
continue
except Exception as e:
print(f"❌ خطأ في جلب الدردشات: {e}")
# نستخدم طريقة بديلة: تخزين القنوات يدوياً عند إضافة البوت كمساعد
print("⚠️ يمكنك إضافة القنوات يدوياً عن طريق إرسال /add_channel")
admin_channels = admin_chats
return admin_chats
@client.on(events.NewMessage(incoming=True, func=lambda e: e.is_private))
async def handle_private_message(event):
"""معالجة الرسائل الخاصة الواردة"""
try:
message_text = event.message.text
sender_id = event.sender_id
print(f"📩 رسالة جديدة من {sender_id}: {message_text}")
# التحقق من الأوامر الخاصة
if message_text.startswith('/'):
if message_text.startswith('/add_channel'):
# إضافة قناة يدوياً
if event.message.reply_to_msg_id:
replied_msg = await event.get_reply_message()
if replied_msg.forward_from_chat:
chat_id = replied_msg.forward_from_chat.id
if chat_id not in admin_channels:
admin_channels.append(chat_id)
await event.reply(f"✅ تمت إضافة القناة {chat_id} إلى القائمة")
else:
await event.reply("⚠️ هذه القناة مضافة بالفعل")
return
await event.reply("⚠️ للاستخدام: رد على رسالة من القناة بأمر /add_channel")
return
elif message_text.startswith('/list_channels'):
# عرض القنوات المضافة
if admin_channels:
response = "📋 القنوات/المجموعات المضافة:\n"
for i, chat_id in enumerate(admin_channels, 1):
response += f"{i}. {chat_id}\n"
await event.reply(response)
else:
await event.reply("❌ لا توجد قنوات مضافة بعد")
return
elif message_text.startswith('/clear_channels'):
# مسح القنوات
admin_channels.clear()
await event.reply("✅ تم مسح جميع القنوات من القائمة")
return
# الحصول على القنوات/المجموعات التي البوت مشرف فيها
admin_chats = await get_admin_channels()
if not admin_chats:
print("❌ البوت ليس مشرفاً في أي قناة أو مجموعة")
await event.reply("⚠️ أنا لست مشرفاً في أي قناة أو مجموعة حالياً.\n\nاستخدم /add_channel لإضافة قنوات يدوياً")
return
# إعادة توجيه الرسالة إلى جميع القنوات/المجموعات
success_count = 0
for chat_id in admin_chats:
try:
await client.forward_messages(chat_id, event.message)
print(f"✅ تم إعادة التوجيه إلى الدردشة: {chat_id}")
success_count += 1
except Exception as e:
print(f"❌ فشل الإرسال إلى {chat_id}: {e}")
# إزالة القناة من القائمة إذا فشل الإرسال
if chat_id in admin_channels:
admin_channels.remove(chat_id)
# إرسال تقرير للمستخدم
await event.reply(f"✅ تم إعادة توجيه رسالتك إلى {success_count} من {len(admin_chats)} قناة/مجموعة")
except Exception as e:
print(f"❌ خطأ في معالجة الرسالة: {e}")
await event.reply("⚠️ عذراً، حدث خطأ أثناء معالجة رسالتك.")
async def main():
"""الدالة الرئيسية لتشغيل البوت"""
print("🔍 جاري البحث عن القنوات والمجموعات التي البوت مشرف فيها...")
admin_chats = await get_admin_channels()
if admin_chats:
print(f"✅ البوت مشرف في {len(admin_chats)} قناة/مجموعة")
else:
print("❌ البوت ليس مشرفاً في أي قناة أو مجموعة")
print("💡 يمكنك إضافة قنوات يدوياً باستخدام الأمر /add_channel")
print("🤖 البوت يعمل الآن ويستمع للرسائل...")
print("📋 الأوامر المتاحة:")
print(" /add_channel - إضافة قناة يدوياً (الرد على رسالة من القناة)")
print(" /list_channels - عرض القنوات المضافة")
print(" /clear_channels - مسح جميع القنوات")
# تشغيل البوت
with client:
client.loop.run_until_complete(main())
client.run_until_disconnected()