Update bot.py
Browse files
bot.py
CHANGED
|
@@ -1,12 +1,14 @@
|
|
| 1 |
import os
|
| 2 |
import asyncio
|
| 3 |
import sqlite3
|
|
|
|
|
|
|
| 4 |
from pyrogram import Client, filters, idle
|
| 5 |
from pyrogram.errors import FloodWait
|
| 6 |
from pyrogram.enums import ChatType
|
| 7 |
|
| 8 |
-
# --- 1. إعداد مساحات التخزين و
|
| 9 |
-
DATA_DIR = "/data"
|
| 10 |
DOWNLOAD_DIR = os.path.join(DATA_DIR, "downloads")
|
| 11 |
DB_PATH = os.path.join(DATA_DIR, 'bot_memory.db')
|
| 12 |
os.makedirs(DOWNLOAD_DIR, exist_ok=True)
|
|
@@ -24,30 +26,40 @@ def mark_processed(chat_id, msg_id):
|
|
| 24 |
cursor.execute("INSERT OR IGNORE INTO processed VALUES (?, ?)", (chat_id, msg_id))
|
| 25 |
conn.commit()
|
| 26 |
|
| 27 |
-
# --- 2.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
API_ID = int(os.environ.get("API_ID", 0))
|
| 29 |
API_HASH = os.environ.get("API_HASH", "")
|
| 30 |
SESSION_STRING = os.environ.get("SESSION_STRING", "")
|
| 31 |
TARGET_CHAT = int(os.environ.get("TARGET_CHAT", 0))
|
| 32 |
|
| 33 |
-
# تقليل العمال لتجنب استفزاز رادار تيليجرام
|
| 34 |
app = Client(
|
| 35 |
"restricted_bypass_bot",
|
| 36 |
api_id=API_ID,
|
| 37 |
api_hash=API_HASH,
|
| 38 |
session_string=SESSION_STRING,
|
| 39 |
-
max_concurrent_transmissions=
|
| 40 |
)
|
| 41 |
|
| 42 |
process_queue = asyncio.Queue()
|
| 43 |
|
| 44 |
-
# ---
|
| 45 |
@app.on_message(filters.incoming & ~filters.me & (filters.channel | filters.group) & filters.media)
|
| 46 |
async def catch_new_messages(client, message):
|
| 47 |
if not is_processed(message.chat.id, message.id):
|
| 48 |
await process_queue.put(message)
|
| 49 |
|
| 50 |
-
# ---
|
| 51 |
async def scan_old_history():
|
| 52 |
print("🔎 [جيمي] بدء مسح أرشيف القنوات والمجموعات...")
|
| 53 |
try:
|
|
@@ -58,20 +70,19 @@ async def scan_old_history():
|
|
| 58 |
async for message in app.get_chat_history(dialog.chat.id):
|
| 59 |
if message.media and not is_processed(message.chat.id, message.id):
|
| 60 |
await process_queue.put(message)
|
| 61 |
-
except Exception
|
| 62 |
-
|
| 63 |
|
| 64 |
-
|
|
|
|
| 65 |
print("✅ اكتمل سحب كافة الرسائل المفقودة إلى الطابور!")
|
| 66 |
except Exception as e:
|
| 67 |
print(f"❌ خطأ عام بالمسح: {e}")
|
| 68 |
|
| 69 |
-
# ---
|
| 70 |
async def restricted_bypass_worker():
|
| 71 |
while True:
|
| 72 |
message = await process_queue.get()
|
| 73 |
-
|
| 74 |
-
# تجنب معالجة ما تم إنجازه
|
| 75 |
if is_processed(message.chat.id, message.id):
|
| 76 |
process_queue.task_done()
|
| 77 |
continue
|
|
@@ -79,18 +90,14 @@ async def restricted_bypass_worker():
|
|
| 79 |
file_path = None
|
| 80 |
try:
|
| 81 |
print(f"⬇️ جاري سحب الملف (ID: {message.id}) من قناة مقفلة...")
|
| 82 |
-
|
| 83 |
-
# خطوة 1: التحميل الفعلي
|
| 84 |
file_path = await message.download(file_name=f"{DOWNLOAD_DIR}/")
|
| 85 |
|
| 86 |
if not file_path:
|
| 87 |
-
print("⚠️ فشل التحميل، سيتم التخطي.")
|
| 88 |
continue
|
| 89 |
|
| 90 |
print(f"⬆️ جاري الرفع إلى قناتك...")
|
| 91 |
-
|
| 92 |
-
# خطوة 2: الرفع الفعلي
|
| 93 |
caption = message.caption or ""
|
|
|
|
| 94 |
if message.photo:
|
| 95 |
await app.send_photo(TARGET_CHAT, photo=file_path, caption=caption)
|
| 96 |
elif message.video:
|
|
@@ -98,26 +105,21 @@ async def restricted_bypass_worker():
|
|
| 98 |
elif message.document:
|
| 99 |
await app.send_document(TARGET_CHAT, document=file_path, caption=caption)
|
| 100 |
else:
|
| 101 |
-
await app.send_audio(TARGET_CHAT, audio=file_path, caption=caption)
|
| 102 |
|
| 103 |
-
# خطوة 3: التوثيق في قاعدة البيانات
|
| 104 |
mark_processed(message.chat.id, message.id)
|
| 105 |
print(f"✅ تم النقل بنجاح!")
|
| 106 |
-
|
| 107 |
-
# خطوة 4: الفاصل الزمني الإجباري (لا تقم بتعديله، فهو درع الحماية من الحظر)
|
| 108 |
-
print("⏳ استراحة أمنية لمدة 12 ثانية...")
|
| 109 |
-
await asyncio.sleep(12)
|
| 110 |
|
| 111 |
except FloodWait as e:
|
| 112 |
-
print(f"🛑
|
| 113 |
await asyncio.sleep(e.value + 5)
|
| 114 |
-
await process_queue.put(message)
|
| 115 |
|
| 116 |
except Exception as e:
|
| 117 |
print(f"❌ خطأ أثناء معالجة الملف: {e}")
|
| 118 |
|
| 119 |
finally:
|
| 120 |
-
# خطوة 5: حذف الملف فوراً لتجنب امتلاء السيرفر
|
| 121 |
if file_path and os.path.exists(file_path):
|
| 122 |
try:
|
| 123 |
os.remove(file_path)
|
|
@@ -125,15 +127,12 @@ async def restricted_bypass_worker():
|
|
| 125 |
pass
|
| 126 |
process_queue.task_done()
|
| 127 |
|
| 128 |
-
# ---
|
| 129 |
async def main():
|
| 130 |
await app.start()
|
| 131 |
-
print("🚀
|
| 132 |
|
| 133 |
-
# عامل رفع واحد فقط لضمان الترتيب وعدم الضغط على سيرفر تيليجرام
|
| 134 |
asyncio.create_task(restricted_bypass_worker())
|
| 135 |
-
|
| 136 |
-
# تشغيل ماسح الأرشيف لجلب الفيديوهات القديمة
|
| 137 |
asyncio.create_task(scan_old_history())
|
| 138 |
|
| 139 |
await idle()
|
|
|
|
| 1 |
import os
|
| 2 |
import asyncio
|
| 3 |
import sqlite3
|
| 4 |
+
from threading import Thread
|
| 5 |
+
from http.server import BaseHTTPRequestHandler, HTTPServer
|
| 6 |
from pyrogram import Client, filters, idle
|
| 7 |
from pyrogram.errors import FloodWait
|
| 8 |
from pyrogram.enums import ChatType
|
| 9 |
|
| 10 |
+
# --- 1. إعداد مساحات التخزين (متوافق مع Hugging Face) ---
|
| 11 |
+
DATA_DIR = "./data" # استخدام مسار محلي داخل الـ Space
|
| 12 |
DOWNLOAD_DIR = os.path.join(DATA_DIR, "downloads")
|
| 13 |
DB_PATH = os.path.join(DATA_DIR, 'bot_memory.db')
|
| 14 |
os.makedirs(DOWNLOAD_DIR, exist_ok=True)
|
|
|
|
| 26 |
cursor.execute("INSERT OR IGNORE INTO processed VALUES (?, ?)", (chat_id, msg_id))
|
| 27 |
conn.commit()
|
| 28 |
|
| 29 |
+
# --- 2. سيرفر الويب الوهمي (لمنع Hugging Face من إغلاق البوت) ---
|
| 30 |
+
class RequestHandler(BaseHTTPRequestHandler):
|
| 31 |
+
def do_GET(self):
|
| 32 |
+
self.send_response(200)
|
| 33 |
+
self.end_headers()
|
| 34 |
+
self.wfile.write(b"Hugging Face Bot is Running Perfectly!")
|
| 35 |
+
def log_message(self, format, *args): pass
|
| 36 |
+
|
| 37 |
+
# تشغيل السيرفر على المنفذ 7860 المطلوب من HF
|
| 38 |
+
Thread(target=lambda: HTTPServer(('0.0.0.0', 7860), RequestHandler).serve_forever(), daemon=True).start()
|
| 39 |
+
|
| 40 |
+
# --- 3. إعدادات الحساب ---
|
| 41 |
API_ID = int(os.environ.get("API_ID", 0))
|
| 42 |
API_HASH = os.environ.get("API_HASH", "")
|
| 43 |
SESSION_STRING = os.environ.get("SESSION_STRING", "")
|
| 44 |
TARGET_CHAT = int(os.environ.get("TARGET_CHAT", 0))
|
| 45 |
|
|
|
|
| 46 |
app = Client(
|
| 47 |
"restricted_bypass_bot",
|
| 48 |
api_id=API_ID,
|
| 49 |
api_hash=API_HASH,
|
| 50 |
session_string=SESSION_STRING,
|
| 51 |
+
max_concurrent_transmissions=1 # تقليل الضغط على سيرفرات تيليجرام
|
| 52 |
)
|
| 53 |
|
| 54 |
process_queue = asyncio.Queue()
|
| 55 |
|
| 56 |
+
# --- 4. صائد الرسائل الجديدة ---
|
| 57 |
@app.on_message(filters.incoming & ~filters.me & (filters.channel | filters.group) & filters.media)
|
| 58 |
async def catch_new_messages(client, message):
|
| 59 |
if not is_processed(message.chat.id, message.id):
|
| 60 |
await process_queue.put(message)
|
| 61 |
|
| 62 |
+
# --- 5. حاصد الأرشيف القديم (مبطأ لتجنب FloodWait) ---
|
| 63 |
async def scan_old_history():
|
| 64 |
print("🔎 [جيمي] بدء مسح أرشيف القنوات والمجموعات...")
|
| 65 |
try:
|
|
|
|
| 70 |
async for message in app.get_chat_history(dialog.chat.id):
|
| 71 |
if message.media and not is_processed(message.chat.id, message.id):
|
| 72 |
await process_queue.put(message)
|
| 73 |
+
except Exception:
|
| 74 |
+
pass
|
| 75 |
|
| 76 |
+
# زيادة الفاصل الزمني إلى 7 ثوانٍ لمنع GetHistory FloodWait
|
| 77 |
+
await asyncio.sleep(7)
|
| 78 |
print("✅ اكتمل سحب كافة الرسائل المفقودة إلى الطابور!")
|
| 79 |
except Exception as e:
|
| 80 |
print(f"❌ خطأ عام بالمسح: {e}")
|
| 81 |
|
| 82 |
+
# --- 6. محرك الكسر والرفع (للقنوات المقفلة) ---
|
| 83 |
async def restricted_bypass_worker():
|
| 84 |
while True:
|
| 85 |
message = await process_queue.get()
|
|
|
|
|
|
|
| 86 |
if is_processed(message.chat.id, message.id):
|
| 87 |
process_queue.task_done()
|
| 88 |
continue
|
|
|
|
| 90 |
file_path = None
|
| 91 |
try:
|
| 92 |
print(f"⬇️ جاري سحب الملف (ID: {message.id}) من قناة مقفلة...")
|
|
|
|
|
|
|
| 93 |
file_path = await message.download(file_name=f"{DOWNLOAD_DIR}/")
|
| 94 |
|
| 95 |
if not file_path:
|
|
|
|
| 96 |
continue
|
| 97 |
|
| 98 |
print(f"⬆️ جاري الرفع إلى قناتك...")
|
|
|
|
|
|
|
| 99 |
caption = message.caption or ""
|
| 100 |
+
|
| 101 |
if message.photo:
|
| 102 |
await app.send_photo(TARGET_CHAT, photo=file_path, caption=caption)
|
| 103 |
elif message.video:
|
|
|
|
| 105 |
elif message.document:
|
| 106 |
await app.send_document(TARGET_CHAT, document=file_path, caption=caption)
|
| 107 |
else:
|
| 108 |
+
await app.send_audio(TARGET_CHAT, audio=file_path, caption=caption)
|
| 109 |
|
|
|
|
| 110 |
mark_processed(message.chat.id, message.id)
|
| 111 |
print(f"✅ تم النقل بنجاح!")
|
| 112 |
+
await asyncio.sleep(15) # استراحة إجبارية
|
|
|
|
|
|
|
|
|
|
| 113 |
|
| 114 |
except FloodWait as e:
|
| 115 |
+
print(f"🛑 تيليجرام يطلب التوقف لمدة {e.value} ثانية! سنطيع الأمر.")
|
| 116 |
await asyncio.sleep(e.value + 5)
|
| 117 |
+
await process_queue.put(message)
|
| 118 |
|
| 119 |
except Exception as e:
|
| 120 |
print(f"❌ خطأ أثناء معالجة الملف: {e}")
|
| 121 |
|
| 122 |
finally:
|
|
|
|
| 123 |
if file_path and os.path.exists(file_path):
|
| 124 |
try:
|
| 125 |
os.remove(file_path)
|
|
|
|
| 127 |
pass
|
| 128 |
process_queue.task_done()
|
| 129 |
|
| 130 |
+
# --- 7. التشغيل ---
|
| 131 |
async def main():
|
| 132 |
await app.start()
|
| 133 |
+
print("🚀 البوت يعمل الآن بكفاءة على Hugging Face!")
|
| 134 |
|
|
|
|
| 135 |
asyncio.create_task(restricted_bypass_worker())
|
|
|
|
|
|
|
| 136 |
asyncio.create_task(scan_old_history())
|
| 137 |
|
| 138 |
await idle()
|