409 lines
21 KiB
PHP
Executable File
409 lines
21 KiB
PHP
Executable File
<?php
|
|
require_once __DIR__ . '/../includes/session_check.php';
|
|
require_once __DIR__ . '/../includes/db.php';
|
|
require_once __DIR__ . '/../src/DiscordSender.php';
|
|
require_once __DIR__ . '/../config/config.php';
|
|
|
|
// Verificar que el usuario sea administrador
|
|
if ($_SESSION['role'] !== 'admin') {
|
|
header('HTTP/1.0 403 Forbidden');
|
|
die('Acceso denegado. Solo los administradores pueden acceder a esta página.');
|
|
}
|
|
|
|
$message = '';
|
|
$error = '';
|
|
$success = '';
|
|
$discordResponse = null;
|
|
$permissionsInfo = [];
|
|
$telegramWebhookInfo = null;
|
|
|
|
// Manejar el envío del formulario de prueba
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
// Verificar si es una solicitud de verificación de permisos de Discord
|
|
if (isset($_POST['check_permissions']) && !empty($_POST['guild_id'])) {
|
|
$guildId = trim($_POST['guild_id']);
|
|
try {
|
|
$ch = curl_init("https://discord.com/api/v10/guilds/{$guildId}");
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_HTTPHEADER => [
|
|
"Authorization: Bot " . DISCORD_BOT_TOKEN,
|
|
"Content-Type: application/json"
|
|
],
|
|
CURLOPT_RETURNTRANSFER => true
|
|
]);
|
|
|
|
$response = curl_exec($ch);
|
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
|
|
if ($httpCode === 200) {
|
|
$guild = json_decode($response, true);
|
|
|
|
$ch = curl_init("https://discord.com/api/v10/users/@me");
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_HTTPHEADER => ["Authorization: Bot " . DISCORD_BOT_TOKEN],
|
|
CURLOPT_RETURNTRANSFER => true
|
|
]);
|
|
|
|
$botInfo = json_decode(curl_exec($ch), true);
|
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
|
|
if ($httpCode !== 200 || !isset($botInfo['id'])) {
|
|
throw new Exception("No se pudo obtener la información del bot de Discord. Verifica que el token sea correcto. Código HTTP: $httpCode");
|
|
}
|
|
|
|
$botId = $botInfo['id'];
|
|
|
|
$ch = curl_init("https://discord.com/api/v10/guilds/{$guildId}/roles");
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_HTTPHEADER => ["Authorization: Bot " . DISCORD_BOT_TOKEN],
|
|
CURLOPT_RETURNTRANSFER => true
|
|
]);
|
|
|
|
$roles = json_decode(curl_exec($ch), true);
|
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
|
|
if ($httpCode === 200 && is_array($roles)) {
|
|
$ch = curl_init("https://discord.com/api/v10/guilds/{$guildId}/members/{$botId}");
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_HTTPHEADER => ["Authorization: Bot " . DISCORD_BOT_TOKEN],
|
|
CURLOPT_RETURNTRANSFER => true
|
|
]);
|
|
|
|
$member = json_decode(curl_exec($ch), true);
|
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
|
|
if ($httpCode === 404) {
|
|
throw new Exception("El bot no está en el servidor de Discord especificado.");
|
|
} elseif ($httpCode !== 200) {
|
|
throw new Exception("Error al obtener información del bot en el servidor. Código HTTP: $httpCode");
|
|
}
|
|
|
|
if (isset($member['roles']) && is_array($member['roles'])) {
|
|
$botRoles = array_filter($roles, fn($role) => in_array($role['id'], $member['roles']));
|
|
$permissions = 0;
|
|
foreach ($botRoles as $role) {
|
|
$permissions |= intval($role['permissions']);
|
|
}
|
|
|
|
$permissionsInfo = [
|
|
'guild_name' => $guild['name'] ?? 'Desconocido',
|
|
'bot_has_admin' => ($permissions & 0x8) === 0x8,
|
|
'can_kick' => ($permissions & 0x2) === 0x2,
|
|
'can_ban' => ($permissions & 0x4) === 0x4,
|
|
'permissions_int' => $permissions,
|
|
'permissions_bin' => decbin($permissions),
|
|
'roles' => array_column($botRoles, 'name')
|
|
];
|
|
|
|
$success = "Permisos de Discord verificados para el servidor: " . htmlspecialchars($permissionsInfo['guild_name']);
|
|
} else {
|
|
$error = "No se pudo obtener la información de roles del bot en el servidor de Discord.";
|
|
}
|
|
} else {
|
|
$error = "No se pudieron obtener los roles del servidor de Discord. Código HTTP: $httpCode";
|
|
}
|
|
} else {
|
|
$error = "Error al obtener información del servidor de Discord. Código HTTP: $httpCode";
|
|
}
|
|
} catch (Exception $e) {
|
|
$error = "Error al verificar permisos de Discord: " . $e->getMessage();
|
|
}
|
|
}
|
|
// Verificar si es una solicitud de verificación de webhook de Telegram
|
|
elseif (isset($_POST['check_telegram_webhook'])) {
|
|
try {
|
|
if (!defined('TELEGRAM_BOT_TOKEN') || empty(TELEGRAM_BOT_TOKEN)) {
|
|
throw new Exception("La constante TELEGRAM_BOT_TOKEN no está definida o está vacía.");
|
|
}
|
|
|
|
$botToken = TELEGRAM_BOT_TOKEN;
|
|
$apiUrl = "https://api.telegram.org/bot{$botToken}/getWebhookInfo";
|
|
|
|
$ch = curl_init($apiUrl);
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_CONNECTTIMEOUT => 10, // Segundos para esperar la conexión
|
|
CURLOPT_TIMEOUT => 20, // Segundos para la ejecución total de cURL
|
|
]);
|
|
$response = curl_exec($ch);
|
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
|
|
if ($response === false) {
|
|
throw new Exception('Error en cURL al contactar la API de Telegram: ' . curl_error($ch));
|
|
}
|
|
|
|
if ($httpCode !== 200) {
|
|
throw new Exception("La API de Telegram devolvió un código HTTP {$httpCode}. Respuesta: " . $response);
|
|
}
|
|
|
|
$result = json_decode($response, true);
|
|
|
|
if (!$result['ok']) {
|
|
throw new Exception("Error de la API de Telegram: " . ($result['description'] ?? 'Error desconocido'));
|
|
}
|
|
|
|
$telegramWebhookInfo = $result['result'];
|
|
$success = "Información del webhook de Telegram obtenida correctamente.";
|
|
|
|
} catch (Exception $e) {
|
|
$error = "Error al verificar el webhook de Telegram: " . $e->getMessage();
|
|
}
|
|
}
|
|
// Manejar la eliminación del webhook de Telegram
|
|
elseif (isset($_POST['delete_telegram_webhook'])) {
|
|
try {
|
|
if (!defined('TELEGRAM_BOT_TOKEN') || empty(TELEGRAM_BOT_TOKEN)) {
|
|
throw new Exception("La constante TELEGRAM_BOT_TOKEN no está definida o está vacía.");
|
|
}
|
|
$botToken = TELEGRAM_BOT_TOKEN;
|
|
$apiUrl = "https://api.telegram.org/bot{$botToken}/deleteWebhook";
|
|
|
|
$ch = curl_init($apiUrl);
|
|
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true]);
|
|
$response = curl_exec($ch);
|
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
$result = json_decode($response, true);
|
|
|
|
if ($httpCode === 200 && $result['ok']) {
|
|
$success = "Webhook de Telegram eliminado correctamente.";
|
|
} else {
|
|
throw new Exception("Error al eliminar el webhook: " . ($result['description'] ?? 'Respuesta inválida de la API.'));
|
|
}
|
|
} catch (Exception $e) {
|
|
$error = "Error al eliminar el webhook de Telegram: " . $e->getMessage();
|
|
}
|
|
}
|
|
// Manejar la configuración del webhook de Telegram
|
|
elseif (isset($_POST['set_telegram_webhook'])) {
|
|
try {
|
|
// Las constantes son definidas en config.php
|
|
if (!defined('TELEGRAM_BOT_TOKEN') || !defined('BOT_BASE_URL') || !defined('TELEGRAM_WEBHOOK_TOKEN')) {
|
|
throw new Exception("Una o más constantes requeridas (TELEGRAM_BOT_TOKEN, BOT_BASE_URL, TELEGRAM_WEBHOOK_TOKEN) no están definidas. Revisa tu archivo .env y la configuración.");
|
|
}
|
|
|
|
$botToken = TELEGRAM_BOT_TOKEN;
|
|
$webhookUrl = rtrim(BOT_BASE_URL, '/') . '/telegram/webhook/telegram_bot_webhook.php?auth_token=' . TELEGRAM_WEBHOOK_TOKEN;
|
|
$apiUrl = "https://api.telegram.org/bot{$botToken}/setWebhook?url=" . urlencode($webhookUrl);
|
|
|
|
$ch = curl_init($apiUrl);
|
|
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true]);
|
|
$response = curl_exec($ch);
|
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
$result = json_decode($response, true);
|
|
|
|
if ($httpCode === 200 && $result['ok']) {
|
|
$success = "Webhook de Telegram configurado correctamente en: " . htmlspecialchars($webhookUrl);
|
|
} else {
|
|
throw new Exception("Error al configurar el webhook: " . ($result['description'] ?? 'Respuesta inválida de la API.'));
|
|
}
|
|
} catch (Exception $e) {
|
|
$error = "Error al configurar el webhook de Telegram: " . $e->getMessage();
|
|
}
|
|
}
|
|
// Si es un envío de mensaje de prueba de Discord
|
|
elseif (isset($_POST['discord_id']) && !empty($_POST['test_content'])) {
|
|
$recipientId = trim($_POST['discord_id']);
|
|
$testContent = trim($_POST['test_content']);
|
|
$testRecipientType = $_POST['test_recipient_type'] ?? 'channel';
|
|
|
|
try {
|
|
$logDir = __DIR__ . '/../logs';
|
|
if (!is_dir($logDir)) mkdir($logDir, 0755, true);
|
|
error_log("Test Discord: ID={$recipientId}, Type={$testRecipientType}, Token=" . substr(DISCORD_BOT_TOKEN, 0, 8) . "...", 3, $logDir . '/discord_api.log');
|
|
|
|
$discordSender = new DiscordSender(DISCORD_BOT_TOKEN);
|
|
$discordResponse = $discordSender->sendMessage($recipientId, $testContent, $testRecipientType);
|
|
$success = "Mensaje de prueba de Discord enviado con éxito.";
|
|
} catch (Exception $e) {
|
|
$error = "Error al enviar mensaje de prueba de Discord: " . $e->getMessage();
|
|
}
|
|
} else {
|
|
$error = "Por favor, completa todos los campos requeridos.";
|
|
}
|
|
}
|
|
|
|
// Incluir el encabezado que contiene el menú lateral
|
|
require_once __DIR__ . '/../templates/header.php';
|
|
?>
|
|
|
|
<!-- Contenido principal -->
|
|
<div id="page-content-wrapper">
|
|
<div class="container-fluid">
|
|
<h1 class="mt-4">Probar Conexiones de Bots</h1>
|
|
|
|
<?php if ($error): ?>
|
|
<div class="alert alert-danger"><?php echo $error; ?></div>
|
|
<?php endif; ?>
|
|
|
|
<?php if ($success): ?>
|
|
<div class="alert alert-success"><?php echo $success; ?></div>
|
|
<?php endif; ?>
|
|
|
|
<div class="card shadow-sm mb-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">Enviar Mensaje de Prueba a Discord</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<form action="" method="POST">
|
|
<div class="mb-3">
|
|
<label for="discord_id" class="form-label">ID de Canal o Usuario de Discord</label>
|
|
<input type="text" class="form-control" id="discord_id" name="discord_id" required
|
|
value="<?php echo htmlspecialchars($_POST['discord_id'] ?? ''); ?>">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Tipo de Destinatario</label>
|
|
<div>
|
|
<input type="radio" id="testRecipientTypeChannel" name="test_recipient_type" value="channel"
|
|
<?php echo (($_POST['test_recipient_type'] ?? 'channel') === 'channel') ? 'checked' : ''; ?>>
|
|
<label for="testRecipientTypeChannel">Canal</label>
|
|
|
|
<input type="radio" id="testRecipientTypeUser" name="test_recipient_type" value="user" class="ms-3"
|
|
<?php echo (($_POST['test_recipient_type'] ?? 'channel') === 'user') ? 'checked' : ''; ?>>
|
|
<label for="testRecipientTypeUser">Usuario</label>
|
|
</div>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="test_content" class="form-label">Contenido del Mensaje</label>
|
|
<textarea class="form-control" id="test_content" name="test_content" rows="3" required><?php
|
|
echo htmlspecialchars($_POST['test_content'] ?? 'Mensaje de prueba desde el bot.');
|
|
?></textarea>
|
|
</div>
|
|
<button type="submit" class="btn btn-primary">Enviar Prueba a Discord</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if (isset($discordResponse) && $discordResponse !== null): ?>
|
|
<div class="card shadow-sm mb-4">
|
|
<div class="card-header"><h5 class="mb-0">Respuesta de la API de Discord</h5></div>
|
|
<div class="card-body"><pre><code><?php print_r($discordResponse); ?></code></pre></div>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div class="card shadow-sm mb-4">
|
|
<div class="card-header"><h5 class="mb-0">Verificar Permisos del Bot de Discord</h5></div>
|
|
<div class="card-body">
|
|
<form action="" method="POST" class="mb-4">
|
|
<input type="hidden" name="check_permissions" value="1">
|
|
<div class="mb-3">
|
|
<label for="guild_id" class="form-label">ID del Servidor de Discord</label>
|
|
<input type="text" class="form-control" id="guild_id" name="guild_id" required
|
|
value="<?php echo htmlspecialchars($_POST['guild_id'] ?? ''); ?>"
|
|
placeholder="Ej: 123456789012345678">
|
|
</div>
|
|
<button type="submit" class="btn btn-info">Verificar Permisos de Discord</button>
|
|
</form>
|
|
|
|
<?php if (!empty($permissionsInfo)): ?>
|
|
<div class="alert alert-info">
|
|
<h6>Resultado de la verificación de Discord:</h6>
|
|
<ul class="mb-0">
|
|
<li>Servidor: <strong><?php echo htmlspecialchars($permissionsInfo['guild_name']); ?></strong></li>
|
|
<li>Es Administrador:
|
|
<span class="badge bg-<?php echo $permissionsInfo['bot_has_admin'] ? 'success' : 'danger'; ?>">
|
|
<?php echo $permissionsInfo['bot_has_admin'] ? 'Sí' : 'No'; ?>
|
|
</span>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card shadow-sm mb-4">
|
|
<div class="card-header"><h5 class="mb-0">Verificar Estado del Webhook de Telegram</h5></div>
|
|
<div class="card-body">
|
|
<p>Obtén el estado actual de tu webhook directamente desde la API de Telegram para diagnosticar problemas de conexión.</p>
|
|
<form action="" method="POST">
|
|
<input type="hidden" name="check_telegram_webhook" value="1">
|
|
<button type="submit" class="btn btn-info">Verificar Webhook de Telegram</button>
|
|
</form>
|
|
|
|
<?php if (isset($telegramWebhookInfo) && is_array($telegramWebhookInfo)): ?>
|
|
<div class="mt-4">
|
|
<h6>Resultado de la verificación de Telegram:</h6>
|
|
<?php if (empty($telegramWebhookInfo['url'])): ?>
|
|
<div class="alert alert-danger">
|
|
<strong>No hay webhook configurado.</strong> El bot está funcionando en modo 'getUpdates'.
|
|
</div>
|
|
<?php else: ?>
|
|
<ul class="list-group">
|
|
<li class="list-group-item"><strong>URL:</strong> <code><?php echo htmlspecialchars($telegramWebhookInfo['url']); ?></code></li>
|
|
<li class="list-group-item"><strong>Actualizaciones pendientes:</strong>
|
|
<span class="badge bg-<?php echo $telegramWebhookInfo['pending_update_count'] > 0 ? 'warning' : 'success'; ?>">
|
|
<?php echo $telegramWebhookInfo['pending_update_count']; ?>
|
|
</span>
|
|
</li>
|
|
<?php if (!empty($telegramWebhookInfo['last_error_date'])): ?>
|
|
<li class="list-group-item list-group-item-danger">
|
|
<strong>Último error:</strong> <?php echo date('Y-m-d H:i:s', $telegramWebhookInfo['last_error_date']); ?>
|
|
<br>
|
|
<strong>Mensaje:</strong> <?php echo htmlspecialchars($telegramWebhookInfo['last_error_message']); ?>
|
|
</li>
|
|
<?php else: ?>
|
|
<li class="list-group-item list-group-item-success"><strong>Último error:</strong> Ninguno reportado.</li>
|
|
<?php endif; ?>
|
|
<li class="list-group-item"><strong>Máx. Conexiones:</strong> <?php echo $telegramWebhookInfo['max_connections'] ?? 'No definido'; ?></li>
|
|
<li class="list-group-item"><strong>Actualizaciones permitidas:</strong>
|
|
<?php if (!empty($telegramWebhookInfo['allowed_updates']) && count($telegramWebhookInfo['allowed_updates']) > 0): ?>
|
|
<code><?php echo implode(', ', $telegramWebhookInfo['allowed_updates']); ?></code>
|
|
<?php else: ?>
|
|
<span>Todos los tipos (por defecto).</span>
|
|
<?php endif; ?>
|
|
</li>
|
|
</ul>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card shadow-sm mb-4">
|
|
<div class="card-header"><h5 class="mb-0">Gestionar Webhook de Telegram</h5></div>
|
|
<div class="card-body">
|
|
<p>Usa estos botones para eliminar o re-configurar el webhook de Telegram. Esto es útil para forzar a Telegram a actualizar la dirección IP de tu servidor si ha cambiado (por ejemplo, con DuckDNS).</p>
|
|
<form action="" method="POST" class="d-inline me-2">
|
|
<input type="hidden" name="delete_telegram_webhook" value="1">
|
|
<button type="submit" class="btn btn-danger" onclick="return confirm('¿Estás seguro de que quieres eliminar el webhook? El bot dejará de recibir actualizaciones.');">Eliminar Webhook</button>
|
|
</form>
|
|
<form action="" method="POST" class="d-inline">
|
|
<input type="hidden" name="set_telegram_webhook" value="1">
|
|
<button type="submit" class="btn btn-success">Configurar Webhook</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Scripts de Bootstrap -->
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
|
|
<script>
|
|
// Toggle del menú lateral
|
|
function toggleSidebar() {
|
|
document.getElementById('wrapper').classList.toggle('toggled');
|
|
}
|
|
|
|
// Función para copiar al portapapeles
|
|
function copyToClipboard(elementId) {
|
|
var copyText = document.getElementById(elementId);
|
|
copyText.select();
|
|
copyText.setSelectionRange(0, 99999);
|
|
document.execCommand("copy");
|
|
|
|
var button = event.target;
|
|
var originalText = button.innerHTML;
|
|
button.innerHTML = '¡Copiado!';
|
|
button.classList.remove('btn-outline-secondary');
|
|
button.classList.add('btn-success');
|
|
|
|
setTimeout(function() {
|
|
button.innerHTML = originalText;
|
|
button.classList.remove('btn-success');
|
|
button.classList.add('btn-outline-secondary');
|
|
}, 2000);
|
|
}
|
|
</script>
|
|
|
|
<?php require_once __DIR__ . '/../templates/footer.php'; ?>
|