From 83fcabe36f564d49f3bc9b29920bda1c60accf8f Mon Sep 17 00:00:00 2001 From: lizandrogd <77708265+lizandrogd@users.noreply.github.com> Date: Tue, 13 Jan 2026 00:48:57 -0500 Subject: [PATCH] full --- api/send_media_message.php | 108 +++++++ api/upload_media.php | 136 +++++++++ chat_window.php | 557 ++++++++++++++++++++++++++++++++++- conversations.php | 334 ++++++++++++++++++++- create_media_table.sql | 16 + execute_media_table.php | 62 ++++ services/WhatsAppService.php | 131 ++++++++ verify_media_table.php | 30 ++ 8 files changed, 1370 insertions(+), 4 deletions(-) create mode 100644 api/send_media_message.php create mode 100644 api/upload_media.php create mode 100644 create_media_table.sql create mode 100644 execute_media_table.php create mode 100644 verify_media_table.php diff --git a/api/send_media_message.php b/api/send_media_message.php new file mode 100644 index 0000000..2439c85 --- /dev/null +++ b/api/send_media_message.php @@ -0,0 +1,108 @@ + false, 'error' => 'Método no permitido']); + exit; +} + +try { + $input = json_decode(file_get_contents('php://input'), true); + + if (!$input) { + throw new Exception('Datos no válidos'); + } + + // Validar campos requeridos + if (empty($input['recipient']) || empty($input['media_url']) || empty($input['media_type'])) { + throw new Exception('Faltan campos requeridos: recipient, media_url, media_type'); + } + + $recipient = $input['recipient']; + $mediaUrl = $input['media_url']; + $mediaType = $input['media_type']; // image, video, audio, document + $caption = $input['caption'] ?? null; + $filename = $input['filename'] ?? null; + + // Inicializar servicio de WhatsApp + $whatsapp = new WhatsAppService(); + + // Enviar según tipo de media + $response = null; + + switch ($mediaType) { + case 'image': + $response = $whatsapp->sendImageMessage($recipient, $mediaUrl, $caption); + break; + + case 'video': + $response = $whatsapp->sendVideoMessage($recipient, $mediaUrl, $caption); + break; + + case 'audio': + $response = $whatsapp->sendAudioMessage($recipient, $mediaUrl); + break; + + case 'document': + $response = $whatsapp->sendDocumentMessage($recipient, $mediaUrl, $filename, $caption); + break; + + default: + throw new Exception('Tipo de media no soportado: ' . $mediaType); + } + + if ($response && isset($response['messages'][0]['id'])) { + // Guardar en base de datos + $db = Database::getInstance(); + + // Obtener usuario + $user = $db->fetch( + "SELECT id FROM users WHERE phone_number = ?", + [$recipient] + ); + + if ($user) { + $db->insert('conversations', [ + 'user_id' => $user['id'], + 'message_id' => $response['messages'][0]['id'], + 'direction' => 'outgoing', + 'message_type' => $mediaType, + 'content' => $caption ?? $filename ?? '', + 'media_url' => $mediaUrl, + 'status' => 'sent', + 'created_at' => date('Y-m-d H:i:s') + ]); + } + + echo json_encode([ + 'success' => true, + 'message' => 'Mensaje multimedia enviado correctamente', + 'data' => $response + ]); + } else { + throw new Exception('Error al enviar mensaje: ' . json_encode($response)); + } + +} catch (Exception $e) { + error_log("Error en send_media_message.php: " . $e->getMessage()); + http_response_code(500); + echo json_encode([ + 'success' => false, + 'error' => $e->getMessage() + ]); +} +?> diff --git a/api/upload_media.php b/api/upload_media.php new file mode 100644 index 0000000..512b87f --- /dev/null +++ b/api/upload_media.php @@ -0,0 +1,136 @@ + false, 'error' => 'Método no permitido']); + exit; +} + +try { + // Verificar que se subió un archivo + if (!isset($_FILES['file']) || $_FILES['file']['error'] !== UPLOAD_ERR_OK) { + throw new Exception('No se recibió ningún archivo o hubo un error en la carga'); + } + + $file = $_FILES['file']; + $fileSize = $file['size']; + $fileName = basename($file['name']); + $fileTmpPath = $file['tmp_name']; + $fileType = $file['type']; + + // Validar tamaño según tipo + $maxSize = 16 * 1024 * 1024; // 16MB por defecto + + if (strpos($fileType, 'image/') === 0) { + $maxSize = 5 * 1024 * 1024; // 5MB para imágenes + } elseif (strpos($fileType, 'application/') === 0) { + $maxSize = 100 * 1024 * 1024; // 100MB para documentos + } + + if ($fileSize > $maxSize) { + throw new Exception('El archivo es demasiado grande. Máximo: ' . ($maxSize / 1024 / 1024) . 'MB'); + } + + // Validar tipos de archivo permitidos + $allowedTypes = [ + // Imágenes + 'image/jpeg', 'image/jpg', 'image/png', 'image/webp', + // Videos + 'video/mp4', 'video/3gpp', 'video/quicktime', + // Audios + 'audio/aac', 'audio/mp3', 'audio/mpeg', 'audio/ogg', 'audio/amr', 'audio/webm', + // Documentos + 'application/pdf', + 'application/msword', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'application/vnd.ms-excel', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'application/vnd.ms-powerpoint', + 'application/vnd.openxmlformats-officedocument.presentationml.presentation' + ]; + + if (!in_array($fileType, $allowedTypes)) { + throw new Exception('Tipo de archivo no permitido: ' . $fileType); + } + + // Crear directorio de uploads si no existe + $uploadDir = __DIR__ . '/../uploads/'; + if (!is_dir($uploadDir)) { + mkdir($uploadDir, 0755, true); + } + + // Generar nombre único + $extension = pathinfo($fileName, PATHINFO_EXTENSION); + $uniqueName = uniqid('media_', true) . '.' . $extension; + $uploadPath = $uploadDir . $uniqueName; + + // Mover archivo + if (!move_uploaded_file($fileTmpPath, $uploadPath)) { + throw new Exception('Error al guardar el archivo en el servidor'); + } + + // Construir URL pública + $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http'; + $host = $_SERVER['HTTP_HOST']; + $publicUrl = $protocol . '://' . $host . '/whatsapp/uploads/' . $uniqueName; + + // Determinar tipo de medio + $mediaType = 'document'; + if (strpos($fileType, 'image/') === 0) { + $mediaType = 'image'; + } elseif (strpos($fileType, 'video/') === 0) { + $mediaType = 'video'; + } elseif (strpos($fileType, 'audio/') === 0) { + $mediaType = 'audio'; + } + + // Guardar información en base de datos (opcional) + $db = Database::getInstance(); + $mediaId = $db->insert('media_files', [ + 'filename' => $fileName, + 'unique_name' => $uniqueName, + 'file_type' => $fileType, + 'file_size' => $fileSize, + 'media_type' => $mediaType, + 'file_path' => $uploadPath, + 'public_url' => $publicUrl, + 'uploaded_by' => $_SESSION['user']['id'] ?? null, + 'created_at' => date('Y-m-d H:i:s') + ]); + + echo json_encode([ + 'success' => true, + 'message' => 'Archivo subido correctamente', + 'data' => [ + 'id' => $mediaId, + 'filename' => $fileName, + 'url' => $publicUrl, + 'type' => $mediaType, + 'mime_type' => $fileType, + 'size' => $fileSize + ] + ]); + +} catch (Exception $e) { + error_log("Error en upload_media.php: " . $e->getMessage()); + http_response_code(500); + echo json_encode([ + 'success' => false, + 'error' => $e->getMessage() + ]); +} +?> diff --git a/chat_window.php b/chat_window.php index 846ee7b..08ba0c9 100644 --- a/chat_window.php +++ b/chat_window.php @@ -145,6 +145,151 @@ if (empty($user_id)) { font-size: 0.8rem; opacity: 0.8; } + + /* Estilos para multimedia */ + .attach-btn { + background: transparent; + border: none; + color: #666; + padding: 12px 15px; + cursor: pointer; + font-size: 1.2rem; + } + + .attach-btn:hover { + color: #25D366; + } + + .media-preview { + padding: 10px; + background: #f0f0f0; + border-radius: 8px; + margin-bottom: 10px; + display: none; + } + + .media-preview.show { + display: block; + animation: slideDown 0.3s ease-out; + } + + @keyframes slideDown { + from { + opacity: 0; + transform: translateY(-10px); + } + to { + opacity: 1; + transform: translateY(0); + } + } + + .media-preview-content { + display: flex; + align-items: center; + gap: 10px; + } + + .media-thumbnail { + width: 60px; + height: 60px; + object-fit: cover; + border-radius: 5px; + } + + .media-info { + flex: 1; + } + + .media-filename { + font-weight: 500; + font-size: 0.9rem; + color: #333; + } + + .media-filesize { + font-size: 0.8rem; + color: #666; + } + + .message-media { + margin-top: 8px; + } + + .message-media img, + .message-media video { + max-width: 100%; + border-radius: 8px; + margin-top: 5px; + } + + .message-media audio { + width: 100%; + margin-top: 5px; + } + + .message-document { + display: flex; + align-items: center; + gap: 10px; + padding: 10px; + background: #f0f0f0; + border-radius: 8px; + margin-top: 5px; + text-decoration: none; + color: inherit; + } + + .message-document:hover { + background: #e0e0e0; + } + + .message-document i { + font-size: 1.5rem; + color: #666; + } + + .mic-btn { + background: transparent; + border: none; + color: #666; + padding: 12px 15px; + cursor: pointer; + font-size: 1.2rem; + } + + .mic-btn:hover { + color: #25D366; + } + + .mic-btn.recording { + color: #dc3545; + animation: pulse 1s infinite; + } + + @keyframes pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.5; } + } + + .recording-indicator { + display: none; + padding: 10px; + background: #fff3cd; + border-radius: 8px; + margin-bottom: 10px; + align-items: center; + gap: 10px; + } + + .recording-indicator.show { + display: flex; + } + + .recording-time { + font-weight: 500; + color: #dc3545; + }
@@ -206,7 +351,44 @@ if (empty($user_id)) { + +