diff --git a/pxy_bots/views.py b/pxy_bots/views.py index e9a1d72..7574735 100644 --- a/pxy_bots/views.py +++ b/pxy_bots/views.py @@ -95,20 +95,21 @@ async def dispatch_private_commands(update, text): # ------------------------------- async def transcribe_with_whisper(update, bot): - # 1. Descarga el archivo de voz desde Telegram - tg_file = await sync_to_async(bot.get_file)(update.message.voice.file_id) + # 1. Descarga el archivo de voz directamente + tg_file = await bot.get_file(update.message.voice.file_id) download_path = f"/tmp/{update.message.voice.file_id}.ogg" - await sync_to_async(tg_file.download)(download_path) + # Con python-telegram-bot async: usa download_to_drive + await tg_file.download_to_drive(download_path) - # 2. Envía el audio a la API Whisper de OpenAI + # 2. Llama al endpoint de transcripción with open(download_path, "rb") as audio: - transcription = openai.audio.transcriptions.create( - model="gpt-4o-transcribe", + resp = openai.audio.transcriptions.create( + model="gpt-4o-transcribe", # o "whisper-1" si prefieres file=audio, response_format="text", language="es" ) - return transcription.text.strip() + return resp.text.strip() # ------------------------------- @@ -120,13 +121,12 @@ async def telegram_webhook(request, bot_name): try: logger.info(f"Webhook called for bot: {bot_name}") - # Carga la configuración del bot + # Carga configuración del bot (sync ORM) try: bot_instance = await sync_to_async(TelegramBot.objects.get)( name=bot_name, is_active=True ) except TelegramBot.DoesNotExist: - logger.error(f"Bot '{bot_name}' not found or inactive.") return JsonResponse({"error": f"Bot '{bot_name}' not found."}, status=400) if not bot_instance.assistant: @@ -135,13 +135,9 @@ async def telegram_webhook(request, bot_name): if request.method != "POST": return JsonResponse({"error": "Invalid request method"}, status=400) - # Decodifica el payload de Telegram - try: - payload = json.loads(request.body.decode("utf-8")) - update = Update.de_json(payload, Bot(token=bot_instance.token)) - except json.JSONDecodeError as e: - logger.error(f"Failed to decode JSON: {e}") - return JsonResponse({"error": "Invalid JSON payload"}, status=400) + # Parsea el update de Telegram + payload = json.loads(request.body.decode("utf-8")) + update = Update.de_json(payload, Bot(token=bot_instance.token)) if not update.message: return JsonResponse({"status": "no message"}) @@ -150,7 +146,7 @@ async def telegram_webhook(request, bot_name): if await handle_location_message(update): return JsonResponse({"status": "ok"}) - # 2) Voz: transcribir y llamar a report_trash + # 2) Voz: transcribir con Whisper y llamar a report_trash if update.message.voice: bot = Bot(token=bot_instance.token) transcript = await transcribe_with_whisper(update, bot) @@ -159,12 +155,12 @@ async def telegram_webhook(request, bot_name): "No pude entender tu mensaje de voz. Intenta de nuevo." ) return JsonResponse({"status": "ok"}) - # Monkey-patch para que report_trash lea el texto + # Patch interno para que report_trash use este texto setattr(update.message, "_text", transcript) await report_trash(update) return JsonResponse({"status": "ok"}) - # 3) Comandos de texto por bot + # 3) Comandos de texto text = update.message.text or "" if bot_name == "PepeBasuritaCoinsBot" and await dispatch_citizen_commands(update, text): return JsonResponse({"status": "ok"}) @@ -173,7 +169,7 @@ async def telegram_webhook(request, bot_name): if bot_name == "PepeMotitoBot" and await dispatch_private_commands(update, text): return JsonResponse({"status": "ok"}) - # 4) Fallback a LLM + # 4) Fallback LLM assistant_instance = await sync_to_async(LangchainAIService)(bot_instance.assistant) bot_response = await sync_to_async(assistant_instance.generate_response)(text) await update.message.reply_text(bot_response)