diff --git a/botdiscord/ui.py b/botdiscord/ui.py index e39f28c..3c4f382 100644 --- a/botdiscord/ui.py +++ b/botdiscord/ui.py @@ -24,48 +24,54 @@ class TranslationButton(discord.ui.Button): self.lang_code = lang_code async def callback(self, interaction: discord.Interaction): - # Para botones persistentes, recuperamos la info del mensaje original - # En el caso de reply, interaction.message.reference.message_id es el original - if not interaction.message.reference: - await interaction.response.send_message("⚠️ No se pudo encontrar el mensaje original.", ephemeral=True) - return + # 1. Avisamos a Discord que estamos procesando (evita el "Interacción fallida" por timeout) + await interaction.response.defer() + + try: + if not interaction.message.reference: + await interaction.followup.send("⚠️ No se pudo encontrar la referencia al mensaje original.", ephemeral=True) + return + + original_msg_id = interaction.message.reference.message_id + db_msg = get_message(original_msg_id) - original_msg_id = interaction.message.reference.message_id - db_msg = get_message(original_msg_id) - - if not db_msg: - await interaction.response.send_message("⚠️ El mensaje original no está en la base de datos (pudo ser borrado o es muy antiguo).", ephemeral=True) - return + if not db_msg: + # Si no está en MySQL, intentamos ver si el mensaje actual tiene el texto (fallback) + await interaction.followup.send("⚠️ Mensaje no encontrado en la base de datos.", ephemeral=True) + return - text = db_msg['content'] - mentions_map = db_msg['mentions_map'] - - # Verificamos caché - cached = get_cached_translation(original_msg_id, self.lang_code) - if cached: - translated = cached - else: - # Traducimos - translated = await translate_text(text, self.lang_code) - save_translation(original_msg_id, self.lang_code, translated) - - # Procesar traducción (HTML unescape y menciones) - import html - import re - translated = html.unescape(translated) - - for placeholder, mention in mentions_map.items(): - match = re.search(r'm\d+', placeholder) - if not match: continue - tag_num = match.group() - open_pattern = re.compile(rf'<\s*{tag_num}\s*/?\s*>') - translated = open_pattern.sub(mention, translated) - close_pattern = re.compile(rf'<\s*/\s*{tag_num}\s*>') - translated = close_pattern.sub('', translated) - - # Si el mensaje original tenía archivos, intentamos mantener la coherencia - # Aunque al ser persistente, simplemente editamos el mensaje de la respuesta - await interaction.response.edit_message(content=translated, view=self.view) + text = db_msg['content'] + mentions_map = db_msg['mentions_map'] + + # Verificamos caché + cached = get_cached_translation(original_msg_id, self.lang_code) + if cached: + translated = cached + else: + translated = await translate_text(text, self.lang_code) + save_translation(original_msg_id, self.lang_code, translated) + + # Procesar traducción + import html + import re + translated = html.unescape(translated) + + if mentions_map: + for placeholder, mention in mentions_map.items(): + match = re.search(r'm\d+', placeholder) + if not match: continue + tag_num = match.group() + open_pattern = re.compile(rf'<\s*{tag_num}\s*/?\s*>') + translated = open_pattern.sub(mention, translated) + close_pattern = re.compile(rf'<\s*/\s*{tag_num}\s*>') + translated = close_pattern.sub('', translated) + + # 2. Usamos edit_original_response porque ya hicimos defer() + await interaction.edit_original_response(content=translated, view=self.view) + + except Exception as e: + print(f"[ERROR UI] Error en callback de traducción: {e}") + await interaction.followup.send(f"❌ Error al traducir: {str(e)}", ephemeral=True) class ConfigSelect(discord.ui.Select): def __init__(self, guild_id: int, bot_type: str = "discord"):