Update main.py
Browse files
main.py
CHANGED
|
@@ -18,7 +18,7 @@ app = Flask(__name__)
|
|
| 18 |
|
| 19 |
@app.route('/')
|
| 20 |
def home():
|
| 21 |
-
return "ربات یکپارچه آلفا (نسخه پرو + دانلود فایل ۱۰۰٪ تضمینی) روشن است! 🚀"
|
| 22 |
|
| 23 |
def run_flask():
|
| 24 |
app.run(host="0.0.0.0", port=7860)
|
|
@@ -26,7 +26,7 @@ def run_flask():
|
|
| 26 |
|
| 27 |
# --- ساختار کیبورد پایین صفحه (Chat Keypad) ---
|
| 28 |
MAIN_KEYPAD_DICT = {
|
| 29 |
-
"rows":
|
| 30 |
{
|
| 31 |
"buttons":[
|
| 32 |
{"id": "chat_btn", "type": "Simple", "button_text": "چت با هوش مصنوعی 🤖"}
|
|
@@ -158,9 +158,8 @@ async def helper_upload_file(client, chat_id, file_name, file_type="Image", capt
|
|
| 158 |
abs_path = os.path.abspath(file_name)
|
| 159 |
error_logs =[]
|
| 160 |
|
| 161 |
-
api_file_type = "Image" if file_type in
|
| 162 |
|
| 163 |
-
# --- تلاش اول: ارسال مستقیم از طریق API خام روبیکا (بهترین کیفیت) ---
|
| 164 |
try:
|
| 165 |
url_request = f"https://botapi.rubika.ir/v3/{bot_token}/requestSendFile"
|
| 166 |
url_send = f"https://botapi.rubika.ir/v3/{bot_token}/sendFile"
|
|
@@ -171,7 +170,6 @@ async def helper_upload_file(client, chat_id, file_name, file_type="Image", capt
|
|
| 171 |
|
| 172 |
if req_data.get("status") == "OK":
|
| 173 |
data_dict = req_data.get("data", {})
|
| 174 |
-
# دریافت آدرس آپلود و آیدی فایل
|
| 175 |
upload_url = data_dict.get("upload_url")
|
| 176 |
file_id = data_dict.get("id") or data_dict.get("file_id")
|
| 177 |
|
|
@@ -207,7 +205,6 @@ async def helper_upload_file(client, chat_id, file_name, file_type="Image", capt
|
|
| 207 |
except Exception as e:
|
| 208 |
error_logs.append(f"Raw HTTP Error: {e}")
|
| 209 |
|
| 210 |
-
# --- تلاش دوم (پشتیبان تضمینی): استفاده از متد داخلی بدون آرگومان Caption ---
|
| 211 |
try:
|
| 212 |
if hasattr(client, "send_file"):
|
| 213 |
await client.send_file(chat_id, abs_path)
|
|
@@ -220,7 +217,6 @@ async def helper_upload_file(client, chat_id, file_name, file_type="Image", capt
|
|
| 220 |
return "\n".join(error_logs)
|
| 221 |
|
| 222 |
|
| 223 |
-
# --- لیست تمام سرورهای تولید صدای شما ---
|
| 224 |
WORKER_URLS =[
|
| 225 |
"https://hamed744-ttspro.hf.space/generate",
|
| 226 |
"https://hamed744-ttspro2.hf.space/generate",
|
|
@@ -249,8 +245,8 @@ SPEAKERS = {
|
|
| 249 |
user_states = {}
|
| 250 |
|
| 251 |
|
| 252 |
-
# --- ۱. پردازش چت متنی ---
|
| 253 |
-
async def process_gemini(client, chat_id, prompt):
|
| 254 |
if not GEMINI_KEYS:
|
| 255 |
await send_with_keyboard(client, chat_id, "❌ کلیدهای API جیمینای تنظیم نشدهاند.", False)
|
| 256 |
return
|
|
@@ -259,10 +255,40 @@ async def process_gemini(client, chat_id, prompt):
|
|
| 259 |
|
| 260 |
history = user_states[chat_id].get("history",[])
|
| 261 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 262 |
if history and history[-1]["role"] == "user":
|
| 263 |
-
|
|
|
|
| 264 |
else:
|
| 265 |
-
history.append({"role": "user", "parts":
|
| 266 |
|
| 267 |
# تغییر تاریخچه به ۴۰ مورد برای ذخیره کردن ۲۰ سوال و جواب (۲۰ پیام رفت و برگشت)
|
| 268 |
if len(history) > 40:
|
|
@@ -279,7 +305,7 @@ async def process_gemini(client, chat_id, prompt):
|
|
| 279 |
url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key={key}"
|
| 280 |
payload = {"contents": history, "generationConfig": {"temperature": 0.7, "maxOutputTokens": 8192}}
|
| 281 |
try:
|
| 282 |
-
async with session.post(url, json=payload, timeout=
|
| 283 |
if response.status == 200:
|
| 284 |
data = await response.json()
|
| 285 |
try:
|
|
@@ -302,7 +328,7 @@ async def process_gemini(client, chat_id, prompt):
|
|
| 302 |
if not final_answer:
|
| 303 |
if history and history[-1]["role"] == "user":
|
| 304 |
history.pop()
|
| 305 |
-
await send_with_keyboard(client, chat_id, "❌ متأسفانه پاسخی دریافت نشد.
|
| 306 |
return
|
| 307 |
|
| 308 |
history.append({"role": "model", "parts":[{"text": final_answer}]})
|
|
@@ -378,7 +404,6 @@ async def process_image(client, chat_id, prompt):
|
|
| 378 |
await asyncio.sleep(1)
|
| 379 |
caption_text = "🎨 تصویر شما آماده شد!\n(مدل: Z-Image-Turbo)"
|
| 380 |
|
| 381 |
-
# آپلود مستقیم به سرور اصلی روبیکا
|
| 382 |
upload_result = await helper_upload_file(client, chat_id, file_name, "Image", caption_text)
|
| 383 |
|
| 384 |
if upload_result is not True:
|
|
@@ -428,7 +453,7 @@ async def process_tts(client, chat_id, user_text, speaker_id, speaker_name):
|
|
| 428 |
if isinstance(proc_msg, dict):
|
| 429 |
msg_id = proc_msg.get('message_update', {}).get('message_id') or proc_msg.get('message_id')
|
| 430 |
if msg_id:
|
| 431 |
-
await client.delete_messages(chat_id,
|
| 432 |
except Exception: pass
|
| 433 |
|
| 434 |
if audio_bytes:
|
|
@@ -437,7 +462,6 @@ async def process_tts(client, chat_id, user_text, speaker_id, speaker_name):
|
|
| 437 |
|
| 438 |
await asyncio.sleep(1)
|
| 439 |
|
| 440 |
-
# آپلود مستقیم به سرور اصلی روبیکا
|
| 441 |
upload_result = await helper_upload_file(client, chat_id, file_name, "Voice", "✅ پردازش صدای شما انجام شد.")
|
| 442 |
|
| 443 |
if upload_result is not True:
|
|
@@ -459,23 +483,20 @@ async def process_stt(client, chat_id, audio_bytes, file_name):
|
|
| 459 |
|
| 460 |
proc_msg = await send_with_keyboard(client, chat_id, "📝 در حال گوش دادن و پیادهسازی متن توسط جیمینای... (لطفاً صبور باشید)", False)
|
| 461 |
|
| 462 |
-
# تبدیل مستقیم بایتهای صوتی به Base64
|
| 463 |
base64_data = base64.b64encode(audio_bytes).decode('utf-8')
|
| 464 |
|
| 465 |
-
# حدس زدن فرمت برای ارسال به جیمینای
|
| 466 |
mime_type, _ = mimetypes.guess_type(file_name)
|
| 467 |
if not mime_type:
|
| 468 |
if file_name.endswith(('.ogg', '.oga')): mime_type = "audio/ogg"
|
| 469 |
elif file_name.endswith('.wav'): mime_type = "audio/wav"
|
| 470 |
elif file_name.endswith('.mp3'): mime_type = "audio/mp3"
|
| 471 |
elif file_name.endswith('.mp4'): mime_type = "video/mp4"
|
| 472 |
-
else: mime_type = "audio/ogg"
|
| 473 |
|
| 474 |
keys_to_try = GEMINI_KEYS.copy()
|
| 475 |
random.shuffle(keys_to_try)
|
| 476 |
transcribed_text = None
|
| 477 |
|
| 478 |
-
# دستور متنی به جیمینای برای گرفتن دقیقترین استخراج متن
|
| 479 |
prompt = "لطفاً این فایل صوتی/تصویری را با دقت کامل گوش بده و صحبتهای داخل آن را کلمه به کلمه به متن تبدیل کن. هیچ توضیح اضافهای نده و فقط متن پیادهسازی شده را بفرست."
|
| 480 |
|
| 481 |
async with aiohttp.ClientSession() as session:
|
|
@@ -510,7 +531,7 @@ async def process_stt(client, chat_id, audio_bytes, file_name):
|
|
| 510 |
await send_with_keyboard(client, chat_id, f"❌ تبدیل فایل به متن ناموفق بود.\n(احتمالاً فرمت فایل پشتیبانی نمیشود یا فایل شما صوتی نیست)", True)
|
| 511 |
|
| 512 |
|
| 513 |
-
# --- ۵. پردازش تحلیل
|
| 514 |
async def process_file_analysis(client, chat_id, file_bytes, file_name, prompt):
|
| 515 |
if not GEMINI_KEYS:
|
| 516 |
await send_with_keyboard(client, chat_id, "❌ کلیدهای API جیمینای تنظیم نشدهاند.", False)
|
|
@@ -526,7 +547,7 @@ async def process_file_analysis(client, chat_id, file_bytes, file_name, prompt):
|
|
| 526 |
elif file_name.endswith('.pdf'): mime_type = "application/pdf"
|
| 527 |
elif file_name.endswith('.mp4'): mime_type = "video/mp4"
|
| 528 |
elif file_name.endswith('.mp3'): mime_type = "audio/mp3"
|
| 529 |
-
elif file_name.endswith('.ogg'): mime_type = "audio/ogg"
|
| 530 |
elif file_name.endswith('.wav'): mime_type = "audio/wav"
|
| 531 |
else: mime_type = "image/jpeg"
|
| 532 |
|
|
@@ -611,7 +632,7 @@ else:
|
|
| 611 |
|
| 612 |
if user_text_str in["/chat", "💬 چت", "چت با هوش مصنوعی 🤖"]:
|
| 613 |
user_states[chat_id] = {"mode": "chat", "text": "", "history":[]}
|
| 614 |
-
await send_with_keyboard(client, chat_id, "💬 شما وارد بخش **چت با هوش مصنوعی** شدید.\n(حالا ربات سابقه گفتگو را به یاد میآورد)\n\nهر سوالی دارید بفرستید تا جواب بدم:\n\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
|
| 615 |
return
|
| 616 |
|
| 617 |
if user_text_str in["/image", "🎨 عکس", "ساخت تصاویر با هوش مصنوعی🎨"]:
|
|
@@ -626,7 +647,7 @@ else:
|
|
| 626 |
|
| 627 |
if user_text_str in["/file", "تحلیل فایل با هوش مصنوعی 📁"]:
|
| 628 |
user_states[chat_id] = {"mode": "file_waiting_for_file", "text": "", "history":[], "file_bytes": None, "file_name": None}
|
| 629 |
-
await send_with_keyboard(client, chat_id, "📁 شما وارد بخش **تحلیل فایل** شدید.\n\nلطفاً هر نوع فایلی (عکس، ویدیو، PDF، داکیومنت و...) را که میخواهید بررسی شود ارسال کنید:\n\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
|
| 630 |
return
|
| 631 |
|
| 632 |
if user_text_str in["/stt", "تبدیل فایل صوتی به متن 📝"]:
|
|
@@ -641,9 +662,19 @@ else:
|
|
| 641 |
elif user_text_str: await send_with_keyboard(client, chat_id, "⚠️ لطفاً ابتدا از کیبورد پایین، بخش مورد نظرتان را انتخاب کنید:", True)
|
| 642 |
return
|
| 643 |
|
| 644 |
-
# --- مسیریابی ---
|
| 645 |
elif current_mode == "chat":
|
| 646 |
-
if
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 647 |
return
|
| 648 |
|
| 649 |
elif current_mode == "image_waiting_for_text":
|
|
@@ -685,7 +716,6 @@ else:
|
|
| 685 |
await send_with_keyboard(client, chat_id, "❌ شماره نامعتبر است! لطفاً فقط یک عدد بین 1 تا 30 بفرستید.", False)
|
| 686 |
return
|
| 687 |
|
| 688 |
-
# --- بخش STT (صدا به متن) آپدیت شده ---
|
| 689 |
elif current_mode == "stt_waiting_for_audio":
|
| 690 |
if not is_file:
|
| 691 |
await send_with_keyboard(client, chat_id, "⚠️ لطفاً یک فایل (ویس، آهنگ، ویدیو و...) ارسال کنید.", False)
|
|
@@ -695,14 +725,13 @@ else:
|
|
| 695 |
try:
|
| 696 |
audio_bytes = await helper_download_file(client, msg_obj)
|
| 697 |
user_states[chat_id]["mode"] = "stt_waiting_for_audio"
|
| 698 |
-
# انتقال نام فایل به تابع جیمینای برای تشخیص فرمت ویس
|
| 699 |
asyncio.create_task(process_stt(client, chat_id, audio_bytes, file_name))
|
| 700 |
except Exception as dl_err:
|
| 701 |
err_trace = traceback.format_exc()
|
| 702 |
await send_with_keyboard(client, chat_id, f"❌ خطا در دانلود فایل!\n\n🔴 لاگ برنامهنویس:\n`{err_trace[-300:]}`\n{str(dl_err)}", False)
|
| 703 |
return
|
| 704 |
|
| 705 |
-
# --- بخش تحلیل فایل ---
|
| 706 |
elif current_mode == "file_waiting_for_file":
|
| 707 |
if not is_file:
|
| 708 |
await send_with_keyboard(client, chat_id, "⚠️ لطفاً ابتدا یک فایل (تصویر، ویدیو، PDF و...) ارسال کنید.", False)
|
|
|
|
| 18 |
|
| 19 |
@app.route('/')
|
| 20 |
def home():
|
| 21 |
+
return "ربات یکپارچه آلفا (نسخه پرو + دانلود فایل ۱۰۰٪ تضمینی + چت چندرسانهای) روشن است! 🚀"
|
| 22 |
|
| 23 |
def run_flask():
|
| 24 |
app.run(host="0.0.0.0", port=7860)
|
|
|
|
| 26 |
|
| 27 |
# --- ساختار کیبورد پایین صفحه (Chat Keypad) ---
|
| 28 |
MAIN_KEYPAD_DICT = {
|
| 29 |
+
"rows":[
|
| 30 |
{
|
| 31 |
"buttons":[
|
| 32 |
{"id": "chat_btn", "type": "Simple", "button_text": "چت با هوش مصنوعی 🤖"}
|
|
|
|
| 158 |
abs_path = os.path.abspath(file_name)
|
| 159 |
error_logs =[]
|
| 160 |
|
| 161 |
+
api_file_type = "Image" if file_type in["photo", "Image", "image"] else "Voice" if file_type in["voice", "Voice", "audio"] else "File"
|
| 162 |
|
|
|
|
| 163 |
try:
|
| 164 |
url_request = f"https://botapi.rubika.ir/v3/{bot_token}/requestSendFile"
|
| 165 |
url_send = f"https://botapi.rubika.ir/v3/{bot_token}/sendFile"
|
|
|
|
| 170 |
|
| 171 |
if req_data.get("status") == "OK":
|
| 172 |
data_dict = req_data.get("data", {})
|
|
|
|
| 173 |
upload_url = data_dict.get("upload_url")
|
| 174 |
file_id = data_dict.get("id") or data_dict.get("file_id")
|
| 175 |
|
|
|
|
| 205 |
except Exception as e:
|
| 206 |
error_logs.append(f"Raw HTTP Error: {e}")
|
| 207 |
|
|
|
|
| 208 |
try:
|
| 209 |
if hasattr(client, "send_file"):
|
| 210 |
await client.send_file(chat_id, abs_path)
|
|
|
|
| 217 |
return "\n".join(error_logs)
|
| 218 |
|
| 219 |
|
|
|
|
| 220 |
WORKER_URLS =[
|
| 221 |
"https://hamed744-ttspro.hf.space/generate",
|
| 222 |
"https://hamed744-ttspro2.hf.space/generate",
|
|
|
|
| 245 |
user_states = {}
|
| 246 |
|
| 247 |
|
| 248 |
+
# --- ۱. پردازش چت متنی و چندرسانهای (ارتقا یافته) ---
|
| 249 |
+
async def process_gemini(client, chat_id, prompt, file_bytes=None, file_name=None):
|
| 250 |
if not GEMINI_KEYS:
|
| 251 |
await send_with_keyboard(client, chat_id, "❌ کلیدهای API جیمینای تنظیم نشدهاند.", False)
|
| 252 |
return
|
|
|
|
| 255 |
|
| 256 |
history = user_states[chat_id].get("history",[])
|
| 257 |
|
| 258 |
+
# آمادهسازی بخشهای پیام کاربر (متن + فایل در صورت وجود)
|
| 259 |
+
new_parts =[]
|
| 260 |
+
|
| 261 |
+
if prompt:
|
| 262 |
+
new_parts.append({"text": prompt})
|
| 263 |
+
elif file_bytes:
|
| 264 |
+
new_parts.append({"text": "لطفاً این فایل را به دقت بررسی کن."})
|
| 265 |
+
|
| 266 |
+
if file_bytes and file_name:
|
| 267 |
+
base64_data = base64.b64encode(file_bytes).decode('utf-8')
|
| 268 |
+
mime_type, _ = mimetypes.guess_type(file_name)
|
| 269 |
+
if not mime_type:
|
| 270 |
+
if file_name.endswith(('.jpg', '.jpeg')): mime_type = "image/jpeg"
|
| 271 |
+
elif file_name.endswith('.png'): mime_type = "image/png"
|
| 272 |
+
elif file_name.endswith('.pdf'): mime_type = "application/pdf"
|
| 273 |
+
elif file_name.endswith('.mp4'): mime_type = "video/mp4"
|
| 274 |
+
elif file_name.endswith('.mp3'): mime_type = "audio/mp3"
|
| 275 |
+
elif file_name.endswith(('.ogg', '.oga')): mime_type = "audio/ogg"
|
| 276 |
+
elif file_name.endswith('.wav'): mime_type = "audio/wav"
|
| 277 |
+
else: mime_type = "image/jpeg"
|
| 278 |
+
|
| 279 |
+
new_parts.append({
|
| 280 |
+
"inlineData": {
|
| 281 |
+
"mimeType": mime_type,
|
| 282 |
+
"data": base64_data
|
| 283 |
+
}
|
| 284 |
+
})
|
| 285 |
+
|
| 286 |
+
# افزودن پیام جدید به سابقه
|
| 287 |
if history and history[-1]["role"] == "user":
|
| 288 |
+
# اگر پیام قبلی هم از کاربر بود، پیام جدید (فایل یا متن) را به آن اضافه کن
|
| 289 |
+
history[-1]["parts"].extend(new_parts)
|
| 290 |
else:
|
| 291 |
+
history.append({"role": "user", "parts": new_parts})
|
| 292 |
|
| 293 |
# تغییر تاریخچه به ۴۰ مورد برای ذخیره کردن ۲۰ سوال و جواب (۲۰ پیام رفت و برگشت)
|
| 294 |
if len(history) > 40:
|
|
|
|
| 305 |
url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key={key}"
|
| 306 |
payload = {"contents": history, "generationConfig": {"temperature": 0.7, "maxOutputTokens": 8192}}
|
| 307 |
try:
|
| 308 |
+
async with session.post(url, json=payload, timeout=60) as response:
|
| 309 |
if response.status == 200:
|
| 310 |
data = await response.json()
|
| 311 |
try:
|
|
|
|
| 328 |
if not final_answer:
|
| 329 |
if history and history[-1]["role"] == "user":
|
| 330 |
history.pop()
|
| 331 |
+
await send_with_keyboard(client, chat_id, "❌ متأسفانه پاسخی دریافت نشد. (شاید سایز فایل بیش از حد مجاز بوده است)", False)
|
| 332 |
return
|
| 333 |
|
| 334 |
history.append({"role": "model", "parts":[{"text": final_answer}]})
|
|
|
|
| 404 |
await asyncio.sleep(1)
|
| 405 |
caption_text = "🎨 تصویر شما آماده شد!\n(مدل: Z-Image-Turbo)"
|
| 406 |
|
|
|
|
| 407 |
upload_result = await helper_upload_file(client, chat_id, file_name, "Image", caption_text)
|
| 408 |
|
| 409 |
if upload_result is not True:
|
|
|
|
| 453 |
if isinstance(proc_msg, dict):
|
| 454 |
msg_id = proc_msg.get('message_update', {}).get('message_id') or proc_msg.get('message_id')
|
| 455 |
if msg_id:
|
| 456 |
+
await client.delete_messages(chat_id,[msg_id])
|
| 457 |
except Exception: pass
|
| 458 |
|
| 459 |
if audio_bytes:
|
|
|
|
| 462 |
|
| 463 |
await asyncio.sleep(1)
|
| 464 |
|
|
|
|
| 465 |
upload_result = await helper_upload_file(client, chat_id, file_name, "Voice", "✅ پردازش صدای شما انجام شد.")
|
| 466 |
|
| 467 |
if upload_result is not True:
|
|
|
|
| 483 |
|
| 484 |
proc_msg = await send_with_keyboard(client, chat_id, "📝 در حال گوش دادن و پیادهسازی متن توسط جیمینای... (لطفاً صبور باشید)", False)
|
| 485 |
|
|
|
|
| 486 |
base64_data = base64.b64encode(audio_bytes).decode('utf-8')
|
| 487 |
|
|
|
|
| 488 |
mime_type, _ = mimetypes.guess_type(file_name)
|
| 489 |
if not mime_type:
|
| 490 |
if file_name.endswith(('.ogg', '.oga')): mime_type = "audio/ogg"
|
| 491 |
elif file_name.endswith('.wav'): mime_type = "audio/wav"
|
| 492 |
elif file_name.endswith('.mp3'): mime_type = "audio/mp3"
|
| 493 |
elif file_name.endswith('.mp4'): mime_type = "video/mp4"
|
| 494 |
+
else: mime_type = "audio/ogg"
|
| 495 |
|
| 496 |
keys_to_try = GEMINI_KEYS.copy()
|
| 497 |
random.shuffle(keys_to_try)
|
| 498 |
transcribed_text = None
|
| 499 |
|
|
|
|
| 500 |
prompt = "لطفاً این فایل صوتی/تصویری را با دقت کامل گوش بده و صحبتهای داخل آن را کلمه به کلمه به متن تبدیل کن. هیچ توضیح اضافهای نده و فقط متن پیادهسازی شده را بفرست."
|
| 501 |
|
| 502 |
async with aiohttp.ClientSession() as session:
|
|
|
|
| 531 |
await send_with_keyboard(client, chat_id, f"❌ تبدیل فایل به متن ناموفق بود.\n(احتمالاً فرمت فایل پشتیبانی نمیشود یا فایل شما صوتی نیست)", True)
|
| 532 |
|
| 533 |
|
| 534 |
+
# --- ۵. پردازش تحلیل فایل مستقل ---
|
| 535 |
async def process_file_analysis(client, chat_id, file_bytes, file_name, prompt):
|
| 536 |
if not GEMINI_KEYS:
|
| 537 |
await send_with_keyboard(client, chat_id, "❌ کلیدهای API جیمینای تنظیم نشدهاند.", False)
|
|
|
|
| 547 |
elif file_name.endswith('.pdf'): mime_type = "application/pdf"
|
| 548 |
elif file_name.endswith('.mp4'): mime_type = "video/mp4"
|
| 549 |
elif file_name.endswith('.mp3'): mime_type = "audio/mp3"
|
| 550 |
+
elif file_name.endswith(('.ogg', '.oga')): mime_type = "audio/ogg"
|
| 551 |
elif file_name.endswith('.wav'): mime_type = "audio/wav"
|
| 552 |
else: mime_type = "image/jpeg"
|
| 553 |
|
|
|
|
| 632 |
|
| 633 |
if user_text_str in["/chat", "💬 چت", "چت با هوش مصنوعی 🤖"]:
|
| 634 |
user_states[chat_id] = {"mode": "chat", "text": "", "history":[]}
|
| 635 |
+
await send_with_keyboard(client, chat_id, "💬 شما وارد بخش **چت با هوش مصنوعی** شدید.\n(حالا ربات سابقه گفتگو را به یاد میآورد)\n\nهر سوالی دارید بفرستید تا جواب بدم:\n💡 نکته: در همین بخش هم میتوانید برای من عکس یا فایل ارسال کنید تا آن را بررسی کنم.\n\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
|
| 636 |
return
|
| 637 |
|
| 638 |
if user_text_str in["/image", "🎨 عکس", "ساخت تصاویر با هوش مصنوعی🎨"]:
|
|
|
|
| 647 |
|
| 648 |
if user_text_str in["/file", "تحلیل فایل با هوش مصنوعی 📁"]:
|
| 649 |
user_states[chat_id] = {"mode": "file_waiting_for_file", "text": "", "history":[], "file_bytes": None, "file_name": None}
|
| 650 |
+
await send_with_keyboard(client, chat_id, "📁 شما وارد بخش **تحلیل فایل اختصاصی** شدید.\n\nلطفاً هر نوع فایلی (عکس، ویدیو، PDF، داکیومنت و...) را که میخواهید بررسی شود ارسال کنید:\n\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
|
| 651 |
return
|
| 652 |
|
| 653 |
if user_text_str in["/stt", "تبدیل فایل صوتی به متن 📝"]:
|
|
|
|
| 662 |
elif user_text_str: await send_with_keyboard(client, chat_id, "⚠️ لطفاً ابتدا از کیبورد پایین، بخش مورد نظرتان را انتخاب کنید:", True)
|
| 663 |
return
|
| 664 |
|
| 665 |
+
# --- مسیریابی و هندل کردن حالت چت (ارتقا یافته برای پشتیبانی از ارسال فایل) ---
|
| 666 |
elif current_mode == "chat":
|
| 667 |
+
if is_file:
|
| 668 |
+
await send_with_keyboard(client, chat_id, "📥 در حال دانلود فایل برای چت هوشمند...", False)
|
| 669 |
+
try:
|
| 670 |
+
file_bytes = await helper_download_file(client, msg_obj)
|
| 671 |
+
# اگر کاربر همراه عکس کپشن نوشته باشد ارسال میشود، در غیر اینصورت ربات متوجه میشود فایل فرستاده
|
| 672 |
+
asyncio.create_task(process_gemini(client, chat_id, user_text_str, file_bytes=file_bytes, file_name=file_name))
|
| 673 |
+
except Exception as dl_err:
|
| 674 |
+
err_trace = traceback.format_exc()
|
| 675 |
+
await send_with_keyboard(client, chat_id, f"❌ خطا در دریافت فایل!\n\n🔴 لاگ برنامهنویس:\n`{err_trace[-300:]}`\n{str(dl_err)}", False)
|
| 676 |
+
elif user_text_str:
|
| 677 |
+
asyncio.create_task(process_gemini(client, chat_id, user_text_str))
|
| 678 |
return
|
| 679 |
|
| 680 |
elif current_mode == "image_waiting_for_text":
|
|
|
|
| 716 |
await send_with_keyboard(client, chat_id, "❌ شماره نامعتبر است! لطفاً فقط یک عدد بین 1 تا 30 بفرستید.", False)
|
| 717 |
return
|
| 718 |
|
|
|
|
| 719 |
elif current_mode == "stt_waiting_for_audio":
|
| 720 |
if not is_file:
|
| 721 |
await send_with_keyboard(client, chat_id, "⚠️ لطفاً یک فایل (ویس، آهنگ، ویدیو و...) ارسال کنید.", False)
|
|
|
|
| 725 |
try:
|
| 726 |
audio_bytes = await helper_download_file(client, msg_obj)
|
| 727 |
user_states[chat_id]["mode"] = "stt_waiting_for_audio"
|
|
|
|
| 728 |
asyncio.create_task(process_stt(client, chat_id, audio_bytes, file_name))
|
| 729 |
except Exception as dl_err:
|
| 730 |
err_trace = traceback.format_exc()
|
| 731 |
await send_with_keyboard(client, chat_id, f"❌ خطا در دانلود فایل!\n\n🔴 لاگ برنامهنویس:\n`{err_trace[-300:]}`\n{str(dl_err)}", False)
|
| 732 |
return
|
| 733 |
|
| 734 |
+
# --- بخش تحلیل فایل اختصاصی ---
|
| 735 |
elif current_mode == "file_waiting_for_file":
|
| 736 |
if not is_file:
|
| 737 |
await send_with_keyboard(client, chat_id, "⚠️ لطفاً ابتدا یک فایل (تصویر، ویدیو، PDF و...) ارسال کنید.", False)
|