Files
whatsapp/configurar_tokens.php
2026-01-12 11:06:43 -05:00

341 lines
14 KiB
PHP

<?php
/**
* Configurador de Tokens y Variables - WhatsApp Bot Manager
* Herramienta para configurar WEBHOOK_VERIFY_TOKEN y otros valores
* Fecha: 4 de enero de 2026
*/
require_once 'config/config.php';
// Solo permitir acceso desde localhost por seguridad
$allowedIPs = ['127.0.0.1', '::1', 'localhost'];
$clientIP = $_SERVER['REMOTE_ADDR'] ?? $_SERVER['HTTP_X_FORWARDED_FOR'] ?? 'unknown';
if (!in_array($clientIP, $allowedIPs) && $clientIP !== 'unknown') {
die("❌ Acceso denegado. Esta utilidad solo puede ejecutarse desde localhost por seguridad.");
}
?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>🔧 Configurador de Tokens - WhatsApp Bot Manager</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #25D366 0%, #128C7E 100%);
color: #333;
margin: 0;
padding: 20px;
min-height: 100vh;
}
.container {
max-width: 900px;
margin: 0 auto;
background: white;
padding: 40px;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
}
h1 {
color: #25D366;
text-align: center;
margin-bottom: 30px;
}
.info-box {
background: #e8f5e8;
padding: 20px;
border-left: 5px solid #25D366;
margin: 20px 0;
border-radius: 5px;
}
.warning-box {
background: #fff3cd;
padding: 20px;
border-left: 5px solid #ffc107;
margin: 20px 0;
border-radius: 5px;
}
.error-box {
background: #f8d7da;
padding: 20px;
border-left: 5px solid #dc3545;
margin: 20px 0;
border-radius: 5px;
}
.form-group {
margin: 20px 0;
}
label {
display: block;
font-weight: bold;
margin-bottom: 8px;
color: #333;
}
input[type="text"], textarea {
width: 100%;
padding: 12px;
border: 2px solid #ddd;
border-radius: 8px;
font-size: 16px;
box-sizing: border-box;
font-family: monospace;
}
input:focus, textarea:focus {
outline: none;
border-color: #25D366;
}
.btn {
background: #25D366;
color: white;
padding: 12px 30px;
border: none;
border-radius: 8px;
font-size: 16px;
cursor: pointer;
margin: 10px 5px;
}
.btn:hover {
background: #1aa347;
}
.btn-secondary {
background: #6c757d;
}
.btn-secondary:hover {
background: #545b62;
}
.config-display {
background: #f8f9fa;
padding: 20px;
border-radius: 8px;
margin: 20px 0;
font-family: monospace;
border: 1px solid #dee2e6;
}
.token-generator {
background: #e3f2fd;
padding: 15px;
border-radius: 8px;
margin: 15px 0;
border-left: 5px solid #2196f3;
}
.copy-btn {
background: #2196f3;
color: white;
border: none;
padding: 8px 15px;
border-radius: 5px;
cursor: pointer;
font-size: 12px;
margin-left: 10px;
}
.copy-btn:hover {
background: #1976d2;
}
</style>
</head>
<body>
<div class="container">
<h1>🔧 Configurador de Tokens WhatsApp</h1>
<?php
try {
$pdo = createDbConnection();
echo '<div class="info-box">';
echo '<h4>✅ Conexión a Base de Datos: EXITOSA</h4>';
echo '</div>';
// Verificar si existe tabla system_config
$configTableExists = $pdo->query("SHOW TABLES LIKE 'system_config'")->rowCount() > 0;
// Crear tabla si no existe
if (!$configTableExists && isset($_POST['create_table'])) {
$createTableSQL = "
CREATE TABLE system_config (
id INT AUTO_INCREMENT PRIMARY KEY,
config_key VARCHAR(100) UNIQUE NOT NULL,
config_value TEXT,
description VARCHAR(255),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci";
$pdo->exec($createTableSQL);
// Insertar valores por defecto
$defaultConfigs = [
['webhook_verify_token', 'mi_token_secreto_' . bin2hex(random_bytes(8)), 'Token para verificar webhook de WhatsApp'],
['whatsapp_token', '', 'Token de acceso de WhatsApp Business API'],
['whatsapp_phone_number_id', '', 'ID del número de teléfono de WhatsApp'],
['whatsapp_api_url', 'https://graph.facebook.com/v22.0/', 'URL base de la API de WhatsApp']
];
$stmt = $pdo->prepare("INSERT INTO system_config (config_key, config_value, description) VALUES (?, ?, ?)");
foreach ($defaultConfigs as $config) {
$stmt->execute($config);
}
echo '<div class="info-box">✅ Tabla system_config creada e inicializada correctamente</div>';
$configTableExists = true;
}
// Procesar actualización de configuración
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_config'])) {
$webhookToken = trim($_POST['webhook_verify_token']);
$whatsappToken = trim($_POST['whatsapp_token']);
$phoneNumberId = trim($_POST['whatsapp_phone_number_id']);
$apiUrl = trim($_POST['whatsapp_api_url']);
if ($configTableExists) {
$stmt = $pdo->prepare("
INSERT INTO system_config (config_key, config_value) VALUES (?, ?)
ON DUPLICATE KEY UPDATE config_value = VALUES(config_value)
");
$stmt->execute(['webhook_verify_token', $webhookToken]);
$stmt->execute(['whatsapp_token', $whatsappToken]);
$stmt->execute(['whatsapp_phone_number_id', $phoneNumberId]);
$stmt->execute(['whatsapp_api_url', $apiUrl]);
echo '<div class="info-box">✅ Configuración actualizada exitosamente en la base de datos</div>';
} else {
echo '<div class="error-box">❌ Tabla system_config no existe. Créala primero.</div>';
}
}
// Mostrar estado actual
echo '<h3>📊 Estado Actual de la Configuración</h3>';
echo '<div class="config-display">';
if ($configTableExists) {
echo '<h4>🗃️ Configuración desde Base de Datos:</h4>';
$stmt = $pdo->query("SELECT config_key, config_value FROM system_config ORDER BY config_key");
$dbConfigs = $stmt->fetchAll();
foreach ($dbConfigs as $config) {
$value = $config['config_value'];
$displayValue = empty($value) ? '<em style="color: #999;">Sin valor</em>' : htmlspecialchars($value);
echo "<strong>{$config['config_key']}:</strong> $displayValue<br>";
}
} else {
echo '<h4>⚠️ Tabla system_config NO EXISTE</h4>';
echo '<p>Los valores se toman de constantes PHP por defecto:</p>';
}
echo '<br><h4>📋 Valores Activos (lo que usa el sistema ahora):</h4>';
echo '<strong>WEBHOOK_VERIFY_TOKEN:</strong> ' . htmlspecialchars(WEBHOOK_VERIFY_TOKEN) . '<br>';
echo '<strong>WHATSAPP_TOKEN:</strong> ' . htmlspecialchars(WHATSAPP_TOKEN) . '<br>';
echo '<strong>WHATSAPP_PHONE_NUMBER_ID:</strong> ' . htmlspecialchars(WHATSAPP_PHONE_NUMBER_ID) . '<br>';
echo '<strong>WHATSAPP_API_URL:</strong> ' . htmlspecialchars(WHATSAPP_API_URL) . '<br>';
echo '</div>';
// Si no existe la tabla, mostrar opción para crearla
if (!$configTableExists) {
echo '<div class="warning-box">';
echo '<h4>🚨 Tabla de Configuración Faltante</h4>';
echo '<p>La tabla <code>system_config</code> no existe. Esta tabla es necesaria para guardar la configuración en la base de datos.</p>';
echo '<form method="post">';
echo '<input type="hidden" name="create_table" value="1">';
echo '<button type="submit" class="btn">🏗️ Crear Tabla system_config</button>';
echo '</form>';
echo '</div>';
} else {
// Formulario de configuración
echo '<h3>⚙️ Actualizar Configuración</h3>';
// Obtener valores actuales de BD
$currentValues = [];
$stmt = $pdo->query("SELECT config_key, config_value FROM system_config");
while ($row = $stmt->fetch()) {
$currentValues[$row['config_key']] = $row['config_value'];
}
echo '<form method="post">';
echo '<div class="form-group">';
echo '<label for="webhook_verify_token">🔐 Webhook Verify Token:</label>';
echo '<input type="text" id="webhook_verify_token" name="webhook_verify_token" ';
echo 'value="' . htmlspecialchars($currentValues['webhook_verify_token'] ?? '') . '" ';
echo 'placeholder="Token para verificar el webhook">';
echo '<div class="token-generator">';
echo '💡 <strong>Sugerencia:</strong> Usa un token seguro como: <code id="suggested-token">whatsapp_' . bin2hex(random_bytes(12)) . '</code>';
echo '<button type="button" class="copy-btn" onclick="copyToField(\'suggested-token\', \'webhook_verify_token\')">📋 Copiar</button>';
echo '</div>';
echo '</div>';
echo '<div class="form-group">';
echo '<label for="whatsapp_token">📱 WhatsApp Access Token:</label>';
echo '<input type="text" id="whatsapp_token" name="whatsapp_token" ';
echo 'value="' . htmlspecialchars($currentValues['whatsapp_token'] ?? '') . '" ';
echo 'placeholder="Token de acceso de WhatsApp Business API">';
echo '</div>';
echo '<div class="form-group">';
echo '<label for="whatsapp_phone_number_id">📞 Phone Number ID:</label>';
echo '<input type="text" id="whatsapp_phone_number_id" name="whatsapp_phone_number_id" ';
echo 'value="' . htmlspecialchars($currentValues['whatsapp_phone_number_id'] ?? '') . '" ';
echo 'placeholder="ID del número de teléfono">';
echo '</div>';
echo '<div class="form-group">';
echo '<label for="whatsapp_api_url">🌐 WhatsApp API URL:</label>';
echo '<input type="text" id="whatsapp_api_url" name="whatsapp_api_url" ';
echo 'value="' . htmlspecialchars($currentValues['whatsapp_api_url'] ?? 'https://graph.facebook.com/v22.0/') . '" ';
echo 'placeholder="URL base de la API">';
echo '</div>';
echo '<input type="hidden" name="update_config" value="1">';
echo '<button type="submit" class="btn">💾 Guardar Configuración</button>';
echo '</form>';
}
} catch (Exception $e) {
echo '<div class="error-box">';
echo '<h4>❌ Error de Sistema</h4>';
echo '<p>Error: ' . htmlspecialchars($e->getMessage()) . '</p>';
echo '</div>';
}
?>
<div class="info-box" style="margin-top: 30px;">
<h4>🌐 Enlaces del Sistema:</h4>
<p><strong>Panel principal:</strong> <a href="index.php" target="_blank">index.php</a></p>
<p><strong>Login:</strong> <a href="login.php" target="_blank">login.php</a></p>
<p><strong>Webhook endpoint:</strong> <a href="api/webhook.php" target="_blank">api/webhook.php</a></p>
</div>
<div class="warning-box" style="margin-top: 30px;">
<h4>⚠️ Instrucciones de Uso:</h4>
<ul>
<li><strong>Webhook Verify Token:</strong> Úsalo en la configuración del webhook de Facebook/Meta</li>
<li><strong>WhatsApp Token:</strong> Obténlo desde Meta for Developers</li>
<li><strong>Phone Number ID:</strong> Disponible en la consola de WhatsApp Business</li>
<li>Los cambios se guardan en la base de datos y tienen prioridad sobre los valores por defecto</li>
<li>Elimina esta herramienta en producción por seguridad</li>
</ul>
</div>
</div>
<script>
function copyToField(sourceId, targetId) {
const sourceText = document.getElementById(sourceId).textContent;
document.getElementById(targetId).value = sourceText;
// Feedback visual
const btn = event.target;
const originalText = btn.textContent;
btn.textContent = '✅ Copiado';
btn.style.background = '#4caf50';
setTimeout(() => {
btn.textContent = originalText;
btn.style.background = '#2196f3';
}, 1500);
}
</script>
</body>
</html>