#!/usr/bin/env php fetchAll($sql, [$currentDate, '23:59:59', $currentDate, $currentTime]); writeScheduledLog("Mensajes encontrados para enviar: " . count($messages)); if (empty($messages)) { writeScheduledLog("No hay mensajes programados para enviar"); exit(0); } $sentCount = 0; $errorCount = 0; foreach ($messages as $msg) { try { writeScheduledLog("Procesando mensaje ID {$msg['id']} para usuario {$msg['user_name']} ({$msg['phone_number']})"); // Verificar que el usuario tenga teléfono if (empty($msg['phone_number'])) { throw new Exception("Usuario sin número de teléfono"); } $response = null; if ($msg['message_type'] === 'template') { // Enviar plantilla $templateName = $msg['template_name']; $language = $msg['template_language'] ?? 'es'; $parameters = []; if (!empty($msg['template_parameters'])) { $parameters = json_decode($msg['template_parameters'], true); if (!is_array($parameters)) { $parameters = []; } } writeScheduledLog("Enviando plantilla: {$templateName} con " . count($parameters) . " parámetros"); $response = $whatsappService->sendTemplateMessage( $msg['phone_number'], $templateName, $language, $parameters ); } else if ($msg['message_type'] === 'text') { // Enviar mensaje de texto $content = $msg['message_content']; writeScheduledLog("Enviando mensaje de texto"); $response = $whatsappService->sendTextMessage( $msg['phone_number'], $content ); } else { throw new Exception("Tipo de mensaje no soportado: " . $msg['message_type']); } // Verificar respuesta if ($response && (isset($response['messages']) || isset($response['success']))) { // Marcar como enviado $db->execute( "UPDATE scheduled_messages SET status = 'sent', sent_at = NOW(), updated_at = NOW() WHERE id = ?", [$msg['id']] ); writeScheduledLog("✅ Mensaje ID {$msg['id']} enviado exitosamente"); $sentCount++; } else { throw new Exception("Respuesta inválida de WhatsApp API: " . json_encode($response)); } } catch (Exception $e) { $errorMessage = $e->getMessage(); writeScheduledLog("❌ Error enviando mensaje ID {$msg['id']}: {$errorMessage}"); // Marcar como fallido $db->execute( "UPDATE scheduled_messages SET status = 'failed', error_message = ?, updated_at = NOW() WHERE id = ?", [$errorMessage, $msg['id']] ); $errorCount++; } // Pequeña pausa entre envíos para no saturar API usleep(250000); // 250ms } writeScheduledLog("=== Resumen ==="); writeScheduledLog("Enviados: {$sentCount}"); writeScheduledLog("Errores: {$errorCount}"); writeScheduledLog("=== Fin ==="); } catch (Exception $e) { writeScheduledLog("ERROR FATAL: " . $e->getMessage()); writeScheduledLog($e->getTraceAsString()); exit(1); } exit(0);