Opera8 commited on
Commit
be6645a
·
verified ·
1 Parent(s): 7c93c71

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +781 -7
main.py CHANGED
@@ -1958,12 +1958,13 @@ async def process_create_file(client, chat_id, topic):
1958
 
1959
  # ==============================================================================
1960
  # 🟢 پارت 20: بدنه اصلی ربات (Handler)، دستورات مدیریتی، حلقه اصلی و استارت
1961
- # ⚠️ (نسخه موقت جاروبرقی: فقط پیام‌ها را می‌خواند و تیک می‌زند تا صف خالی شود) ⚠️
1962
  # ==============================================================================
1963
  # ==================================================================
1964
  # حلقه و مدیریت اصلی ربات
1965
  # ==================================================================
1966
 
 
 
1967
  # 🧹 سیستم پاکسازی هوشمند رم (Garbage Collector) مخصوص هزاران کاربر
1968
  async def ram_garbage_collector():
1969
  """این تابع در پس‌زمینه می‌چرخد و فایل‌های رها شده در حافظه را پاک می‌کند تا رم سرور پر نشود"""
@@ -2027,20 +2028,793 @@ else:
2027
  if not msg_id and msg_obj:
2028
  msg_id = msg_obj.get("message_id") if isinstance(msg_obj, dict) else getattr(msg_obj, "message_id", None)
2029
 
 
 
 
2030
  # ===================================================================
2031
- # 🛑 سیستم صد در صد قطعی ضد تکرار پیام با استفاده از دیتابیس ابری
2032
  # ===================================================================
2033
  if msg_id:
2034
  str_msg_id = str(msg_id).strip()
2035
  if is_message_processed(str_msg_id):
2036
  return
2037
- # شناسه پیام در دیتابیس ثبت می‌شود تا دیگر هرگز خوانده نشود
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2038
  mark_message_processed(str_msg_id)
2039
- print(f"✅ پیام قدیمی با شناسه {str_msg_id} تیک خورد و دور انداخته شد.")
 
 
 
2040
  # ===================================================================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2041
 
2042
- # ⛔️ توقف در همین نقطه! هیچ پردازشی انجام نمی‌شود و هیچ پیامی ارسال نمی‌گردد.
2043
- return
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2044
 
2045
  except Exception: traceback.print_exc()
2046
 
@@ -2054,5 +2828,5 @@ if __name__ == "__main__":
2054
 
2055
  loop.create_task(ram_garbage_collector())
2056
 
2057
- print("🚀 ربات در حالت موقت (جاروبرقی پیام‌های قدیمی) روشن شد. منتظر بمانید تا صف پیام‌ها خالی شود...")
2058
  bot.run()
 
1958
 
1959
  # ==============================================================================
1960
  # 🟢 پارت 20: بدنه اصلی ربات (Handler)، دستورات مدیریتی، حلقه اصلی و استارت
 
1961
  # ==============================================================================
1962
  # ==================================================================
1963
  # حلقه و مدیریت اصلی ربات
1964
  # ==================================================================
1965
 
1966
+ BOT_START_TIME = time.time() # ⏳ زمان دقیق روشن شدن ربات ثبت می‌شود
1967
+
1968
  # 🧹 سیستم پاکسازی هوشمند رم (Garbage Collector) مخصوص هزاران کاربر
1969
  async def ram_garbage_collector():
1970
  """این تابع در پس‌زمینه می‌چرخد و فایل‌های رها شده در حافظه را پاک می‌کند تا رم سرور پر نشود"""
 
2028
  if not msg_id and msg_obj:
2029
  msg_id = msg_obj.get("message_id") if isinstance(msg_obj, dict) else getattr(msg_obj, "message_id", None)
2030
 
2031
+ str_chat_id = str(chat_id).replace("`", "").replace("'", "").replace('"', "").strip()
2032
+ creds = get_user_credits(str_chat_id)
2033
+
2034
  # ===================================================================
2035
+ # 🛑 سیستم صد در صد قطعی ضد تکرار پیام و فیلتر پیام‌های قدیمی (Timestamp)
2036
  # ===================================================================
2037
  if msg_id:
2038
  str_msg_id = str(msg_id).strip()
2039
  if is_message_processed(str_msg_id):
2040
  return
2041
+
2042
+ # ⏳ تشخیص پیام‌های قدیمی (مربوط به قبل از ری‌استارت ربات)
2043
+ is_old = False
2044
+ try:
2045
+ for attr in['timestamp', 'time', 'date', 'message_date']:
2046
+ val = getattr(msg_obj, attr, None)
2047
+ if not val and isinstance(msg_obj, dict):
2048
+ val = msg_obj.get(attr)
2049
+ if val:
2050
+ val_int = int(val)
2051
+ # روبیکا معمولا زمان را ۱۳ رقمی (میلی‌ثانیه) می‌دهد، تبدیل به ثانیه:
2052
+ if val_int > 10000000000:
2053
+ val_int = val_int / 1000
2054
+
2055
+ # اگر پیام بیشتر از 60 ثانیه قبل از روشن شدن ربات فرستاده شده باشد، قدیمی است
2056
+ if val_int < BOT_START_TIME - 60:
2057
+ is_old = True
2058
+ break
2059
+ except Exception:
2060
+ pass
2061
+
2062
+ # پیام چه قدیمی باشد چه جدید، در دیتابیس ثبت می‌شود که دیگر خوانده نشود
2063
  mark_message_processed(str_msg_id)
2064
+
2065
+ if is_old:
2066
+ # پیام تلنبار شده و قدیمی است، کاملا بی‌سروصدا دور ریخته می‌شود (بدون جواب دادن)
2067
+ return
2068
  # ===================================================================
