147 lines
5.0 KiB
PHP
Executable File
147 lines
5.0 KiB
PHP
Executable File
#!/usr/bin/env php
|
|
<?php
|
|
/**
|
|
* Script para enviar mensajes programados
|
|
* Se ejecuta cada minuto desde cron o worker
|
|
*
|
|
* Uso:
|
|
* php send_scheduled_messages.php
|
|
*/
|
|
|
|
require_once __DIR__ . '/config/config.php';
|
|
|
|
// Configurar logs
|
|
$logFile = __DIR__ . '/logs/scheduled_messages.log';
|
|
|
|
function writeScheduledLog($message) {
|
|
global $logFile;
|
|
$timestamp = date('Y-m-d H:i:s');
|
|
file_put_contents($logFile, "[$timestamp] $message\n", FILE_APPEND);
|
|
}
|
|
|
|
writeScheduledLog("=== Iniciando envío de mensajes programados ===");
|
|
|
|
try {
|
|
$db = Database::getInstance();
|
|
$whatsappService = new WhatsAppService();
|
|
|
|
// Obtener mensajes programados para enviar
|
|
// Buscar mensajes cuya fecha/hora ya pasó y están pendientes
|
|
$currentDateTime = date('Y-m-d H:i:s');
|
|
$currentDate = date('Y-m-d');
|
|
$currentTime = date('H:i:00'); // Redondear a minuto exacto
|
|
|
|
$sql = "SELECT sm.*, u.phone_number, u.name as user_name
|
|
FROM scheduled_messages sm
|
|
LEFT JOIN users u ON sm.user_id = u.id
|
|
WHERE sm.status = 'pending'
|
|
AND (
|
|
(sm.scheduled_date < ? AND sm.scheduled_time <= ?)
|
|
OR (sm.scheduled_date = ? AND sm.scheduled_time <= ?)
|
|
)
|
|
LIMIT 50";
|
|
|
|
$messages = $db->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);
|