'Método no permitido. Use POST.', 'method_received' => $_SERVER['REQUEST_METHOD']]); exit; } try { $rawInput = file_get_contents('php://input'); $input = json_decode($rawInput, true); // Debug logging if ($debugMode) { error_log("=== SEND MESSAGE DEBUG ==="); error_log("Method: " . $_SERVER['REQUEST_METHOD']); error_log("Content-Type: " . ($_SERVER['CONTENT_TYPE'] ?? 'not set')); error_log("Raw input: " . $rawInput); error_log("Parsed JSON: " . json_encode($input)); error_log("========================"); } if (!$input) { http_response_code(400); echo json_encode(['error' => 'JSON inválido o vacío', 'raw_input' => $rawInput]); exit; } $db = Database::getInstance(); // Modo debug: simular envío exitoso if ($debugMode) { $recipient = $input['recipient'] ?? $input['user_id'] ?? 'unknown'; $message = $input['message'] ?? 'mensaje de prueba'; $type = $input['type'] ?? 'text'; $template = $input['template'] ?? $input['template_name'] ?? null; $responseData = [ 'recipient' => $recipient, 'type' => $type, 'timestamp' => date('Y-m-d H:i:s'), 'warning' => 'Para envío real, verifica que el usuario haya respondido en las últimas 24h o usa plantillas' ]; if ($type === 'template') { // Detectar formato de plantilla if (isset($input['template']) && is_array($input['template'])) { // Formato WhatsApp estándar $templateData = $input['template']; $responseData['template_name'] = $templateData['name'] ?? 'unknown'; $responseData['language'] = $templateData['language']['code'] ?? 'es'; $responseData['format'] = 'whatsapp_standard'; $message = "Plantilla WhatsApp: {$templateData['name']}"; } else { // Formato simple $template = $input['template'] ?? $input['template_name'] ?? null; $responseData['template_name'] = $template; $responseData['language'] = $input['language'] ?? 'es'; $responseData['format'] = 'simple'; $message = "Plantilla: {$template}"; } } else { $responseData['message'] = $message; } echo json_encode([ 'success' => true, 'message' => 'Mensaje simulado enviado correctamente (modo debug) - NOTA: En producción, usa plantillas para números que no han respondido en 24h', 'data' => $responseData ]); exit; } // Modo 1: Envío directo a número de teléfono (formato original) if (isset($input['recipient'])) { $recipient = $input['recipient']; $type = $input['type'] ?? 'text'; // Verificar si es mensaje de texto y si el usuario respondió en las últimas 24h if ($type === 'text') { // Permitir número específico que sí ha respondido if ($recipient === '573168950803') { // Este número específico tiene permitido envío de texto libre error_log("NÚMERO AUTORIZADO: 573168950803 - Permitiendo envío de texto libre"); } else { // Primero obtener el user_id del teléfono $userStmt = $db->query( "SELECT id FROM users WHERE phone_number = ? LIMIT 1", [$recipient] ); $user = $userStmt->fetch(); if ($user) { $stmt = $db->query( "SELECT MAX(created_at) as last_message FROM conversations WHERE user_id = ? AND direction = 'incoming' AND created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)", [$user['id']] ); $lastMessage = $stmt->fetch(); if (!$lastMessage || !$lastMessage['last_message']) { echo json_encode([ 'success' => false, 'error' => 'No se puede enviar mensaje de texto libre. El usuario no ha respondido en las últimas 24 horas.', 'suggestion' => 'Usa una plantilla pre-aprobada o espera a que el usuario te escriba.', 'error_code' => 'OUTSIDE_24H_WINDOW' ]); exit; } } // Si no existe el usuario, permitir envío (se creará automáticamente) } } $whatsappService = new WhatsAppService(); $response = null; switch ($type) { case 'text': if (!isset($input['message']) || empty($input['message'])) { http_response_code(400); echo json_encode(['error' => 'Mensaje requerido']); exit; } // DEBUG: Mostrar datos de envío de mensaje de texto error_log("=== DEBUG WHATSAPP TEXT MESSAGE ==="); error_log("Recipient: " . $recipient); error_log("Message: " . $input['message']); error_log("Method: sendTextMessage()"); error_log("===================================="); $response = $whatsappService->sendTextMessage($recipient, $input['message']); break; case 'template': // Formato 1: Simple (actual) if (isset($input['template_name']) || (isset($input['template']) && !is_array($input['template']))) { $template = $input['template'] ?? $input['template_name'] ?? ''; if (empty($template)) { http_response_code(400); echo json_encode(['error' => 'Template requerido']); exit; } $language = $input['language'] ?? 'es'; $parameters = $input['parameters'] ?? []; // Verificar plantilla en base de datos (opcional) $templateRecord = null; try { $stmt = $db->query( "SELECT * FROM message_templates WHERE template_name = ? LIMIT 1", [$template] ); $templateRecord = $stmt->fetch(); } catch (Exception $e) { // Si no existe la tabla, continuar sin validación local error_log("Template validation skipped: " . $e->getMessage()); } // Solo validar si la tabla existe y encontramos registros if ($templateRecord && $templateRecord['status'] !== 'approved') { echo json_encode([ 'success' => false, 'error' => 'Plantilla no aprobada en el sistema local', 'template_name' => $template, 'template_status' => $templateRecord['status'], 'suggestions' => [ '1. Aprueba la plantilla desde la pestaña Plantillas', '2. O verifica que esté aprobada en WhatsApp Business Manager', '3. Usa el nombre exacto de la plantilla' ] ]); exit; } // Usar el idioma de la base de datos si no se especifica if ($language === 'es' && $templateRecord['language_code']) { $language = $templateRecord['language_code']; } // DEBUG: Mostrar datos de envío de plantilla formato simple error_log("=== DEBUG WHATSAPP TEMPLATE MESSAGE (SIMPLE FORMAT) ==="); error_log("Recipient: " . $recipient); error_log("Template Name: " . $template); error_log("Language: " . $language); error_log("Parameters: " . json_encode($parameters)); error_log("Template Record Status: " . ($templateRecord ? $templateRecord['status'] : 'not found in DB')); error_log("Method: sendTemplateMessage()"); error_log("========================================================"); $response = $whatsappService->sendTemplateMessage($recipient, $template, $language, $parameters); } // Formato 2: WhatsApp Business API estándar elseif (isset($input['template']) && is_array($input['template'])) { $templateData = $input['template']; $templateName = $templateData['name'] ?? ''; $languageCode = $templateData['language']['code'] ?? 'es'; $components = $templateData['components'] ?? []; if (empty($templateName)) { http_response_code(400); echo json_encode(['error' => 'Template name requerido en formato WhatsApp']); exit; } // Convertir formato WhatsApp a nuestro servicio $parameters = []; foreach ($components as $component) { if ($component['type'] === 'body' && isset($component['parameters'])) { foreach ($component['parameters'] as $param) { $parameters[] = $param['text'] ?? ''; } } } // DEBUG: Mostrar datos de envío de plantilla formato WhatsApp estándar error_log("=== DEBUG WHATSAPP TEMPLATE MESSAGE (WHATSAPP STANDARD FORMAT) ==="); error_log("Recipient: " . $recipient); error_log("Template Name: " . $templateName); error_log("Language Code: " . $languageCode); error_log("Original Components: " . json_encode($components)); error_log("Converted Parameters: " . json_encode($parameters)); error_log("Full Template Data: " . json_encode($templateData)); error_log("Method: sendTemplateMessage()"); error_log("================================================================="); $response = $whatsappService->sendTemplateMessage($recipient, $templateName, $languageCode, $parameters); } else { http_response_code(400); echo json_encode(['error' => 'Template requerido (formato simple o WhatsApp estándar)']); exit; } break; default: http_response_code(400); echo json_encode(['error' => 'Tipo de mensaje no soportado']); exit; } if ($response) { // DEBUG: Mostrar respuesta exitosa de WhatsApp error_log("=== DEBUG WHATSAPP SUCCESS RESPONSE ==="); error_log("Response: " . json_encode($response)); error_log("======================================"); // Guardar mensaje en la base de datos try { // Buscar o crear usuario por teléfono $stmt = $db->query( "SELECT id FROM users WHERE phone_number = ? LIMIT 1", [$recipient] ); $user = $stmt->fetch(); $userId = null; if ($user) { $userId = $user['id']; } else { // Crear nuevo usuario $stmt = $db->query( "INSERT INTO users (phone_number, name, created_at) VALUES (?, ?, NOW())", [$recipient, $recipient] ); $userId = $stmt ? $db->lastInsertId() : null; } if ($userId) { // Preparar datos del mensaje $messageContent = ''; $messageType = $type; if ($type === 'text') { $messageContent = $input['message']; } elseif ($type === 'template') { $templateName = $input['template'] ?? $input['template_name'] ?? ''; $messageContent = "Plantilla: {$templateName}"; } // Guardar en la tabla conversations $stmt = $db->query( "INSERT INTO conversations (user_id, content, direction, message_type, status, message_id, created_at) VALUES (?, ?, 'outgoing', ?, 'sent', ?, NOW())", [$userId, $messageContent, $messageType, $response['messages'][0]['id'] ?? null] ); error_log("Mensaje guardado en BD - User ID: $userId, Content: $messageContent"); } else { error_log("Error: No se pudo obtener o crear user_id para recipient: $recipient"); } } catch (Exception $e) { error_log("Error detallado guardando mensaje en base de datos: " . $e->getMessage()); error_log("Stack trace: " . $e->getTraceAsString()); } echo json_encode([ 'success' => true, 'message' => 'Mensaje enviado correctamente', 'whatsapp_response' => $response ]); } else { // DEBUG: Mostrar error de respuesta de WhatsApp error_log("=== DEBUG WHATSAPP ERROR RESPONSE ==="); error_log("Response was NULL or FALSE"); error_log("Type: " . $type); error_log("===================================="); // Error específico para plantillas con soluciones detalladas if ($type === 'template') { $templateName = $input['template_name'] ?? $input['template'] ?? 'unknown'; $language = $input['language'] ?? 'es'; echo json_encode([ 'success' => false, 'error' => 'Error #132001: Template name does not exist in the translation', 'template_name' => $templateName, 'language' => $language, 'error_analysis' => [ 'El error #132001 indica que WhatsApp no encuentra la plantilla', 'Esto puede suceder por varias razones:' ], 'solutions' => [ '1. CREAR PLANTILLA: Ve a WhatsApp Business Manager → Account Tools → Message Templates', '2. APROBAR PLANTILLA: Asegúrate que Meta haya aprobado tu plantilla', '3. NOMBRE EXACTO: Usa el nombre exacto (case-sensitive)', '4. IDIOMA CORRECTO: Usa el código exacto (en_US, es_ES, etc.)', '5. TIEMPO DE PROPAGACIÓN: Espera 15-30 min después de la aprobación' ], 'debug_info' => [ 'template_attempted' => $templateName, 'language_attempted' => $language, 'common_templates' => ['hello_world', 'sample_shipping_confirmation'], 'common_languages' => ['en_US', 'es_ES', 'es_MX'] ], 'next_steps' => [ '1. Verifica en WhatsApp Business Manager si la plantilla existe', '2. Crea una plantilla simple primero (ej: "hello_world")', '3. Usa el modo debug para probar sin envío real' ] ]); } else { http_response_code(500); echo json_encode(['error' => 'Error enviando mensaje']); } } // Modo 2: Envío a usuario existente (nuevo formato para conversaciones) } elseif (isset($input['user_id']) && isset($input['message'])) { $userId = intval($input['user_id']); $message = trim($input['message']); if (!$userId || !$message) { http_response_code(400); echo json_encode(['error' => 'user_id y message son requeridos']); exit; } // Obtener información del usuario $stmt = $db->query( "SELECT phone_number, name FROM users WHERE id = ?", [$userId] ); $user = $stmt->fetch(); if (!$user) { http_response_code(404); echo json_encode(['error' => 'Usuario no encontrado']); exit; } // Enviar mensaje via WhatsApp API $whatsappService = new WhatsAppService(); // DEBUG: Mostrar datos de envío a usuario existente error_log("=== DEBUG WHATSAPP MESSAGE TO EXISTING USER ==="); error_log("User ID: " . $userId); error_log("User Name: " . ($user['name'] ?? 'N/A')); error_log("Phone Number: " . $user['phone_number']); error_log("Message: " . $message); error_log("Method: sendTextMessage()"); error_log("==============================================="); $response = $whatsappService->sendTextMessage($user['phone_number'], $message); if ($response && isset($response['messages']) && !empty($response['messages'])) { // Guardar mensaje en la base de datos $messageData = [ 'user_id' => $userId, 'content' => $message, 'direction' => 'outgoing', 'message_type' => 'text', 'status' => 'sent', 'message_id' => $response['messages'][0]['id'] ?? null, 'created_at' => date('Y-m-d H:i:s') ]; // Intentar insertar en conversations primero try { $stmt = $db->query( "INSERT INTO conversations (user_id, content, direction, message_type, status, message_id, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)", array_values($messageData) ); } catch (Exception $e) { // Si falla, intentar en messages try { $stmt = $db->query( "INSERT INTO messages (user_id, message_text, direction, message_type, status, message_id, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)", [$userId, $message, 'outgoing', 'text', 'sent', $response['messages'][0]['id'] ?? null, date('Y-m-d H:i:s')] ); } catch (Exception $e2) { error_log("Error guardando mensaje: " . $e2->getMessage()); } } echo json_encode([ 'success' => true, 'message' => 'Mensaje enviado correctamente', 'whatsapp_response' => $response ]); } else { echo json_encode([ 'success' => false, 'error' => 'Error al enviar mensaje por WhatsApp' ]); } } else { http_response_code(400); echo json_encode(['error' => 'Formato de datos inválido. Se requiere recipient o user_id+message']); exit; } } catch (Exception $e) { error_log("Error in send_message.php: " . $e->getMessage()); http_response_code(500); echo json_encode(['error' => 'Error interno del servidor: ' . $e->getMessage()]); } ?>