2069
+
2070
+ user_text = getattr(update, "text", "") or getattr(msg_obj, "text", "")
2071
+ user_text_str = str(user_text).strip() if user_text else ""
2072
+ user_text_lower = user_text_str.lower()
2073
+
2074
+ if is_user_spamming(str_chat_id):
2075
+ return
2076
+
2077
+ if str_chat_id not in user_states:
2078
+ user_states[str_chat_id] = {"mode": None, "text": "", "history":[], "file_bytes": None, "file_name": None, "last_time": time.time()}
2079
+ else:
2080
+ user_states[str_chat_id]["last_time"] = time.time()
2081
+
2082
+ if user_text_lower.startswith(f"{ADMIN_CODE} pro=") or user_text_lower.startswith(f"{ADMIN_CODE}pro="):
2083
+ parts = user_text_str.split("=", 1)
2084
+ if len(parts) >= 2:
2085
+ target_id = parts[1].replace("`", "").replace("'", "").replace('"', "").strip()
2086
+ if target_id:
2087
+ if target_id not in user_credits_db or not isinstance(user_credits_db[target_id], dict):
2088
+ user_credits_db[target_id] = {
2089
+ "is_premium": False,
2090
+ "expire_date": None,
2091
+ "last_reset": "",
2092
+ "chat": 10,
2093
+ "image": 0,
2094
+ "edit_image": 0,
2095
+ "podcast": 2,
2096
+ "tts": 5,
2097
+ "file": 1,
2098
+ "stt": 5,
2099
+ "voice_conv": 3,
2100
+ "voice_clone": 1,
2101
+ "last_msg_id": 0,
2102
+ "has_joined": True,
2103
+ "invited_count": 0,
2104
+ "used_referral": False,
2105
+ "referral_code": ""
2106
+ }
2107
+
2108
+ user_credits_db[target_id]["is_premium"] = True
2109
+ expire_time = datetime.datetime.now() + datetime.timedelta(days=30)
2110
+ user_credits_db[target_id]["expire_date"] = expire_time.isoformat()
2111
+
2112
+ user_credits_db[target_id]["chat"] = 999999
2113
+ user_credits_db[target_id]["image"] = 10
2114
+ user_credits_db[target_id]["edit_image"] = 5
2115
+ user_credits_db[target_id]["podcast"] = 999999
2116
+ user_credits_db[target_id]["tts"] = 999999
2117
+ user_credits_db[target_id]["file"] = 999999
2118
+ user_credits_db[target_id]["stt"] = 999999
2119
+ user_credits_db[target_id]["voice_conv"] = 999999
2120
+ user_credits_db[target_id]["voice_clone"] = 999999
2121
+
2122
+ save_db(user_credits_db)
2123
+ await send_with_keyboard(client, chat_id, f"✅ حساب کاربر `{target_id}` به مدت ۳۰ روز شارژ شد و به پرو ارتقا یافت.", False)
2124
+ try:
2125
+ await send_with_keyboard(client, target_id, "🎉 **کاربر گرامی، تبریک!**\n\nحساب شما با موفقیت توسط پشتیبانی به **🌟 نسخه پرو (ویژه)** ارتقا یافت.\nهم‌اکنون بسته‌های نامحدود و طلایی یک‌ماهه شما فعال گردید.\n\nجهت مشاهده جزئیات روی دکمه «حساب کاربری 👤» کلیک کنید.", True)
2126
+ except Exception: pass
2127
+ return
2128
+
2129
+ if user_text_lower.startswith(f"{ADMIN_CODE} free=") or user_text_lower.startswith(f"{ADMIN_CODE}free="):
2130
+ parts = user_text_str.split("=", 1)
2131
+ if len(parts) >= 2:
2132
+ target_id = parts[1].replace("`", "").replace("'", "").replace('"', "").strip()
2133
+ if target_id:
2134
+ if target_id in user_credits_db and isinstance(user_credits_db[target_id], dict):
2135
+ user_credits_db[target_id]["is_premium"] = False
2136
+ user_credits_db[target_id]["expire_date"] = None
2137
+ user_credits_db[target_id]["last_reset"] = ""
2138
+ user_credits_db[target_id]["image"] = 0
2139
+ user_credits_db[target_id]["edit_image"] = 0
2140
+ save_db(user_credits_db)
2141
+ await send_with_keyboard(client, chat_id, f"✅ اشتراک کاربر `{target_id}` لغو شد و به رایگان تبدیل گشت.", False)
2142
+ try:
2143
+ await send_with_keyboard(client, target_id, "⚠️ کاربر گرامی، اشتراک ویژه شما به پایان رسید و حساب شما به نسخه رایگان (آزمایشی) تغییر یافت.", True)
2144
+ except Exception: pass
2145
+ return
2146
+
2147
+ if user_text_lower.startswith(f"{ADMIN_CODE} =") or user_text_lower.startswith(f"{ADMIN_CODE}="):
2148
+ parts = user_text_str.split("=", 1)
2149
+ if len(parts) >= 2:
2150
+ target_id = parts[1].replace("`", "").replace("'", "").replace('"', "").strip()
2151
+ if target_id:
2152
+ if target_id in user_credits_db and isinstance(user_credits_db[target_id], dict):
2153
+ t_creds = user_credits_db[target_id]
2154
+ is_prem = t_creds.get("is_premium", False)
2155
+
2156
+ if is_prem:
2157
+ expire_txt = "نامشخص"
2158
+ days_left = 0
2159
+ if t_creds.get("expire_date"):
2160
+ exp_d = datetime.datetime.fromisoformat(t_creds["expire_date"])
2161
+ now = datetime.datetime.now()
2162
+ diff = exp_d - now
2163
+ days_left = diff.days if diff.days >= 0 else 0
2164
+
2165
+ jy, jm, jd = gregorian_to_jalali(exp_d.year, exp_d.month, exp_d.day)
2166
+ expire_txt = f"{jy:04d}/{jm:02d}/{jd:02d}"
2167
+ status_text = f"🌟 نسخه پرو (ویژه)\n📅 انقضا: {expire_txt}\n⏳ باقیمانده: {days_left} روز"
2168
+ else:
2169
+ status_text = "🥉 نسخه رایگان (آزمایشی)\n⏳ وضعیت: سهمیه روزانه محدود"
2170
+
2171
+ chat_rem = "نامحدود ∞" if is_prem else t_creds.get('chat', 0)
2172
+ vc_rem = "نامحدود ∞" if is_prem else t_creds.get('voice_conv', 0)
2173
+ clone_rem = "نامحدود ∞" if is_prem else t_creds.get('voice_clone', 0)
2174
+ podcast_rem = "نامحدود ∞" if is_prem else t_creds.get('podcast', 0)
2175
+ tts_rem = "نامحدود ∞" if is_prem else t_creds.get('tts', 0)
2176
+ file_rem = "نامحدود ∞" if is_prem else t_creds.get('file', 0)
2177
+ stt_rem = "نامحدود ∞" if is_prem else t_creds.get('stt', 0)
2178
+ image_rem = t_creds.get('image', 0)
2179
+ edit_image_rem = t_creds.get('edit_image', 0)
2180
+ invs = t_creds.get('invited_count', 0)
2181
+ joined_status = "بله ✅" if t_creds.get('has_joined') else "خیر ❌"
2182
+
2183
+ info_msg = f"""🔍 **اطلاعات اختصاصی کاربر:**
2184
+ 👤 شناسه: `{target_id}`
2185
+ عضو کانال: {joined_status}
2186
+
2187
+ 🔹 **وضعیت اشتراک:**
2188
+ {status_text}
2189
+ 🎁 **تعداد افراد دعوت شده:** {invs} نفر
2190
+
2191
+ 📊 **سهمیه باقی‌مانده فعلی:**
2192
+ 💬 چت: {chat_rem}
2193
+ 🎨 تولید عکس: {image_rem}
2194
+ 🪄 ویرایش عکس: {edit_image_rem}
2195
+ 🎙️ تغییر صدا: {vc_rem}
2196
+ 👤 کلون کردن صدا: {clone_rem}
2197
+ 🎙 پادکست: {podcast_rem}
2198
+ 🗣 متن به صدا: {tts_rem}
2199
+ 📁 تحلیل فایل: {file_rem}
2200
+ 📝 صدا به متن: {stt_rem}"""
2201
+ await send_with_keyboard(client, chat_id, info_msg, False)
2202
+ else:
2203
+ await send_with_keyboard(client, chat_id, f"❌ کاربری با شناسه `{target_id}` در دیتابیس ربات یافت نشد.", False)
2204
+ return
2205
+
2206
+ is_file = False
2207
+ file_name = f"unknown_file_{uuid.uuid4().hex[:6]}.jpg"
2208
 
