Opera8 commited on
Commit
98e97fd
·
verified ·
1 Parent(s): 9113c12

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +54 -48
main.py CHANGED
@@ -23,9 +23,9 @@ from pydub import AudioSegment
23
  # --- کد مدیریت برای ارتقای کاربران بدون نیاز به لاگین ---
24
  ADMIN_CODE = "3011"
25
 
26
- # --- ثبت زمان روشن شدن ربات برای جلوگیری از پرتاب پیام‌های قدیمی ---
27
- # ده ثانیه زودتر در نظر میگیریم تا خطای هماهنگی ساعت سرورها مشکلی ایجاد نکند
28
- BOT_STARTUP_TIME = time.time() - 10.0
29
 
30
  # متغیر سراسری برای ذخیره آیدی خود ربات (جلوگیری از جواب دادن ربات به خودش)
31
  BOT_GUID = None
@@ -38,7 +38,7 @@ db_lock = threading.Lock()
38
 
39
  # --- الگوریتم تبدیل تاریخ میلادی به شمسی (بدون نیاز به نصب کتابخانه) ---
40
  def gregorian_to_jalali(gy, gm, gd):
41
- g_d_m = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]
42
  gy2 = (gy + 1) if (gm > 2) else gy
43
  days = 355666 + (365 * gy) + ((gy2 + 3) // 4) - ((gy2 + 99) // 100) + ((gy2 + 399) // 400) + gd + g_d_m[gm - 1]
44
  jy = -1595 + (33 * (days // 12053))
@@ -185,43 +185,43 @@ def run_flask():
185
 
186
  # --- ساختار کیبورد آپدیت شده ---
187
  MAIN_KEYPAD_DICT = {
188
- "rows": [
189
  {
190
- "buttons": [
191
  {"id": "chat_btn", "type": "Simple", "button_text": "چت با هوش مصنوعی 🤖"}
192
  ]
193
  },
194
  {
195
- "buttons": [
196
  {"id": "img_btn", "type": "Simple", "button_text": "ساخت تصاویر🎨"},
197
  {"id": "edit_img_btn", "type": "Simple", "button_text": "ویرایش تصاویر 🪄"}
198
  ]
199
  },
200
  {
201
- "buttons": [
202
  {"id": "podcast_btn", "type": "Simple", "button_text": "ساخت پادکست 🎙️"},
203
  {"id": "tts_btn", "type": "Simple", "button_text": "تبدیل متن به صدا🗣️"}
204
  ]
205
  },
206
  {
207
- "buttons": [
208
  {"id": "stt_btn", "type": "Simple", "button_text": "فایل صوتی به متن 📝"},
209
  {"id": "file_btn", "type": "Simple", "button_text": "تحلیل فایل 📁"}
210
  ]
211
  },
212
  {
213
- "buttons": [
214
  {"id": "account_btn", "type": "Simple", "button_text": "حساب کاربری 👤"},
215
  {"id": "buy_btn", "type": "Simple", "button_text": "خرید اشتراک 💎"}
216
  ]
217
  },
218
  {
219
- "buttons": [
220
  {"id": "transfer_btn", "type": "Simple", "button_text": "انتقال اکانت از برنامه به ربات"}
221
  ]
222
  },
223
  {
224
- "buttons": [
225
  {"id": "cancel_btn", "type": "Simple", "button_text": "برگشت♻️"}
226
  ]
227
  }
@@ -251,10 +251,10 @@ async def send_with_keyboard(client, chat_id, text, use_keyboard=True):
251
 
252
  # --- 🚨 تابع هوشمند دانلود فایل (با استفاده از UUID جهت جلوگیری از تداخل حریم خصوصی) 🚨 ---
253
  async def helper_download_file(client, msg_obj):
254
- errors = []
255
  file_id = None
256
  file_obj = None
257
- for attr in ['file', 'file_inline', 'photo', 'voice', 'audio', 'document', 'video']:
258
  val = getattr(msg_obj, attr, None)
259
  if val:
260
  file_obj = val
@@ -307,7 +307,7 @@ async def helper_download_file(client, msg_obj):
307
  GEMINI_KEYS_STR1 = os.environ.get("GEMINI_API_KEYS1", "")
308
  GEMINI_KEYS_STR2 = os.environ.get("GEMINI_API_KEYS2", "")
309
 
310
- _raw_keys = []
311
  if GEMINI_KEYS_STR1:
312
  _raw_keys.extend(GEMINI_KEYS_STR1.split(","))
313
  if GEMINI_KEYS_STR2:
@@ -332,10 +332,10 @@ def get_next_gemini_keys(count=100):
332
  with gemini_key_lock:
333
  total_keys = len(GEMINI_KEYS)
334
  if total_keys == 0:
335
- return []
336
 
337
  actual_count = min(count, total_keys)
338
- selected_keys = []
339
 
340
  for _ in range(actual_count):
341
  selected_keys.append(GEMINI_KEYS[current_gemini_key_index])
@@ -344,7 +344,7 @@ def get_next_gemini_keys(count=100):
344
  return selected_keys
345
 
346
  HF_TOKENS_STR = os.environ.get("HF_TOKENS", "")
347
- HF_TOKENS = [k.strip() for k in HF_TOKENS_STR.split(",") if k.strip()]
348
 
349
  bot_token = os.environ.get("RUBIKA_AUTH", "").strip()
350
 
@@ -352,7 +352,7 @@ bot_token = os.environ.get("RUBIKA_AUTH", "").strip()
352
  # --- 🚨 تابع اختصاصی آپلود فایل به روبیکا 🚨 ---
353
  async def helper_upload_file(client, chat_id, file_name, file_type="Image", caption=""):
354
  abs_path = os.path.abspath(file_name)
355
- error_logs = []
356
 
357
  api_file_type = "Image" if file_type in ["photo", "Image", "image"] else "Voice" if file_type in ["voice", "Voice", "audio"] else "File"
358
 
@@ -413,7 +413,7 @@ async def helper_upload_file(client, chat_id, file_name, file_type="Image", capt
413
  return "\n".join(error_logs)
414
 
415
 
416
- WORKER_URLS = [
417
  "https://hamed744-ttspro.hf.space/generate",
418
  "https://hamed744-ttspro2.hf.space/generate",
419
  "https://hamed744-ttspro3.hf.space/generate",
@@ -454,7 +454,7 @@ async def process_gemini(client, chat_id, prompt, file_bytes=None, file_name=Non
454
 
455
  proc_msg = await send_with_keyboard(client, chat_id, "🧠 در حال پردازش...", False)
456
  history = user_states[chat_id].get("history", [])
457
- new_parts = []
458
 
459
  if prompt: new_parts.append({"text": prompt})
460
  elif file_bytes: new_parts.append({"text": "لطفاً این فایل را به دقت بررسی کن."})
@@ -520,7 +520,7 @@ async def process_gemini(client, chat_id, prompt, file_bytes=None, file_name=Non
520
 
521
  try:
522
  max_len = 1000
523
- chunks = []
524
  temp_text = final_answer
525
  while len(temp_text) > max_len:
526
  split_idx = temp_text.rfind('\n', 0, max_len)
@@ -559,7 +559,7 @@ async def process_image(client, chat_id, prompt):
559
  async with aiohttp.ClientSession() as session:
560
  for key in keys_to_try_gemini:
561
  url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key={key}"
562
- payload = {"contents": [{"parts": [{"text": gemini_sys_prompt}]}], "generationConfig": {"temperature": 0.7}}
563
  try:
564
  async with session.post(url, json=payload, timeout=20) as response:
565
  if response.status == 200:
@@ -572,7 +572,7 @@ async def process_image(client, chat_id, prompt):
572
  if proc_msg:
573
  msg_id = getattr(proc_msg, 'message_id', None)
574
  if isinstance(proc_msg, dict): msg_id = proc_msg.get('message_update', {}).get('message_id') or proc_msg.get('message_id')
575
- if msg_id: await client.delete_messages(chat_id, [msg_id])
576
  except Exception: pass
577
 
578
  short_preview = enhanced_prompt[:150] + "..." if len(enhanced_prompt) > 150 else enhanced_prompt
@@ -621,7 +621,7 @@ async def translate_text_aloha(prompt_text):
621
  session_hash = ''.join(random.choices(string.ascii_lowercase + string.digits, k=11))
622
  join_url = "https://hamed744-translate-tts-aloha.hf.space/gradio_api/queue/join"
623
  payload = {
624
- "data": [prompt_text, "انگلیسی (آمریکا) - جنی (زن)", 0, 0, 0],
625
  "fn_index": 1,
626
  "session_hash": session_hash
627
  }
@@ -748,7 +748,7 @@ async def process_tts(client, chat_id, user_text, speaker_id, speaker_name):
748
  if proc_msg:
749
  msg_id = getattr(proc_msg, 'message_id', None)
750
  if isinstance(proc_msg, dict): msg_id = proc_msg.get('message_update', {}).get('message_id') or proc_msg.get('message_id')
751
- if msg_id: await client.delete_messages(chat_id, [msg_id])
752
  except Exception: pass
753
 
754
  if audio_bytes:
@@ -775,7 +775,7 @@ async def process_podcast(client, chat_id, prompt):
775
  return await send_with_keyboard(client, chat_id, "❌ اعتبار ساخت پادکست شما تمام شده است. لطفاً از منوی اصلی وارد بخش «خرید اشتراک 💎» شوید.", False)
776
 
777
  proc_msg = await send_with_keyboard(client, chat_id, "📻 در حال بررسی موضوع و نگارش سناریوی پادکست توسط هوش مصنوعی...\n(لطفاً صبور باشید)", False)
778
- available_speakers = []
779
  for num_key, (spk_name, spk_id) in SPEAKERS.items():
780
  gender = "male" if "مرد" in spk_name else "female"
781
  available_speakers.append({"id": spk_id, "name": spk_name.split(' (')[0], "gender": gender})
@@ -799,7 +799,7 @@ async def process_podcast(client, chat_id, prompt):
799
  if resp.status == 200:
800
  status_data = await resp.json()
801
  if status_data.get("status") == "completed":
802
- script_data = status_data.get("data", {}).get("script", [])
803
  break
804
  elif status_data.get("status") == "failed":
805
  return await send_with_keyboard(client, chat_id, "❌ متأسفانه هوش مصنوعی نتوانست برای این موضوع سناریو بنویسد.", True)
@@ -880,7 +880,7 @@ async def process_stt(client, chat_id, audio_bytes, file_name):
880
  async with aiohttp.ClientSession() as session:
881
  for key in keys_to_try:
882
  url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key={key}"
883
- payload = {"contents": [{"parts": [{"text": prompt}, {"inlineData": {"mimeType": mime_type, "data": base64_data}}]}], "generationConfig": {"temperature": 0.2}}
884
  try:
885
  async with session.post(url, json=payload, timeout=60) as response:
886
  if response.status == 200:
@@ -927,7 +927,7 @@ async def process_file_analysis(client, chat_id, file_bytes, file_name, prompt):
927
  async with aiohttp.ClientSession() as session:
928
  for key in keys_to_try:
929
  url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key={key}"
930
- payload = {"contents": [{"parts": [{"text": prompt}, {"inlineData": {"mimeType": mime_type, "data": base64_data}}]}], "generationConfig": {"temperature": 0.6}}
931
  try:
932
  async with session.post(url, json=payload, timeout=45) as response:
933
  if response.status == 200:
@@ -963,6 +963,13 @@ else:
963
  async def main_handler(client, update):
964
  global BOT_GUID
965
 
 
 
 
 
 
 
 
966
  try:
967
  # 🛡 دریافت آیدی یکتای ربات برای جلوگیری از لوپ 🛡
968
  if not BOT_GUID:
@@ -975,7 +982,7 @@ else:
975
 
976
  msg_obj = getattr(update, "message", None) or getattr(update, "new_message", None)
977
 
978
- # --- استخراج دقیق شناسه فرستنده (برای جلوگیری از حرف زدن ربات با خودش) ---
979
  author_id = getattr(update, 'author_guid', None)
980
  if not author_id and msg_obj:
981
  author_id = msg_obj.get('author_object_guid') if isinstance(msg_obj, dict) else getattr(msg_obj, 'author_object_guid', None)
@@ -984,7 +991,8 @@ else:
984
  if BOT_GUID and author_id == BOT_GUID:
985
  return
986
 
987
- # --- استخراج زمان دقیق پیام برای جلوگیری از اسپم شدن ربات بعد از ری‌استارت (Backlog) ---
 
988
  msg_time = getattr(update, 'timestamp', None)
989
  if not msg_time and msg_obj:
990
  msg_time = msg_obj.get('timestamp') if isinstance(msg_obj, dict) else getattr(msg_obj, 'timestamp', None)
@@ -992,11 +1000,11 @@ else:
992
  if msg_time:
993
  try:
994
  msg_time_int = int(msg_time)
995
- if msg_time_int > 1e12: # اگر زمان به میلی‌ثانیه است، تبدیل به ثانیه شود
996
  msg_time_int = msg_time_int / 1000.0
997
 
998
  if msg_time_int < BOT_STARTUP_TIME:
999
- # ⛔️ پیام مربوط به گذشته است و دور ریخته می‌شود
1000
  return
1001
  except Exception:
1002
  pass
@@ -1017,8 +1025,6 @@ else:
1017
  processed_message_ids.add(unique_msg_key)
1018
  if len(processed_message_ids) > 5000: processed_message_ids.clear()
1019
 
1020
- current_time = time.time()
1021
-
1022
  # 🛡 سیستم محدودکننده سرعت کاربر (Rate Limit) 🛡
1023
  last_req_time = user_last_request_time.get(chat_id, 0)
1024
  if current_time - last_req_time < 1.0:
@@ -1030,12 +1036,12 @@ else:
1030
  user_text_str = str(user_text).strip() if user_text else ""
1031
  user_text_lower = user_text_str.lower()
1032
 
1033
- # ⛔️ لایه امنیتی دوم برای جلوگیری از پاسخ دادن ربات به پیام‌های سیستم خودش
1034
  if user_text_str and user_text_str.startswith(("⏳", "❌", "✅", "🧠", "🎨", "🪄", "🎙", "📻", "📝", "👁️", "💡", "📥")):
1035
  return
1036
 
1037
  if chat_id not in user_states:
1038
- user_states[chat_id] = {"mode": None, "text": "", "history": [], "file_bytes": None, "file_name": None}
1039
 
1040
  # 🛠 --- سیستم پنل مدیریت (بدون نیاز به لاگین) --- 🛠
1041
  if user_text_lower.startswith(f"{ADMIN_CODE} pro=") or user_text_lower.startswith(f"{ADMIN_CODE}pro="):
@@ -1146,7 +1152,7 @@ else:
1146
  file_name = f"unknown_file_{uuid.uuid4().hex[:6]}.jpg"
1147
 
1148
  if msg_obj:
1149
- for attr in ['file', 'file_inline', 'photo', 'voice', 'audio', 'document', 'video']:
1150
  file_attr = getattr(msg_obj, attr, None)
1151
  if file_attr:
1152
  is_file = True
@@ -1155,14 +1161,14 @@ else:
1155
 
1156
  if not is_file and hasattr(msg_obj, 'to_dict'):
1157
  msg_dict = msg_obj.to_dict()
1158
- for attr in ['file', 'file_inline', 'photo', 'voice', 'audio', 'document', 'video']:
1159
  if attr in msg_dict:
1160
  is_file = True
1161
  file_attr = msg_dict.get(attr, {})
1162
  file_name = file_attr.get('file_name', file_name) if isinstance(file_attr, dict) else file_name
1163
  break
1164
 
1165
- if user_text_str in ["/start", "سلام", "لغو", "/cancel", "❌ لغو", "برگشت♻️"]:
1166
  user_states[chat_id]["mode"] = None
1167
  user_states[chat_id]["file_bytes"] = None
1168
  await send_with_keyboard(client, chat_id, "سلام! به ربات هوش مصنوعی آلفا خوش آمدید 🤖\n\nلطفاً برای شروع، از کیبورد پایین یکی از بخش‌ها را انتخاب کنید:", True)
@@ -1252,7 +1258,7 @@ else:
1252
  return
1253
 
1254
  # --- دکمه انتقال اکانت ---
1255
- if user_text_str in ["/transfer", "انتقال اکانت از برنامه به ربات"]:
1256
  transfer_text = f"""🔄 **انتقال اکانت از برنامه به ربات**
1257
 
1258
  کاربر گرامی، در صورتی که داخل برنامه «هوش مصنوعی آلفا» پیش‌تر اشتراک تهیه کرده‌اید، نیازی به خرید مجدد اشتراک داخل ربات نیست! 🎉
@@ -1268,7 +1274,7 @@ else:
1268
 
1269
  if user_text_str in ["/chat", "💬 چت", "چت با هوش مصنوعی 🤖"]:
1270
  user_states[chat_id]["mode"] = "chat"
1271
- user_states[chat_id]["history"] = []
1272
  await send_with_keyboard(client, chat_id, "💬 شما وارد بخش **چت با هوش مصنوعی** شدید.\n\nهر سوالی دارید بفرستید تا جواب بدم:\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
1273
  return
1274
 
@@ -1277,13 +1283,13 @@ else:
1277
  await send_with_keyboard(client, chat_id, "🎨 شما وارد بخش **ساخت عکس پیشرفته** شدید.\n\nمتن خود را ارسال کنید:\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
1278
  return
1279
 
1280
- if user_text_str in ["/edit_image", "ویرایش تصاویر 🪄"]:
1281
  user_states[chat_id]["mode"] = "image_edit_waiting_for_image"
1282
  user_states[chat_id]["file_bytes"] = None
1283
  await send_with_keyboard(client, chat_id, "🪄 به بخش **ویرایش عکس (Flux.2)** خوش آمدید.\n\nلطفاً ابتدا عکسی که می‌خواهید ویرایش کنید را بفرستید:\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
1284
  return
1285
 
1286
- if user_text_str in ["/tts", "🎙️ صدا", "تبدیل متن به صدا🗣️"]:
1287
  user_states[chat_id]["mode"] = "tts_waiting_for_text"
1288
  await send_with_keyboard(client, chat_id, "🎙️ شما وارد بخش **تبدیل متن به صدا** شدید.\n\nلطفاً متنی که می‌خواهید به صدا تبدیل شود را ارسال کنید:\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
1289
  return
@@ -1299,7 +1305,7 @@ else:
1299
  await send_with_keyboard(client, chat_id, "📁 شما وارد بخش **تحلیل فایل اختصاصی** شدید.\n\nلطفاً فایل خود را ارسال کنید:\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
1300
  return
1301
 
1302
- if user_text_str in ["/stt", "فایل صوتی به متن 📝"]:
1303
  user_states[chat_id]["mode"] = "stt_waiting_for_audio"
1304
  await send_with_keyboard(client, chat_id, "📝 شما وارد بخش **تبدیل صدا به متن** شدید.\n\nلطفاً فایل خود (ویس، آهنگ، ویدیو و...) را ارسال کنید:\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
1305
  return
@@ -1418,5 +1424,5 @@ else:
1418
  if __name__ == "__main__":
1419
  threading.Thread(target=run_flask, daemon=True).start()
1420
  if bot_token:
1421
- print("ربات آلفا پرو با سیستم اشتراک نامحدود روشن شد...")
1422
- bot.run()
 
23
  # --- کد مدیریت برای ارتقای کاربران بدون نیاز به لاگین ---
24
  ADMIN_CODE = "3011"
25
 
26
+ # --- ثبت زمان دقیق روشن شدن ربات ---
27
+ # (حذف ارفاق 10 ثانیه‌ای قبلی برای جلوگیری کامل از پیام‌های قدیمی)
28
+ BOT_STARTUP_TIME = time.time()
29
 
30
  # متغیر سراسری برای ذخیره آیدی خود ربات (جلوگیری از جواب دادن ربات به خودش)
31
  BOT_GUID = None
 
38
 
39
  # --- الگوریتم تبدیل تاریخ میلادی به شمسی (بدون نیاز به نصب کتابخانه) ---
40
  def gregorian_to_jalali(gy, gm, gd):
41
+ g_d_m =[0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]
42
  gy2 = (gy + 1) if (gm > 2) else gy
43
  days = 355666 + (365 * gy) + ((gy2 + 3) // 4) - ((gy2 + 99) // 100) + ((gy2 + 399) // 400) + gd + g_d_m[gm - 1]
44
  jy = -1595 + (33 * (days // 12053))
 
185
 
186
  # --- ساختار کیبورد آپدیت شده ---
187
  MAIN_KEYPAD_DICT = {
188
+ "rows":[
189
  {
190
+ "buttons":[
191
  {"id": "chat_btn", "type": "Simple", "button_text": "چت با هوش مصنوعی 🤖"}
192
  ]
193
  },
194
  {
195
+ "buttons":[
196
  {"id": "img_btn", "type": "Simple", "button_text": "ساخت تصاویر🎨"},
197
  {"id": "edit_img_btn", "type": "Simple", "button_text": "ویرایش تصاویر 🪄"}
198
  ]
199
  },
200
  {
201
+ "buttons":[
202
  {"id": "podcast_btn", "type": "Simple", "button_text": "ساخت پادکست 🎙️"},
203
  {"id": "tts_btn", "type": "Simple", "button_text": "تبدیل متن به صدا🗣️"}
204
  ]
205
  },
206
  {
207
+ "buttons":[
208
  {"id": "stt_btn", "type": "Simple", "button_text": "فایل صوتی به متن 📝"},
209
  {"id": "file_btn", "type": "Simple", "button_text": "تحلیل فایل 📁"}
210
  ]
211
  },
212
  {
213
+ "buttons":[
214
  {"id": "account_btn", "type": "Simple", "button_text": "حساب کاربری 👤"},
215
  {"id": "buy_btn", "type": "Simple", "button_text": "خرید اشتراک 💎"}
216
  ]
217
  },
218
  {
219
+ "buttons":[
220
  {"id": "transfer_btn", "type": "Simple", "button_text": "انتقال اکانت از برنامه به ربات"}
221
  ]
222
  },
223
  {
224
+ "buttons":[
225
  {"id": "cancel_btn", "type": "Simple", "button_text": "برگشت♻️"}
226
  ]
227
  }
 
251
 
252
  # --- 🚨 تابع هوشمند دانلود فایل (با استفاده از UUID جهت جلوگیری از تداخل حریم خصوصی) 🚨 ---
253
  async def helper_download_file(client, msg_obj):
254
+ errors =[]
255
  file_id = None
256
  file_obj = None
257
+ for attr in['file', 'file_inline', 'photo', 'voice', 'audio', 'document', 'video']:
258
  val = getattr(msg_obj, attr, None)
259
  if val:
260
  file_obj = val
 
307
  GEMINI_KEYS_STR1 = os.environ.get("GEMINI_API_KEYS1", "")
308
  GEMINI_KEYS_STR2 = os.environ.get("GEMINI_API_KEYS2", "")
309
 
310
+ _raw_keys =[]
311
  if GEMINI_KEYS_STR1:
312
  _raw_keys.extend(GEMINI_KEYS_STR1.split(","))
313
  if GEMINI_KEYS_STR2:
 
332
  with gemini_key_lock:
333
  total_keys = len(GEMINI_KEYS)
334
  if total_keys == 0:
335
+ return[]
336
 
337
  actual_count = min(count, total_keys)
338
+ selected_keys =[]
339
 
340
  for _ in range(actual_count):
341
  selected_keys.append(GEMINI_KEYS[current_gemini_key_index])
 
344
  return selected_keys
345
 
346
  HF_TOKENS_STR = os.environ.get("HF_TOKENS", "")
347
+ HF_TOKENS =[k.strip() for k in HF_TOKENS_STR.split(",") if k.strip()]
348
 
349
  bot_token = os.environ.get("RUBIKA_AUTH", "").strip()
350
 
 
352
  # --- 🚨 تابع اختصاصی آپلود فایل به روبیکا 🚨 ---
353
  async def helper_upload_file(client, chat_id, file_name, file_type="Image", caption=""):
354
  abs_path = os.path.abspath(file_name)
355
+ error_logs =[]
356
 
357
  api_file_type = "Image" if file_type in ["photo", "Image", "image"] else "Voice" if file_type in ["voice", "Voice", "audio"] else "File"
358
 
 
413
  return "\n".join(error_logs)
414
 
415
 
416
+ WORKER_URLS =[
417
  "https://hamed744-ttspro.hf.space/generate",
418
  "https://hamed744-ttspro2.hf.space/generate",
419
  "https://hamed744-ttspro3.hf.space/generate",
 
454
 
455
  proc_msg = await send_with_keyboard(client, chat_id, "🧠 در حال پردازش...", False)
456
  history = user_states[chat_id].get("history", [])
457
+ new_parts =[]
458
 
459
  if prompt: new_parts.append({"text": prompt})
460
  elif file_bytes: new_parts.append({"text": "لطفاً این فایل را به دقت بررسی کن."})
 
520
 
521
  try:
522
  max_len = 1000
523
+ chunks =[]
524
  temp_text = final_answer
525
  while len(temp_text) > max_len:
526
  split_idx = temp_text.rfind('\n', 0, max_len)
 
559
  async with aiohttp.ClientSession() as session:
560
  for key in keys_to_try_gemini:
561
  url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key={key}"
562
+ payload = {"contents": [{"parts":[{"text": gemini_sys_prompt}]}], "generationConfig": {"temperature": 0.7}}
563
  try:
564
  async with session.post(url, json=payload, timeout=20) as response:
565
  if response.status == 200:
 
572
  if proc_msg:
573
  msg_id = getattr(proc_msg, 'message_id', None)
574
  if isinstance(proc_msg, dict): msg_id = proc_msg.get('message_update', {}).get('message_id') or proc_msg.get('message_id')
575
+ if msg_id: await client.delete_messages(chat_id,[msg_id])
576
  except Exception: pass
577
 
578
  short_preview = enhanced_prompt[:150] + "..." if len(enhanced_prompt) > 150 else enhanced_prompt
 
621
  session_hash = ''.join(random.choices(string.ascii_lowercase + string.digits, k=11))
622
  join_url = "https://hamed744-translate-tts-aloha.hf.space/gradio_api/queue/join"
623
  payload = {
624
+ "data":[prompt_text, "انگلیسی (آمریکا) - جنی (زن)", 0, 0, 0],
625
  "fn_index": 1,
626
  "session_hash": session_hash
627
  }
 
748
  if proc_msg:
749
  msg_id = getattr(proc_msg, 'message_id', None)
750
  if isinstance(proc_msg, dict): msg_id = proc_msg.get('message_update', {}).get('message_id') or proc_msg.get('message_id')
751
+ if msg_id: await client.delete_messages(chat_id,[msg_id])
752
  except Exception: pass
753
 
754
  if audio_bytes:
 
775
  return await send_with_keyboard(client, chat_id, "❌ اعتبار ساخت پادکست شما تمام شده است. لطفاً از منوی اصلی وارد بخش «خرید اشتراک 💎» شوید.", False)
776
 
777
  proc_msg = await send_with_keyboard(client, chat_id, "📻 در حال بررسی موضوع و نگارش سناریوی پادکست توسط هوش مصنوعی...\n(لطفاً صبور باشید)", False)
778
+ available_speakers =[]
779
  for num_key, (spk_name, spk_id) in SPEAKERS.items():
780
  gender = "male" if "مرد" in spk_name else "female"
781
  available_speakers.append({"id": spk_id, "name": spk_name.split(' (')[0], "gender": gender})
 
799
  if resp.status == 200:
800
  status_data = await resp.json()
801
  if status_data.get("status") == "completed":
802
+ script_data = status_data.get("data", {}).get("script",[])
803
  break
804
  elif status_data.get("status") == "failed":
805
  return await send_with_keyboard(client, chat_id, "❌ متأسفانه هوش مصنوعی نتوانست برای این موضوع سناریو بنویسد.", True)
 
880
  async with aiohttp.ClientSession() as session:
881
  for key in keys_to_try:
882
  url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key={key}"
883
+ payload = {"contents": [{"parts":[{"text": prompt}, {"inlineData": {"mimeType": mime_type, "data": base64_data}}]}], "generationConfig": {"temperature": 0.2}}
884
  try:
885
  async with session.post(url, json=payload, timeout=60) as response:
886
  if response.status == 200:
 
927
  async with aiohttp.ClientSession() as session:
928
  for key in keys_to_try:
929
  url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key={key}"
930
+ payload = {"contents":[{"parts":[{"text": prompt}, {"inlineData": {"mimeType": mime_type, "data": base64_data}}]}], "generationConfig": {"temperature": 0.6}}
931
  try:
932
  async with session.post(url, json=payload, timeout=45) as response:
933
  if response.status == 200:
 
963
  async def main_handler(client, update):
964
  global BOT_GUID
965
 
966
+ current_time = time.time()
967
+
968
+ # 🛡 سد دفاعی اول: فریز ۳۰ ثانیه‌ای کامل 🛡
969
+ # در ۳۰ ثانیه اول راه‌اندازی، هیچ پیامی تحت هیچ شرایطی پردازش نمی‌شود
970
+ if current_time - BOT_STARTUP_TIME < 30:
971
+ return
972
+
973
  try:
974
  # 🛡 دریافت آیدی یکتای ربات برای جلوگیری از لوپ 🛡
975
  if not BOT_GUID:
 
982
 
983
  msg_obj = getattr(update, "message", None) or getattr(update, "new_message", None)
984
 
985
+ # --- استخراج دقیق شناسه فرستنده ---
986
  author_id = getattr(update, 'author_guid', None)
987
  if not author_id and msg_obj:
988
  author_id = msg_obj.get('author_object_guid') if isinstance(msg_obj, dict) else getattr(msg_obj, 'author_object_guid', None)
 
991
  if BOT_GUID and author_id == BOT_GUID:
992
  return
993
 
994
+ # 🛡 سد دفاعی دوم: جلوگیری کامل از تلنبار شدن پیامهای قدیمی (Backlog) 🛡
995
+ # حتی اگر ۳۰ ثانیه گذشته باشد، اگر کاربر این پیام را در زمان خاموشی سرور داده باشد، درجا حذف می‌شود
996
  msg_time = getattr(update, 'timestamp', None)
997
  if not msg_time and msg_obj:
998
  msg_time = msg_obj.get('timestamp') if isinstance(msg_obj, dict) else getattr(msg_obj, 'timestamp', None)
 
1000
  if msg_time:
1001
  try:
1002
  msg_time_int = int(msg_time)
1003
+ if msg_time_int > 1e12: # تبدیل میلی‌ثانیه به ثانیه اگر نیاز بود
1004
  msg_time_int = msg_time_int / 1000.0
1005
 
1006
  if msg_time_int < BOT_STARTUP_TIME:
1007
+ # ⛔️ پیام متعلق به گذشته است و برای همیشه دور ریخته می‌شود
1008
  return
1009
  except Exception:
1010
  pass
 
1025
  processed_message_ids.add(unique_msg_key)
1026
  if len(processed_message_ids) > 5000: processed_message_ids.clear()
1027
 
 
 
1028
  # 🛡 سیستم محدودکننده سرعت کاربر (Rate Limit) 🛡
1029
  last_req_time = user_last_request_time.get(chat_id, 0)
1030
  if current_time - last_req_time < 1.0:
 
1036
  user_text_str = str(user_text).strip() if user_text else ""
1037
  user_text_lower = user_text_str.lower()
1038
 
1039
+ # ⛔️ لایه امنیتی سوم برای جلوگیری از پاسخ دادن ربات به پیام‌های سیستم خودش
1040
  if user_text_str and user_text_str.startswith(("⏳", "❌", "✅", "🧠", "🎨", "🪄", "🎙", "📻", "📝", "👁️", "💡", "📥")):
1041
  return
1042
 
1043
  if chat_id not in user_states:
1044
+ user_states[chat_id] = {"mode": None, "text": "", "history":[], "file_bytes": None, "file_name": None}
1045
 
1046
  # 🛠 --- سیستم پنل مدیریت (بدون نیاز به لاگین) --- 🛠
1047
  if user_text_lower.startswith(f"{ADMIN_CODE} pro=") or user_text_lower.startswith(f"{ADMIN_CODE}pro="):
 
1152
  file_name = f"unknown_file_{uuid.uuid4().hex[:6]}.jpg"
1153
 
1154
  if msg_obj:
1155
+ for attr in['file', 'file_inline', 'photo', 'voice', 'audio', 'document', 'video']:
1156
  file_attr = getattr(msg_obj, attr, None)
1157
  if file_attr:
1158
  is_file = True
 
1161
 
1162
  if not is_file and hasattr(msg_obj, 'to_dict'):
1163
  msg_dict = msg_obj.to_dict()
1164
+ for attr in['file', 'file_inline', 'photo', 'voice', 'audio', 'document', 'video']:
1165
  if attr in msg_dict:
1166
  is_file = True
1167
  file_attr = msg_dict.get(attr, {})
1168
  file_name = file_attr.get('file_name', file_name) if isinstance(file_attr, dict) else file_name
1169
  break
1170
 
1171
+ if user_text_str in["/start", "سلام", "لغو", "/cancel", "❌ لغو", "برگشت♻️"]:
1172
  user_states[chat_id]["mode"] = None
1173
  user_states[chat_id]["file_bytes"] = None
1174
  await send_with_keyboard(client, chat_id, "سلام! به ربات هوش مصنوعی آلفا خوش آمدید 🤖\n\nلطفاً برای شروع، از کیبورد پایین یکی از بخش‌ها را انتخاب کنید:", True)
 
1258
  return
1259
 
1260
  # --- دکمه انتقال اکانت ---
1261
+ if user_text_str in["/transfer", "انتقال اکانت از برنامه به ربات"]:
1262
  transfer_text = f"""🔄 **انتقال اکانت از برنامه به ربات**
1263
 
1264
  کاربر گرامی، در صورتی که داخل برنامه «هوش مصنوعی آلفا» پیش‌تر اشتراک تهیه کرده‌اید، نیازی به خرید مجدد اشتراک داخل ربات نیست! 🎉
 
1274
 
1275
  if user_text_str in ["/chat", "💬 چت", "چت با هوش مصنوعی 🤖"]:
1276
  user_states[chat_id]["mode"] = "chat"
1277
+ user_states[chat_id]["history"] =[]
1278
  await send_with_keyboard(client, chat_id, "💬 شما وارد بخش **چت با هوش مصنوعی** شدید.\n\nهر سوالی دارید بفرستید تا جواب بدم:\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
1279
  return
1280
 
 
1283
  await send_with_keyboard(client, chat_id, "🎨 شما وارد بخش **ساخت عکس پیشرفته** شدید.\n\nمتن خود را ارسال کنید:\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
1284
  return
1285
 
1286
+ if user_text_str in["/edit_image", "ویرایش تصاویر 🪄"]:
1287
  user_states[chat_id]["mode"] = "image_edit_waiting_for_image"
1288
  user_states[chat_id]["file_bytes"] = None
1289
  await send_with_keyboard(client, chat_id, "🪄 به بخش **ویرایش عکس (Flux.2)** خوش آمدید.\n\nلطفاً ابتدا عکسی که می‌خواهید ویرایش کنید را بفرستید:\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
1290
  return
1291
 
1292
+ if user_text_str in["/tts", "🎙️ صدا", "تبدیل متن به صدا🗣️"]:
1293
  user_states[chat_id]["mode"] = "tts_waiting_for_text"
1294
  await send_with_keyboard(client, chat_id, "🎙️ شما وارد بخش **تبدیل متن به صدا** شدید.\n\nلطفاً متنی که می‌خواهید به صدا تبدیل شود را ارسال کنید:\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
1295
  return
 
1305
  await send_with_keyboard(client, chat_id, "📁 شما وارد بخش **تحلیل فایل اختصاصی** شدید.\n\nلطفاً فایل خود را ارسال کنید:\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
1306
  return
1307
 
1308
+ if user_text_str in["/stt", "فایل صوتی به متن 📝"]:
1309
  user_states[chat_id]["mode"] = "stt_waiting_for_audio"
1310
  await send_with_keyboard(client, chat_id, "📝 شما وارد بخش **تبدیل صدا به متن** شدید.\n\nلطفاً فایل خود (ویس، آهنگ، ویدیو و...) را ارسال کنید:\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
1311
  return
 
1424
  if __name__ == "__main__":
1425
  threading.Thread(target=run_flask, daemon=True).start()
1426
  if bot_token:
1427
+ print("ربات آلفا پرو با سیستم اشتراک نامحدود و دیواره امنیتی ضد Backlog روشن شد...")
1428
+ bot.run()