From 7af0e95e0ba0edf954b4d37403340c9df0c88c11 Mon Sep 17 00:00:00 2001 From: nickpons666 Date: Sat, 7 Feb 2026 20:03:56 -0600 Subject: [PATCH] =?UTF-8?q?Mejora=20traducci=C3=B3n=20bot=20Discord:=20det?= =?UTF-8?q?ecci=C3=B3n=20de=20im=C3=A1genes/videos=20y=20preservaci=C3=B3n?= =?UTF-8?q?=20de=20emojis?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Evita mostrar botones de traducción en mensajes con solo imágenes/videos - Detecta y traduce captions de imágenes/videos - Preserva emojis, menciones y elementos de Discord durante traducción - Soluciona problema de placeholders en emojis Unicode estándar --- discord_bot.php | 107 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 99 insertions(+), 8 deletions(-) diff --git a/discord_bot.php b/discord_bot.php index 8bd3043..a3da799 100755 --- a/discord_bot.php +++ b/discord_bot.php @@ -104,8 +104,10 @@ try { return; } + // Extraer y preservar emojis, stickers y elementos de Discord + $processedContent = preserveDiscordElements($originalContent); $translator = new Translate(LIBRETRANSLATE_URL); - $sourceLang = $translator->detectLanguage($originalContent) ?? 'es'; + $sourceLang = $translator->detectLanguage($processedContent['text']) ?? 'es'; if ($sourceLang === $targetLang) { $interaction->respondWithMessage( @@ -115,7 +117,10 @@ try { return; } - $translatedText = $translator->translateText($originalContent, $sourceLang, $targetLang); + $translatedText = $translator->translateText($processedContent['text'], $sourceLang, $targetLang); + + // Restaurar emojis y elementos de Discord + $finalText = restoreDiscordElements($translatedText, $processedContent['placeholders']); // Obtener bandera $stmt = $pdo->prepare("SELECT flag_emoji FROM supported_languages WHERE language_code = ? AND is_active = 1"); @@ -125,7 +130,7 @@ try { $flag = $flag !== '' ? $flag : '🏳️'; // Responder efímeramente con la traducción - $response = "{$flag} **Traducción ({$sourceLang} → {$targetLang}):**\n\n" . $translatedText; + $response = "{$flag} **Traducción ({$sourceLang} → {$targetLang}):**\n\n" . $finalText; $interaction->respondWithMessage( MessageBuilder::new()->setContent($response), true // Efímero - solo visible para el usuario @@ -154,8 +159,10 @@ try { return; } + // Extraer y preservar emojis, stickers y elementos de Discord + $processedContent = preserveDiscordElements($originalContent); $translator = new Translate(LIBRETRANSLATE_URL); - $sourceLang = $translator->detectLanguage($originalContent) ?? 'es'; + $sourceLang = $translator->detectLanguage($processedContent['text']) ?? 'es'; if ($sourceLang === $targetLang) { $interaction->respondWithMessage( @@ -165,7 +172,10 @@ try { return; } - $translatedText = $translator->translateText($originalContent, $sourceLang, $targetLang); + $translatedText = $translator->translateText($processedContent['text'], $sourceLang, $targetLang); + + // Restaurar emojis y elementos de Discord + $finalText = restoreDiscordElements($translatedText, $processedContent['placeholders']); // Obtener bandera $stmt = $pdo->prepare("SELECT flag_emoji FROM supported_languages WHERE language_code = ? AND is_active = 1"); @@ -175,7 +185,7 @@ try { $flag = $flag !== '' ? $flag : '🏳️'; // Responder efímeramente con la traducción - $response = "{$flag} **Traducción ({$sourceLang} → {$targetLang}):**\n\n" . $translatedText; + $response = "{$flag} **Traducción ({$sourceLang} → {$targetLang}):**\n\n" . $finalText; $interaction->respondWithMessage( MessageBuilder::new()->setContent($response), true // Efímero - solo visible para el usuario @@ -550,8 +560,39 @@ function handleDiscordTranslation(Message $message, PDO $pdo, Logger $logger) { try { $text = $message->content; + $attachments = $message->attachments; + + // Verificar si el mensaje tiene contenido de texto + $hasTextContent = !empty(trim($text)); + + // Verificar si hay texto en los attachments (captions de imágenes/videos) + $attachmentText = ''; + if (!empty($attachments)) { + foreach ($attachments as $attachment) { + // Algunos attachments tienen propiedad 'description' o 'caption' + if (!empty($attachment->description)) { + $attachmentText .= $attachment->description . ' '; + } + if (!empty($attachment->caption)) { + $attachmentText .= $attachment->caption . ' '; + } + } + } + + // Combinar texto principal con texto de attachments + $fullText = trim($text . ' ' . $attachmentText); + $hasAnyText = !empty($fullText); + + // Verificar si el mensaje tiene solo imágenes/adjuntos sin texto + $hasOnlyAttachments = !$hasAnyText && !empty($attachments) && count($attachments) > 0; + + // Si el mensaje no tiene texto o tiene solo imágenes, no mostrar botones de traducción + if (!$hasAnyText || $hasOnlyAttachments) { + $logger->info("[TRADUCCIÓN] Mensaje #{$message->id} no tiene contenido de texto, omitiendo botones de traducción."); + return; + } $translator = new Translate(LIBRETRANSLATE_URL); - $detectedLang = $translator->detectLanguage(strip_tags($text)) ?? 'es'; + $detectedLang = $translator->detectLanguage(strip_tags($fullText)) ?? 'es'; // Obtener idiomas activos disponibles $langStmt = $pdo->query("SELECT language_code, language_name, flag_emoji FROM supported_languages WHERE is_active = 1"); @@ -596,7 +637,7 @@ function handleDiscordTranslation(Message $message, PDO $pdo, Logger $logger) // Enviar mensaje con botones efímeros $builder = MessageBuilder::new() - ->setContent("🌍 **Selecciona idioma para traducir:**") +// ->setContent("🌍 **Selecciona idioma para traducir:**") ->setComponents($components); $message->reply($builder, true); // true = ephemeral (solo visible para el usuario) @@ -607,3 +648,53 @@ function handleDiscordTranslation(Message $message, PDO $pdo, Logger $logger) $logger->error("[Error Traducción Discord]", ['error' => $e->getMessage(), 'trace' => $e->getTraceAsString()]); } } + +/** + * Función para preservar emojis, stickers y elementos de Discord durante la traducción + */ +function preserveDiscordElements($text) { + $placeholders = []; + $processedText = $text; + + // Patrones para detectar elementos de Discord (excluyendo emojis Unicode) + $patterns = [ + // Emojis personalizados de Discord <:name:id> + '//', + // Menciones de usuarios <@id> y <@!id> + '/<@!?(\d+)>/', + // Menciones de canales <#id> + '/<#(\d+)>/', + // Menciones de roles <@&id> + '/<@&(\d+)>/', + // Stickers y GIFs animados (pueden venir como URLs especiales) + '/https?:\/\/(?:media|cdn)\.discordapp\.(?:com|net)\/(stickers|attachments)\/\S+/i' + ]; + + $index = 0; + foreach ($patterns as $pattern) { + $processedText = preg_replace_callback($pattern, function($matches) use (&$placeholders, &$index) { + $placeholder = "DISCORD_ELEMENT_{$index}"; + $placeholders[$placeholder] = $matches[0]; + $index++; + return $placeholder; + }, $processedText); + } + + return [ + 'text' => $processedText, + 'placeholders' => $placeholders + ]; +} + +/** + * Función para restaurar emojis, stickers y elementos de Discord después de la traducción + */ +function restoreDiscordElements($translatedText, $placeholders) { + $restoredText = $translatedText; + + foreach ($placeholders as $placeholder => $originalElement) { + $restoredText = str_replace($placeholder, $originalElement, $restoredText); + } + + return $restoredText; +}