Files
contenedor_ibiza/bot/webhook.php

225 lines
9.2 KiB
PHP
Executable File

<?php
// ---- INICIO DE INSTRUMENTACIÓN ----
$startTime = microtime(true);
function log_timing($message) {
static $lastTime = null;
global $startTime;
if ($lastTime === null) {
$lastTime = $startTime;
}
$now = microtime(true);
$elapsed = $now - $lastTime;
$totalElapsed = $now - $startTime;
$logMessage = sprintf(
"[%s] Total: %.4fs | Step: %.4fs | %s\n",
date('Y-m-d H:i:s'),
$totalElapsed,
$elapsed,
$message
);
// Usar __DIR__ para asegurar la ruta correcta
file_put_contents(__DIR__ . '/../logs/webhook_timing.log', $logMessage, FILE_APPEND);
$lastTime = $now;
}
// ---- FIN DE INSTRUMENTACIÓN ----
// Configurar logging de errores
error_reporting(E_ALL);
ini_set('log_errors', 1);
ini_set('error_log', __DIR__ . '/../public/logs/bot_error.log');
require_once __DIR__ . '/../config/config.php';
require_once __DIR__ . '/TelegramBot.php';
class TurnoBot {
private $bot;
private $config;
public function __construct() {
log_timing("TurnoBot: __construct start");
$this->config = require __DIR__ . '/../config/config.php';
$this->bot = new TelegramBot();
log_timing("TurnoBot: __construct end");
}
public function handleUpdate($update) {
log_timing("handleUpdate: start");
try {
// Manejar callback de botones inline
if (isset($update['callback_query'])) {
log_timing("handleUpdate: detected callback_query");
$this->handleCallback($update['callback_query']);
return;
}
// Manejar mensajes normales
if (!isset($update['message'])) {
log_timing("handleUpdate: no message found, exiting");
return;
}
$message = $update['message'];
$chatId = $message['chat']['id'];
$text = trim($message['text'] ?? '');
if (empty($text)) {
log_timing("handleUpdate: empty text, exiting");
return;
}
$textLower = mb_strtolower($text, 'UTF-8');
log_timing("handleUpdate: processing command '{$textLower}'");
// Comandos
if ($textLower === '/start' || $textLower === '/menu' || $textLower === 'menu') {
$this->sendMenu($chatId);
} elseif ($textLower === '/turnos' || $textLower === 'turnos') {
log_timing("handleUpdate: /turnos command start");
$this->bot->sendMessage($chatId, $this->bot->getTablaTurnos(8));
log_timing("handleUpdate: /turnos command end");
} elseif ($textLower === '/semana' || $textLower === 'semana' || $textLower === 'hoy') {
log_timing("handleUpdate: /semana command start");
$this->bot->sendMessage($chatId, $this->bot->getSemanaActual());
log_timing("handleUpdate: /semana command end");
} elseif ($textLower === '/ayudantes' || $textLower === 'ayudantes') {
log_timing("handleUpdate: /ayudantes command start");
$ayudantes = $this->bot->getListaAyudantesParaBusqueda();
$this->bot->sendMessage($chatId, "<b>AYUDANTES DISPONIBLES:</b>\n\n" . implode("\n", $ayudantes));
log_timing("handleUpdate: /ayudantes command end");
} elseif ($textLower === '/pdf' || $textLower === 'pdf' || $textLower === 'mi pdf') {
log_timing("handleUpdate: /pdf command start");
$this->bot->sendPDFGeneral($chatId);
log_timing("handleUpdate: /pdf command end");
} else {
log_timing("handleUpdate: searching by name '{$text}'");
$config = require __DIR__ . '/../config/config.php';
try {
log_timing("handleUpdate: DB connection start");
$pdo = new PDO(
"mysql:host={$config['db']['host']};port={$config['db']['port']};dbname={$config['db']['database']};charset=utf8mb4",
$config['db']['username'],
$config['db']['password'],
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
log_timing("handleUpdate: DB connection end");
} catch (Exception $e) {
log_timing("handleUpdate: DB connection FAILED");
$this->bot->sendMessage($chatId, "Error de conexion.");
return;
}
log_timing("handleUpdate: DB query start");
$stmt = $pdo->prepare("SELECT * FROM users WHERE (nombre LIKE ? OR username LIKE ?) AND (rol = 'ayudante' OR rol = 'coordinador') AND activo = 1 LIMIT 1");
$stmt->execute(["%$text%", "%$text%"]);
$user = $stmt->fetch();
log_timing("handleUpdate: DB query end");
if ($user) {
log_timing("handleUpdate: user found, sending text turnos");
$this->bot->sendMessage($chatId, $this->bot->getTurnosAyudante($user['nombre']));
} else {
log_timing("handleUpdate: user not found, getting plain text turnos");
$this->bot->sendMessage($chatId, $this->bot->getTurnosAyudante($text));
log_timing("handleUpdate: plain text turnos sent");
}
}
} catch (Exception $e) {
error_log("Error en handleUpdate: " . $e->getMessage());
log_timing("handleUpdate: EXCEPTION: " . $e->getMessage());
if (isset($update['message']['chat']['id'])) {
$this->bot->sendMessage($update['message']['chat']['id'], "Error: " . $e->getMessage());
}
}
log_timing("handleUpdate: end");
}
private function handleCallback($callback) {
log_timing("handleCallback: start");
try {
$callbackId = $callback['id'];
$data = $callback['data'];
$message = $callback['message'];
$chatId = $message['chat']['id'];
$messageId = $message['message_id'];
log_timing("handleCallback: processing data '{$data}'");
switch ($data) {
case 'ver_turnos':
$this->bot->answerCallback($callbackId, 'Cargando turnos...');
$this->bot->editMessage($chatId, $messageId, $this->bot->getTablaTurnos(8));
break;
case 'semana_actual':
$this->bot->answerCallback($callbackId, 'Cargando semana actual...');
$this->bot->editMessage($chatId, $messageId, $this->bot->getSemanaActual());
break;
case 'mi_pdf':
$this->bot->answerCallback($callbackId, 'Generando PDF...');
$this->bot->deleteMessage($chatId, $messageId);
$this->bot->sendPDFGeneral($chatId);
break;
case 'buscar_nombre':
$this->bot->answerCallback($callbackId, '');
$this->bot->deleteMessage($chatId, $messageId);
$this->bot->sendMessage($chatId, "🔍 <b>Buscar por Nombre</b>\n\nEscribe el nombre del ayudante que buscas:");
break;
case 'mi_turno':
$this->bot->answerCallback($callbackId, 'Enviando tu turno...');
$this->bot->editMessage($chatId, $messageId, "Por favor ingresa tu nombre para ver tu turno:");
break;
default:
$this->bot->answerCallback($callbackId, 'Opcion no reconocida');
}
log_timing("handleCallback: data '{$data}' processed");
} catch (Exception $e) {
error_log("Error en handleCallback: " . $e->getMessage());
log_timing("handleCallback: EXCEPTION: " . $e->getMessage());
}
log_timing("handleCallback: end");
}
private function sendMenu($chatId) {
log_timing("sendMenu: start");
$mensaje = "<b>BOT DE TURNOS - CONTENEDOR IBIZA</b>\n\n";
$mensaje .= "Selecciona una opcion del menu:\n\n";
$mensaje .= "Ver Turnos - Tabla completa de asignaciones\n";
$mensaje .= "Semana Actual - Quien tiene turno esta semana\n";
$mensaje .= "Horarios PDF - Descargar horarios en PDF\n";
$mensaje .= "Buscar por Nombre - Consultar un ayudante especifico\n";
$mensaje .= "Mi Turno - Ver tu proximo turno";
$this->bot->sendKeyboard($chatId, $mensaje);
log_timing("sendMenu: end");
}
}
// Recibir actualización
$update = json_decode(file_get_contents('php://input'), true);
log_timing("Webhook invoked");
// Log para debugging
// error_log("Webhook recibido: " . json_encode($update)); // Se puede comentar para no llenar el log de errores
if ($update) {
log_timing("Update received, initializing bot");
$bot = new TurnoBot();
$bot->handleUpdate($update);
log_timing("Script finished");
} else {
http_response_code(200);
log_timing("Webhook checked (no update provided)");
// echo "Webhook activo. Usa /start para ver el menu."; // No es necesario en producción
}