2209
+ if msg_obj:
2210
+ for attr in['file', 'file_inline', 'photo', 'voice', 'audio', 'document', 'video']:
2211
+ file_attr = getattr(msg_obj, attr, None)
2212
+ if file_attr:
2213
+ is_file = True
2214
+ file_name = getattr(file_attr, 'file_name', file_name)
2215
+ break
2216
+
2217
+ if not is_file and hasattr(msg_obj, 'to_dict'):
2218
+ msg_dict = msg_obj.to_dict()
2219
+ for attr in['file', 'file_inline', 'photo', 'voice', 'audio', 'document', 'video']:
2220
+ if attr in msg_dict:
2221
+ is_file = True
2222
+ file_attr = msg_dict.get(attr, {})
2223
+ file_name = file_attr.get('file_name', file_name) if isinstance(file_attr, dict) else file_name
2224
+ break
2225
+
2226
+ if user_text_str == "✅ عضو شدم":
2227
+ if not creds.get("has_joined", False):
2228
+ user_credits_db[str_chat_id]["has_joined"] = True
2229
+ save_db(user_credits_db)
2230
+ await send_with_keyboard(client, chat_id, "🎉 **عضویت شما با موفقیت تایید شد! خیلی خوش آمدید.**\n\nحالا می‌توانید از تمامی امکانات ربات استفاده کنید.\nلطفاً یکی از گزینه‌های منو را انتخاب کنید:", True)
2231
+ return
2232
+ else:
2233
+ await send_with_keyboard(client, chat_id, "✅ شما قبلاً عضو شده‌اید! لطفا از منوی اصلی استفاده کنید.", True)
2234
+ return
2235
+
2236
+ if not creds.get("has_joined", False):
2237
+ join_msg = "👋 **سلام کاربر گرامی!**\n\nجهت استفاده از خدمات ربات هوش مصنوعی آلفا و مطلع شدن از آخرین آپدیت‌ها، لطفا ابتدا در کانال رسمی ما عضو شوید:\n\n📢 **آیدی کانال:** @aialpha\n\n👇 پس از عضویت در کا��ال، بر روی دکمه **«✅ عضو شدم»** کلیک کنید تا ربات برای شما فعال شود."
2238
+ try:
2239
+ payload = {"chat_id": chat_id, "text": join_msg, "chat_keypad_type": "New", "chat_keypad": JOIN_KEYPAD_DICT}
2240
+ await client._make_request("sendMessage", payload)
2241
+ except Exception:
2242
+ await client.send_message(chat_id, join_msg)
2243
+ return
2244
+
2245
+ if user_text_lower.startswith("/start"):
2246
+ user_states[str_chat_id]["mode"] = None
2247
+ user_states[str_chat_id]["file_bytes"] = None
2248
+ await send_with_keyboard(client, chat_id, "سلام! به ربات هوش مصنوعی آلفا خوش آمدید 🤖\n\nلطفاً برای شروع، از کیبورد پایین یکی از بخش‌ها را انتخاب کنید:", True)
2249
+ return
2250
+
2251
+ if user_text_str in["سلام", "لغو", "/cancel", "❌ لغو", "برگشت♻️"]:
2252
+ user_states[str_chat_id]["mode"] = None
2253
+ user_states[str_chat_id]["file_bytes"] = None
2254
+ await send_with_keyboard(client, chat_id, "سلام! به ربات هوش مصنوعی آلفا خوش آمدید 🤖\n\nلطفاً برای شروع، از کیبورد پایین یکی از بخش‌ها را انتخاب کنید:", True)
2255
+ return
2256
+
2257
+ if user_text_str in["/account", "حساب کاربری 👤"]:
2258
+ is_prem = creds.get("is_premium", False)
2259
+
2260
+ if is_prem:
2261
+ expire_txt = "نامشخص"
2262
+ days_left = 0
2263
+ if creds.get("expire_date"):
2264
+ exp_d = datetime.datetime.fromisoformat(creds["expire_date"])
2265
+ now = datetime.datetime.now()
2266
+ diff = exp_d - now
2267
+ days_left = diff.days if diff.days >= 0 else 0
2268
+
2269
+ jy, jm, jd = gregorian_to_jalali(exp_d.year, exp_d.month, exp_d.day)
2270
+ expire_txt = f"{jy:04d}/{jm:02d}/{jd:02d} (ساعت {exp_d.hour:02d}:{exp_d.minute:02d})"
2271
+
2272
+ status_text = "🌟 نسخه پرو (ویژه)"
2273
+ expire_info = f"\n📅 **تاریخ انقضا:** {expire_txt}\n⏳ **زمان باقیمانده:** {days_left} روز"
2274
+ daily_note = "*نکته: سهمیه پردازشی شما مختص همین دوره یک‌ماهه می‌باشد.*"
2275
+ else:
2276
+ status_text = "🥉 نسخه رایگان (آزمایشی)"
2277
+ expire_info = ""
2278
+ daily_note = "*نکته: سهمیه شما هر روز ساعت ۰۰:۰۰ بامداد به صورت خودکار مجدداً شارژ می‌گردد.*"
2279
+
2280
+ chat_rem = "نامحدود ∞" if is_prem else creds['chat']
2281
+ vc_rem = "نامحدود ∞" if is_prem else creds.get('voice_conv', 0)
2282
+ clone_rem = "نامحدود ∞" if is_prem else creds.get('voice_clone', 0)
2283
+ podcast_rem = "نامحدود ∞" if is_prem else creds['podcast']
2284
+ tts_rem = "نامحدود ∞" if is_prem else creds['tts']
2285
+ file_rem = "نامحدود ∞" if is_prem else creds['file']
2286
+ stt_rem = "نامحدود ∞" if is_prem else creds['stt']
2287
+ image_rem = creds['image']
2288
+ edit_image_rem = creds['edit_image']
2289
+ invited_count = creds.get('invited_count', 0)
2290
+ my_code = get_or_create_referral_code(str_chat_id)
2291
+
2292
+ account_profile = f"""👤 **اطلاعات حساب کاربری شما**
2293
+
2294
+ 🔹 **شناسه یکتا:** `{chat_id}`
2295
+ 🎫 **کد هدیه شما:** `{my_code}`
2296
+ 🔹 **وضعیت اشتراک:** {status_text}{expire_info}
2297
+ 🎁 **تعداد افراد دعوت شده:** {invited_count} نفر
2298
+
2299
+ 📊 **سهمیه باقی‌مانده شما:**
2300
+ - 💬 چت هوشمند: {chat_rem}
2301
+ - 🎨 تولید تصویر: {image_rem} عدد
2302
+ - 🪄 ویرایش تصویر: {edit_image_rem} عدد
2303
+ - 🎙️ تغییر صدا: {vc_rem}
2304
+ - 👤 کلون کردن صدا: {clone_rem}
2305
+ - 🎙 ساخت پادکست: {podcast_rem}
2306
+ - 🗣 تبدیل متن به صدا: {tts_rem}
2307
+ - 📁 تحلیل فایل و سند: {file_rem}
2308
+ - 📝 تبدیل صدا به متن: {stt_rem}
2309
+
2310
+ {daily_note}"""
2311
+ await send_with_keyboard(client, chat_id, account_profile, True)
2312
+ return
2313
+
2314
+ if user_text_str in["/invite", "دعوت دوستان 🎁"]:
2315
+ invites = creds.get("invited_count", 0)
2316
+ remains = 10 - (invites % 10)
2317
+ my_code = get_or_create_referral_code(str_chat_id)
2318
+
2319
+ invite_text = f"""🎁 **سیستم دعوت دوستان (دو سر سود)**
2320
+
2321
+ با دعوت دوستان خود به ربات آلفا، هم شما و هم دوستتان هدیه می‌گیرید!
2322
+ به دوست خود بگویید پس از ورود به ربات، دکمه **«ثبت کد هدیه 🎫»** را بزند و کد زیر را وارد کند.
2323
+ ✨ **سود دوست شما:** در همان لحظه 10 تبدیل رایگان متن به صدا دریافت می‌کند.
2324
+ ✨ **سود شما:** به آمار دعوت‌هایتان اضافه می‌شود و به ازای هر **10 نفر**، **3 روز اشتراک پرو نامحدود** می‌گیرید.
2325
+
2326
+ 📊 **آمار شما:**
2327
+ - تعداد دعوت‌های موفق: {invites} نفر
2328
+ - دعوت‌های باقی‌مانده تا جایزه بعدی: {remains} نفر
2329
+
2330
+ کد هدیه اختصاصی شما:
2331
+ `{my_code}`
2332
+
2333
+ (متن زیر را کپی کرده و برای دوستانتان بفرستید 👇)"""
2334
+ await send_with_keyboard(client, chat_id, invite_text, True)
2335
+
2336
+ forward_text = f"""🤖 **ربات هوش مصنوعی آلفا پرو**
2337
+
2338
+ ✨ با این ربات می‌تونی کارهای زیر رو به راحتی انجام بدی:
2339
+ 💬 چت با پیشرفته‌ترین هوش مصنوعی
2340
+ 🎨 ساخت و ویرایش حرفه‌ای عکس
2341
+ 🎙️ تغییر صدا و کلون کردن صدا
2342
+ 🎙 ساخت پادکست اختصاصی
2343
+ 🗣 تبدیل متن به صدا (30 گوینده مختلف)
2344
+ 📝 تبدیل صدا و ویدیو به متن
2345
+ 📁 تحلیل فایل‌ها و ساخت مقاله
2346
+
2347
+ 👇 اول وارد ربات زیر شو:
2348
+ @aialphabot
2349
+
2350
+ سپس دکمه **«ثبت کد هدیه 🎫»** را بزن و کد 8 رقمی زیر رو وارد کن تا همون اول **10 تا تبدیل صدا هدیه بگیری**:
2351
+ `{my_code}`"""
2352
+ await send_with_keyboard(client, chat_id, forward_text, False)
2353
+ return
2354
+
2355
+ if user_text_str in["/referral", "ثبت کد هدیه 🎫"]:
2356
+ if creds.get("used_referral", False):
2357
+ await send_with_keyboard(client, chat_id, "❌ شما قبلاً کد هدیه یک نفر را ثبت کرده‌اید و فقط یک‌بار مجاز به استفاده از این امکان هستید.", True)
2358
+ return
2359
+ user_states[str_chat_id]["mode"] = "waiting_for_referral_code"
2360
+ msg = "🎫 **ثبت کد هدیه**\n\nکد هدیه 8 رقمی (اعداد) که از دوست خود دریافت کرده‌اید را اینجا وارد کنید تا در همان لحظه **10 سهمیه تبدیل رایگان متن به صدا** هدیه بگیرید!\n\n(برای انصراف دکمه «برگشت♻️» را بزنید)"
2361
+ await send_with_keyboard(client, chat_id, msg, True)
2362
+ return
2363
+
2364
+ if user_text_str in["/buy", "خرید اشتراک 💎"]:
2365
+ buy_text = f"""💎 **خرید اشتراک ویژه آلفا پرو (یک ماهه)**
2366
+
2367
+ با تهیه اشتراک ویژه، محدودیت‌ها را کنار بزنید و از نهایت قدرت هوش مصنوعی لذت ببرید! 🚀
2368
+
2369
+ ━━━━━━━━━━━━━━━━━━━
2370
+ 🎁 **بسته طلایی یک‌ماهه شامل:**
2371
+ 🤖 چت با هوش مصنوعی: نامحدود ∞
2372
+ 🎙️ تغییر صدا و کلون کردن صدا: نامحدود ∞
2373
+ 🗣 تبدیل متن به صدا (۳۰ گوینده): نامحدود ∞
2374
+ 🎙 ساخت پادکست: نامحدود ∞
2375
+ 📁 تحلیل فایل و سند: نامحدود ∞
2376
+ 📝 تبدیل فایل صوتی به متن: نامحدود ∞
2377
+ 🪄 ویرایش تصویر: 5 عدد
2378
+ 🎨 تولید تصویر: 10 عدد
2379
+ ━━━━━━━━━━━━━━━━━━━
2380
+
2381
+ 💳 **هزینه اشتراک یک ماهه:** 250 هزار تومان
2382
+
2383
+ 💳 **شماره کارت جهت واریز:**
2384
+ ➖➖➖➖➖➖➖➖
2385
+ `6219861411958035`
2386
+ ➖➖➖➖➖➖➖➖
2387
+ 👤 **به نام:** کوهی
2388
+
2389
+ ✅ **نحوه فعال‌سازی:**
2390
+ پس از واریز مبلغ، لطفاً رسید پرداختی را به همراه **شناسه یکتای خود** (که در پایین آمده) به آیدی پشتیبانی زیر ارسال کنید تا اشتراک شما فعال گردد:
2391
+
2392
+ 🔑 **شناسه یکتای شما:**
2393
+ `{chat_id}`
2394
+
2395
+ 👨‍💻 **ارتباط با پشتیبانی:**
2396
+ 🆔 @aialpha_admin"""
2397
+ await send_with_keyboard(client, chat_id, buy_text, True)
2398
+ return
2399
+
2400
+ if user_text_str in["/transfer", "انتقال اکانت از برنامه به ربات"]:
2401
+ transfer_text = f"""🔄 **انتقال اکانت از برنامه به ربات**
2402
+
2403
+ کاربر گرامی، در صورتی که داخل برنامه «هوش مصنوعی آلفا» پیش‌تر اشتراک تهیه کرده‌اید، نیازی به خرید مجدد اشتراک داخل ربات نیست! 🎉
2404
+
2405
+ کافیست **شناسه یکتای** ربات روبیکای خود را کپی کرده و برای پشتیبانی ما در برنامه هوش مصنوعی آلفا ارسال کنید تا اکانت اشتراکی شما به سرعت از برنامه به ربات روبیکا انتقال داده شود.
2406
+
2407
+ 🔑 **شناسه یکتای ربات شما:**
2408
+ `{chat_id}`
2409
+
2410
+ 👨‍💻 **دقت کنید شناسه ربات رو به پشتیبانی داخل خود برنامه هوش مصنوعی آلفا ارسال کنید.**"""
2411
+ await send_with_keyboard(client, chat_id, transfer_text, True)
2412
+ return
2413
+
2414
+ if user_text_str in["/chat", "💬 چت", "چت با هوش مصنوعی 🤖"]:
2415
+ user_states[str_chat_id]["mode"] = "chat"
2416
+ user_states[str_chat_id]["history"] =[]
2417
+ await send_with_keyboard(client, chat_id, "💬 شما وارد بخش **چت با هوش مصنوعی** شدید.\n\nهر سوالی دارید بفرستید تا جواب بدم:\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
2418
+ return
2419
+
2420
+ if user_text_str in["/image", "🎨 عکس", "ساخت تصاویر🎨"]:
2421
+ user_states[str_chat_id]["mode"] = "image_waiting_for_text"
2422
+ await send_with_keyboard(client, chat_id, "🎨 شما وارد بخش **ساخت عکس پیشرفته** شدید.\n\nمتن (ایده) خود را به صورت کامل ارسال کنید:\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
2423
+ return
2424
+
2425
+ if user_text_str in["/edit_image", "ویرایش تصاویر 🪄"]:
2426
+ if not creds.get("is_premium", False):
2427
+ msg = """کاربر گرامی،
2428
+
2429
+ ضمن تشکر از توجه شما، به اطلاع می‌رساند که قابلیت ویرایش تصاویر در حال حاضر به صورت رایگان در دسترس نمی‌باشد. این سرویس به دلیل نیاز به منابع پردازشی بالا، جزو خدمات ویژه و نیازمند تهیه اشتراک است.
2430
+
2431
+ با این حال، شما می‌توانید از تست رایگان و امکانات سایر بخش‌های پلتفرم ما بهره‌مند شوید.
2432
+
2433
+ ما همواره در تلاش برای افزایش منابع و اضافه کردن خدمات رایگان بیشتر به کاربران عزیز هستیم.
2434
+
2435
+ در حال حاضر، می‌توانید از سایر بخش‌های رایگان موجود استفاده کنید و یا برای دسترسی کامل و نامحدود به تمامی قابلیت‌ها (از جمله ویرایش تصاویر)، اشتراک تهیه نمایید.
2436
+
2437
+ از صبوری و همراهی شما سپاسگزاریم."""
2438
+ await send_with_keyboard(client, chat_id, msg, False)
2439
+ return
2440
+
2441
+ user_states[str_chat_id]["mode"] = "image_edit_waiting_for_image"
2442
+ user_states[str_chat_id]["file_bytes"] = None
2443
+ await send_with_keyboard(client, chat_id, "🪄 به بخش **ویرایش عکس (Flux.2)** خوش آمدید.\n\nلطفاً ابتدا عکسی که می‌خواهید ویرایش کنید را بفرستید:\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
2444
+ return
2445
+
2446
+ if user_text_str in["/tts", "🎙️ صدا", "تبدیل متن به صدا🗣️"]:
2447
+ user_states[str_chat_id]["mode"] = "tts_waiting_for_text"
2448
+ await send_with_keyboard(client, chat_id, "🎙️ شما وارد بخش **تبدیل متن به صدا** شدید.\n\nلطفاً متنی که می‌خواهید به صدا تبدیل شود را ارسال کنید:\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
2449
+ return
2450
+
2451
+ if user_text_str in["/podcast", "📻 پادکست", "ساخت پادکست 🎙️"]:
2452
+ user_states[str_chat_id]["mode"] = "podcast_waiting_for_topic"
2453
+ await send_with_keyboard(client, chat_id, "📻 شما وارد بخش **ساخت پادکست** شدید.\n\nلطفاً موضوع پادکست خود را بفرستید.\nمثال: درباره تاریخچه پیدایش قهوه با ۳ گوینده یک پادکست جذاب بساز . همچنین این قسمت متصل به مدل زبانی است و درخواست هارو قبل از ساخت درک میکنه. میتوانید مقاله کامل یک سایت بفرستید با تبلیغات یا هرچی، هوش مصنوعی متن مقاله رو استخراج و پادکست براتون میسازه . در توضیحات امکان مشخص کردن تعداد گوینده به همراه اسم شون نیز از سمت شما امکان پذیر است.\n\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
2454
+ return
2455
+
2456
+ if user_text_str in["/vc", "تغییر صدا 🎙️"]:
2457
+ user_states[str_chat_id]["mode"] = "vc_waiting_for_voice"
2458
+ user_states[str_chat_id]["file_bytes"] = None
2459
+ await send_with_keyboard(client, chat_id, "🎙️ شما وارد بخش **تغییر صدا** شدید.\n\nلطفاً صدای خود (ویس) را بفرستید تا آن را به صدای شخصیت‌های معروف تبدیل کنم:\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
2460
+ return
2461
+
2462
+ if user_text_str in["/clone", "کلون کردن صدا 👤"]:
2463
+ user_states[str_chat_id]["mode"] = "clone_waiting_for_src"
2464
+ user_states[str_chat_id]["file_bytes"] = None
2465
+ user_states[str_chat_id]["ref_bytes"] = None
2466
+ clone_text = """👤 **شما وارد بخش کلون کردن صدای اختصاصی شدید.**
2467
+
2468
+ ✨ **این بخش چه کاری انجام می‌دهد؟**
2469
+ با این ویژگی بی‌نظیر، شما می‌توانید صدای خود (یا هر فرد دیگری) را دقیقاً شبیه‌سازی کنید! کافیست یک نمونه از صدای خودتان صحبت کنید و یک نمونه از صدای شخص مورد نظر (الگو) را به هوش مصنوعی بدهید. ربات لحن و کلمات شما را گرفته و دقیقاً با جنس صدای شخص الگو بازسازی می‌کند.
2470
+
2471
+ 📌 **راهنمای استفاده:**
2472
+ شما در این مرحله به **2 فایل صوتی** نیاز دارید:
2473
+ 1️⃣ **صدای ورودی (شما):** صدایی که می‌خواهید متن و لحن آن خوانده شود.
2474
+ 2️⃣ **صدای الگو (هدف):** صدایی که می‌خواهید خروجی نهایی شبیه به آن شود (بدون نویز و موزیک پس‌زمینه، بین ۳ تا ۱۰ ثانیه بهترین نتیجه را می‌دهد).
2475
+
2476
+ 👇 **مرحله اول:**
2477
+ لطفاً ابتدا **صدای خودتان (ورودی)** را به صورت ویس یا فایل صوتی ارسال کنید:
2478
+
2479
+ *(برای خروج دکمه «برگشت♻️» را بزنید)*"""
2480
+ await send_with_keyboard(client, chat_id, clone_text, True)
2481
+ return
2482
+
2483
+ if user_text_str in["/file", "تحلیل فایل 📁"]:
2484
+ user_states[str_chat_id]["mode"] = "file_waiting_for_file"
2485
+ user_states[str_chat_id]["file_bytes"] = None
2486
+ await send_with_keyboard(client, chat_id, "📁 شما وارد بخش **تحلیل فایل اختصاصی** شدید.\n\nلطفاً فایل خود را ارسال کنید:\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
2487
+ return
2488
+
2489
+ if user_text_str in["/stt", "فایل صوتی به متن 📝"]:
2490
+ user_states[str_chat_id]["mode"] = "stt_waiting_for_audio"
2491
+ await send_with_keyboard(client, chat_id, "📝 شما وارد بخش **تبدیل صدا به متن** شدید.\n\nلطفاً فایل خود (ویس، آهنگ، ویدیو و...) را ارسال کنید:\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
2492
+ return
2493
+
2494
+ if user_text_str in["/create_file", "ساخت فایل 📄"]:
2495
+ user_states[str_chat_id]["mode"] = "create_file_waiting_for_topic"
2496
+ await send_with_keyboard(client, chat_id, "📄 شما وارد بخش **ساخت فایل** شدید.\n\nلطفاً موضوع مقاله‌ای که می‌خواهید را کامل بفرستید.\nمثال: نحوه مدیریت زمان\n\nهوش مصنوعی یک مقاله کامل و طولانی نوشته و در نهایت فایل PDF و Word آن را به شما تحویل می‌دهد.\n\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
2497
+ return
2498
+
2499
+ current_mode = user_states[str_chat_id].get("mode")
2500
+
2501
+ if current_mode is None:
2502
+ if is_file: pass
2503
+ elif user_text_str: await send_with_keyboard(client, chat_id, "⚠️ لطفاً ابتدا از کیبورد پایین، بخش مورد نظرتان را انتخاب کنید:", True)
2504
+ return
2505
+
2506
+ elif current_mode == "waiting_for_referral_code":
2507
+ if user_text_str:
2508
+ normalized_code = to_english_digits(user_text_str).strip()
2509
+
2510
+ if not normalized_code.isdigit() or len(normalized_code) != 8:
2511
+ await send_with_keyboard(client, chat_id, "❌ کد وارد شده نامعتبر است. لطفاً یک کد 8 رقمی صحیح بفرستید.", False)
2512
+ return
2513
+
2514
+ inviter_id = find_user_by_referral_code(normalized_code)
2515
+
2516
+ if not inviter_id:
2517
+ await send_with_keyboard(client, chat_id, "❌ کد هدیه یافت نشد. لطفاً کد را با دقت بررسی کنید.", False)
2518
+ return
2519
+
2520
+ if str(inviter_id) == str(str_chat_id):
2521
+ await send_with_keyboard(client, chat_id, "❌ شما نمی‌توانید کد خودتان را ثبت کنید!", False)
2522
+ return
2523
+
2524
+ user_states[str_chat_id]["mode"] = None
2525
+
2526
+ user_credits_db[str_chat_id]["used_referral"] = True
2527
+ user_credits_db[str_chat_id]["tts"] = user_credits_db[str_chat_id].get("tts", 0) + 10
2528
+
2529
+ user_credits_db[inviter_id]["invited_count"] = user_credits_db[inviter_id].get("invited_count", 0) + 1
2530
+ current_invites = user_credits_db[inviter_id]["invited_count"]
2531
+
2532
+ if current_invites > 0 and current_invites % 10 == 0:
2533
+ inviter_data = user_credits_db[inviter_id]
2534
+ inviter_data["is_premium"] = True
2535
+ now = datetime.datetime.now()
2536
+ if inviter_data.get("expire_date"):
2537
+ try:
2538
+ current_exp = datetime.datetime.fromisoformat(inviter_data["expire_date"])
2539
+ if current_exp > now:
2540
+ new_exp = current_exp + datetime.timedelta(days=3)
2541
+ else:
2542
+ new_exp = now + datetime.timedelta(days=3)
2543
+ except:
2544
+ new_exp = now + datetime.timedelta(days=3)
2545
+ else:
2546
+ new_exp = now + datetime.timedelta(days=3)
2547
+
2548
+ inviter_data["expire_date"] = new_exp.isoformat()
2549
+ inviter_data["chat"] = 999999
2550
+ inviter_data["image"] = 10
2551
+ inviter_data["edit_image"] = 5
2552
+ inviter_data["podcast"] = 999999
2553
+ inviter_data["tts"] = 999999
2554
+ inviter_data["file"] = 999999
2555
+ inviter_data["stt"] = 999999
2556
+
2557
+ save_db(user_credits_db)
2558
+ try:
2559
+ msg_text = f"🎉 **تبریک ویژه!**\nیک دوست کد هدیه شما را ثبت کرد.\nتعداد کل دعوت‌های شما: {current_invites} نفر\n\n🎁 **هدیه شما:** ۳ روز اشتراک پرو نامحدود به حساب شما افزوده شد!"
2560
+ asyncio.create_task(send_with_keyboard(client, inviter_id, msg_text, True))
2561
+ except: pass
2562
+ else:
2563
+ save_db(user_credits_db)
2564
+ remains = 10 - (current_invites % 10)
2565
+ try:
2566
+ msg_text = f"🎉 **تبریک!**\nیک دوست کد هدیه شما را ثبت کرد.\nتعداد کل دعوت‌های شما: {current_invites} نفر\n\n⏳ با دعوت {remains} نفر دیگر، ۳ روز اشتراک رایگان دریافت می‌کنید!"
2567
+ asyncio.create_task(send_with_keyboard(client, inviter_id, msg_text, True))
2568
+ except: pass
2569
+
2570
+ await send_with_keyboard(client, chat_id, "✅ کد هدیه با موفقیت ثبت شد!\n🎁 **10 سهمیه تبدیل رایگان متن به صدا** به حساب شما اضافه گردید.", True)
2571
+ return
2572
+
2573
+ elif current_mode == "chat":
2574
+ if is_file:
2575
+ await send_with_keyboard(client, chat_id, "📥 در حال دانلود فایل...", False)
2576
+ try:
2577
+ file_bytes = await helper_download_file(client, msg_obj)
2578
+ user_states[str_chat_id]["file_bytes"] = file_bytes
2579
+ user_states[str_chat_id]["file_name"] = file_name
2580
+ user_states[str_chat_id]["mode"] = "chat_waiting_for_prompt"
2581
+ await send_with_keyboard(client, chat_id, "✅ فایل با موفقیت دریافت شد.\n\nحالا لطفاً متنی بفرستید و بگویید **چه کاری با این فایل انجام دهم؟**\n(مثلاً: این تصویر را توصیف کن، یا متن این سند را خلاصه کن)", False)
2582
+ except Exception as dl_err:
2583
+ await send_with_keyboard(client, chat_id, f"❌ خطا در دریافت فایل!\n{str(dl_err)}", False)
2584
+ elif user_text_str:
2585
+ asyncio.create_task(process_gemini(client, chat_id, user_text_str))
2586
+ return
2587
+
2588
+ elif current_mode == "chat_waiting_for_prompt":
2589
+ if user_text_str:
2590
+ saved_bytes = user_states[str_chat_id].get("file_bytes")
2591
+ saved_name = user_states[str_chat_id].get("file_name", "file.jpeg")
2592
+ user_states[str_chat_id]["mode"] = "chat"
2593
+ user_states[str_chat_id]["file_bytes"] = None
2594
+ asyncio.create_task(process_gemini(client, chat_id, user_text_str, file_bytes=saved_bytes, file_name=saved_name))
2595
+ else:
2596
+ await send_with_keyboard(client, chat_id, "⚠️ لطفاً درخواست خود را متنی بنویسید.", False)
2597
+ return
2598
+
2599
+ elif current_mode == "image_waiting_for_text":
2600
+ if user_text_str:
2601
+ user_states[str_chat_id]["text"] = user_text_str
2602
+ user_states[str_chat_id]["mode"] = "image_waiting_for_size"
2603
+
2604
+ size_menu = """🖼 **لطفاً ابعاد تصویر خود را انتخاب کنید:**
2605
+
2606
+ 1️⃣ `1:1` (مربع) - مناسب پروفایل ⬛
2607
+ 2️⃣ `9:16` (عمودی) - مناسب استوری و پس‌زمینه گوشی 📱
2608
+ 3️⃣ `16:9` (افقی) - مناسب دسکتاپ و ویدیو 🖥️
2609
+ 4️⃣ `4:3` (استاندارد) - مناسب چاپ و پست 📸
2610
+
2611
+ (لطفاً فقط عدد 1 تا 4 را بفرستید)"""
2612
+ await send_with_keyboard(client, chat_id, size_menu, False)
2613
+ else:
2614
+ await send_with_keyboard(client, chat_id, "⚠️ لطفاً ایده عکس خود را به صورت متنی بفرستید.", False)
2615
+ return
2616
+
2617
+ elif current_mode == "image_waiting_for_size":
2618
+ normalized_choice = to_english_digits(user_text_str).strip()
2619
+ if normalized_choice in["1", "2", "3", "4"]:
2620
+ saved_text = user_states[str_chat_id].get("text", "")
2621
+ user_states[str_chat_id]["mode"] = None
2622
+ asyncio.create_task(process_image(client, chat_id, saved_text, normalized_choice))
2623
+ else:
2624
+ await send_with_keyboard(client, chat_id, "❌ عدد وارد شده نامعتبر است! لطفاً فقط یکی از اعداد 1 تا 4 را بفرستید.", False)
2625
+ return
2626
+
2627
+ elif current_mode == "image_edit_waiting_for_image":
2628
+ if not is_file: return await send_with_keyboard(client, chat_id, "⚠️ لطفاً ابتدا یک عکس ارسال کنید.", False)
2629
+ await send_with_keyboard(client, chat_id, "📥 در حال دانلود عکس...", False)
2630
+ try:
2631
+ file_bytes = await helper_download_file(client, msg_obj)
2632
+ user_states[str_chat_id]["file_bytes"] = file_bytes
2633
+ user_states[str_chat_id]["mode"] = "image_edit_waiting_for_prompt"
2634
+ await send_with_keyboard(client, chat_id, "✅ عکس با موفقیت دریافت شد.\n\nحالا دستور خود را به صورت متنی تایپ کنید.\nمثال: یک کلاه قرمز روی سر این گربه بگذار.", False)
2635
+ except Exception as dl_err: await send_with_keyboard(client, chat_id, f"❌ خطا در دریافت عکس!\n{str(dl_err)}", False)
2636
+ return
2637
+
2638
+ elif current_mode == "image_edit_waiting_for_prompt":
2639
+ if user_text_str:
2640
+ saved_bytes = user_states[str_chat_id].get("file_bytes")
2641
+ user_states[str_chat_id]["mode"] = None
2642
+ user_states[str_chat_id]["file_bytes"] = None
2643
+ asyncio.create_task(process_image_edit(client, chat_id, saved_bytes, user_text_str))
2644
+ else: await send_with_keyboard(client, chat_id, "⚠️ لطفاً درخواست خود را متنی بنویسید.", False)
2645
+ return
2646
+
2647
+ elif current_mode == "tts_waiting_for_text":
2648
+ if user_text_str:
2649
+ if len(user_text_str) > 2500: return await send_with_keyboard(client, chat_id, "⚠️ لطفاً متنی کوتاه‌تر از 2500 کاراکتر بفرستید.", False)
2650
+ user_states[str_chat_id]["text"] = user_text_str
2651
+ user_states[str_chat_id]["mode"] = "tts_waiting_for_speaker"
2652
+
2653
+ speakers_menu = """✅ متن شما ذخیره شد.
2654
+ لطفاً **شماره** گوینده مورد نظر خود را بفرستید:
2655
+ 1. شهاب | 2. آوا | 3. نوید
2656
+ 4. آرمان | 5. مهسا | 6. دانا
2657
+ 7. سامان | 8. آرش | 9. شبنم
2658
+ 10. سحر | 11. مریم | 12. بهرام
2659
+ 13. نیکان| 14. فرناز | 15. سارا
2660
+ 16. مانی | 17. آرتین | 18. دلنواز
2661
+ 19. روژان | 20. امید | 21. بردیا
2662
+ 22. ترانه | 23. نیکو | 24. هستی
2663
+ 25. کامیار| 26. کیانوش| 27. پویا
2664
+ 28. مهتاب | 29. سام | 30. لیدا"""
2665
+ await send_with_keyboard(client, chat_id, speakers_menu, False)
2666
+ return
2667
+
2668
+ elif current_mode == "tts_waiting_for_speaker":
2669
+ normalized_text = to_english_digits(user_text_str)
2670
+
2671
+ if normalized_text.isdigit() and normalized_text in SPEAKERS:
2672
+ spk_name, spk_id = SPEAKERS[normalized_text]
2673
+ txt = user_states[str_chat_id]["text"]
2674
+ user_states[str_chat_id]["mode"] = "tts_waiting_for_text"
2675
+ asyncio.create_task(process_tts(client, chat_id, txt, spk_id, spk_name))
2676
+ else:
2677
+ await send_with_keyboard(client, chat_id, "❌ شماره نامعتبر است! لطفاً فقط یک عدد بین 1 تا 30 بفرستید.", False)
2678
+ return
2679
+
2680
+ elif current_mode == "podcast_waiting_for_topic":
2681
+ if user_text_str: asyncio.create_task(process_podcast(client, chat_id, user_text_str))
2682
+ else: await send_with_keyboard(client, chat_id, "⚠️ لطفاً موضوع پادکست خود را به صورت متنی بفرستید.", False)
2683
+ return
2684
+
2685
+ elif current_mode == "stt_waiting_for_audio":
2686
+ if not is_file: return await send_with_keyboard(client, chat_id, "⚠️ لطفاً یک فایل ارسال کنید.", False)
2687
+ await send_with_keyboard(client, chat_id, "📥 در حال دانلود فایل...", False)
2688
+ try:
2689
+ audio_bytes = await helper_download_file(client, msg_obj)
2690
+ asyncio.create_task(process_stt(client, chat_id, audio_bytes, file_name))
2691
+ except Exception as dl_err: await send_with_keyboard(client, chat_id, f"❌ خطا در دانلود فایل!\n{str(dl_err)}", False)
2692
+ return
2693
+
2694
+ elif current_mode == "file_waiting_for_file":
2695
+ if not is_file: return await send_with_keyboard(client, chat_id, "⚠️ لطفاً ابتدا یک فایل ارسال کنید.", False)
2696
+ await send_with_keyboard(client, chat_id, "📥 در حال دریافت فایل...", False)
2697
+ try:
2698
+ file_bytes = await helper_download_file(client, msg_obj)
2699
+ user_states[str_chat_id]["file_bytes"] = file_bytes
2700
+ user_states[str_chat_id]["file_name"] = file_name
2701
+ user_states[str_chat_id]["mode"] = "file_waiting_for_prompt"
2702
+ await send_with_keyboard(client, chat_id, "✅ فایل با موفقیت دریافت شد.\n\nحالا لطفاً متنی بگویید **چگونه تحلیل شود؟**\n(می‌توانید سوال خاصی بپرسید یا فقط بخواهید فایل را توضیح دهد)", False)
2703
+ except Exception as dl_err: await send_with_keyboard(client, chat_id, f"❌ خطا در دریافت فایل!\n{str(dl_err)}", False)
2704
+ return
2705
+
2706
+ elif current_mode == "file_waiting_for_prompt":
2707
+ if user_text_str:
2708
+ saved_bytes = user_states[str_chat_id].get("file_bytes")
2709
+ saved_name = user_states[str_chat_id].get("file_name", "file.jpeg")
2710
+ user_states[str_chat_id]["mode"] = "file_waiting_for_file"
2711
+ asyncio.create_task(process_file_analysis(client, chat_id, saved_bytes, saved_name, user_text_str))
2712
+ else: await send_with_keyboard(client, chat_id, "⚠️ لطفاً درخواست خود را متنی بنویسید.", False)
2713
+ return
2714
+
2715
+ elif current_mode == "create_file_waiting_for_topic":
2716
+ if user_text_str:
2717
+ asyncio.create_task(process_create_file(client, chat_id, user_text_str))
2718
+ else:
2719
+ await send_with_keyboard(client, chat_id, "⚠️ لطفاً موضوع مقاله خود را به صورت متنی بفرستید.", False)
2720
+ return
2721
+
2722
+ elif current_mode == "vc_waiting_for_voice":
2723
+ if not is_file: return await send_with_keyboard(client, chat_id, "⚠️ لطفاً یک فایل صوتی یا ویس ارسال کنید.", False)
2724
+ await send_with_keyboard(client, chat_id, "📥 در حال دانلود فایل صوتی شما...", False)
2725
+ try:
2726
+ file_bytes = await helper_download_file(client, msg_obj)
2727
+ user_states[str_chat_id]["file_bytes"] = file_bytes
2728
+ user_states[str_chat_id]["mode"] = "vc_waiting_for_model"
2729
+
2730
+ model_menu = "✅ صدای شما دریافت شد.\n\nلطفا **شماره** مدلی که می‌خواهید صدایتان به آن تبدیل شود را ارسال کنید:\n\n"
2731
+ for k, v in LEGACY_MODELS.items():
2732
+ if k == "8":
2733
+ model_menu += f"{k}. {v['name']} (نامحدود رایگان)\n"
2734
+ else:
2735
+ model_menu += f"{k}. {v['name']}\n"
2736
+ model_menu += "➖➖➖➖➖➖➖➖\n"
2737
+ for k, v in STANDARD_MODELS.items(): model_menu += f"{k}. {v['name']}\n"
2738
+
2739
+ await send_with_keyboard(client, chat_id, model_menu, False)
2740
+ except Exception as dl_err:
2741
+ await send_with_keyboard(client, chat_id, f"❌ خطا در دریافت فایل!\n{str(dl_err)}", False)
2742
+ return
2743
+
2744
+ elif current_mode == "vc_waiting_for_model":
2745
+ choice = to_english_digits(user_text_str).strip()
2746
+
2747
+ if choice in STANDARD_MODELS:
2748
+ if creds["voice_conv"] <= 0: return await send_with_keyboard(client, chat_id, "❌ سهمیه تغییر صدای شما تمام شده است. لطفاً از منوی اصلی وارد بخش «خرید اشتراک 💎» شوید.", False)
2749
+ user_states[str_chat_id]["mode"] = None
2750
+ model = STANDARD_MODELS[choice]
2751
+ src_bytes = user_states[str_chat_id]["file_bytes"]
2752
+ await send_with_keyboard(client, chat_id, "📥 در حال آماده‌سازی فایل‌ها...", False)
2753
+ ref_bytes = await helper_download_url_to_bytes(model["ref"])
2754
+ if not ref_bytes: return await send_with_keyboard(client, chat_id, "❌ خطا در دسترسی به فایل صدای مدل.", False)
2755
+
2756
+ asyncio.create_task(process_standard_vc_job(client, chat_id, src_bytes, ref_bytes, model["name"], "voice_conv"))
2757
+
2758
+ elif choice in LEGACY_MODELS:
2759
+ if choice != "8" and creds["voice_conv"] <= 0:
2760
+ return await send_with_keyboard(client, chat_id, "❌ سهمیه تغییر صدای شما تمام شده است. لطفاً از منوی اصلی وارد بخش «خرید اشتراک 💎» شوید.", False)
2761
+
2762
+ user_states[str_chat_id]["selected_model"] = choice
2763
+ user_states[str_chat_id]["mode"] = "vc_waiting_for_gender"
2764
+
2765
+ gender_msg = f"✅ مدل {LEGACY_MODELS[choice]['name']} انتخاب شد.\n\nبرای تنظیم دقیق فرکانس‌ها به ما بگویید صدایی که خودتان فرستادید صدای یک **مرد** است یا **زن**؟\n\n1. مرد 👨\n2. زن 👩"
2766
+ await send_with_keyboard(client, chat_id, gender_msg, False)
2767
+ else:
2768
+ await send_with_keyboard(client, chat_id, "❌ شماره وارد شده صحیح نیست. لطفاً فقط عدد مدل را بفرستید.", False)
2769
+ return
2770
+
2771
+ elif current_mode == "vc_waiting_for_gender":
2772
+ choice = to_english_digits(user_text_str).strip()
2773
+ if choice not in["1", "2"]:
2774
+ return await send_with_keyboard(client, chat_id, "❌ لطفاً عدد 1 (مرد) یا 2 (زن) را ارسال کنید.", False)
2775
+
2776
+ user_gender = "male" if choice == "1" else "female"
2777
+ model_key = user_states[str_chat_id]["selected_model"]
2778
+ model = LEGACY_MODELS[model_key]
2779
+ target_gender = model["gender"]
2780
+
2781
+ pitch = 0
2782
+ if target_gender == "female" and user_gender == "male": pitch = 12
2783
+ elif target_gender == "male" and user_gender == "female": pitch = -12
2784
+
2785
+ user_states[str_chat_id]["mode"] = None
2786
+ src_bytes = user_states[str_chat_id]["file_bytes"]
2787
+ asyncio.create_task(process_legacy_vc_job(client, chat_id, src_bytes, model["url"], pitch, model["name"]))
2788
+ return
2789
+
2790
+ elif current_mode == "clone_waiting_for_src":
2791
+ if not is_file: return await send_with_keyboard(client, chat_id, "⚠️ لطفاً فایل صوتی صدای خودتان را بفرستید.", False)
2792
+ await send_with_keyboard(client, chat_id, "📥 در حال دانلود صدای شما...", False)
2793
+ try:
2794
+ file_bytes = await helper_download_file(client, msg_obj)
2795
+ user_states[str_chat_id]["file_bytes"] = file_bytes
2796
+ user_states[str_chat_id]["mode"] = "clone_waiting_for_ref"
2797
+ await send_with_keyboard(client, chat_id, "✅ صدای شما دریافت شد.\n\nحالا **فایل الگو (صدای شخصی که می‌خواهید شبیه‌سازی کنید)** را ارسال کنید.\n(پیشنهاد: فایل بدون نویز و موسیقی، بین ۳ تا ۱۰ ثانیه)", False)
2798
+ except Exception as dl_err:
2799
+ await send_with_keyboard(client, chat_id, f"❌ خطا در دریافت فایل!\n{str(dl_err)}", False)
2800
+ return
2801
+
2802
+ elif current_mode == "clone_waiting_for_ref":
2803
+ if not is_file: return await send_with_keyboard(client, chat_id, "⚠️ لطفاً فایل صوتی ��لگوی هدف را بفرستید.", False)
2804
+ await send_with_keyboard(client, chat_id, "📥 در حال دانلود صدای الگو...", False)
2805
+ try:
2806
+ ref_bytes = await helper_download_file(client, msg_obj)
2807
+
2808
+ if creds["voice_clone"] <= 0:
2809
+ return await send_with_keyboard(client, chat_id, "❌ سهمیه کلون کردن صدای شما تمام شده است. نیازمند تهیه اشتراک هستید.", False)
2810
+
2811
+ user_states[str_chat_id]["mode"] = None
2812
+ src_bytes = user_states[str_chat_id]["file_bytes"]
2813
+
2814
+ asyncio.create_task(process_standard_vc_job(client, chat_id, src_bytes, ref_bytes, "صدای اختصاصی (کلون شده)", "voice_clone"))
2815
+ except Exception as dl_err:
2816
+ await send_with_keyboard(client, chat_id, f"❌ خطا در دریافت فایل!\n{str(dl_err)}", False)
2817
+ return
2818
 
2819
  except Exception: traceback.print_exc()
2820
 
 
2828
 
2829
  loop.create_task(ram_garbage_collector())
2830
 
2831
+ print("🚀 ربات آلفا پرو (نسخه صنعتی + دیتابیس هوشمند + فیلتر زمان قطعی + 256 تونل همزمان) روشن شد...")
2832
  bot.run()