Spaces:
Runtime error
Runtime error
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 | |
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() | |