284 lines
29 KiB
PHP
Executable File
284 lines
29 KiB
PHP
Executable File
<?php
|
||
error_reporting(E_ALL);
|
||
ini_set('display_errors', 0);
|
||
|
||
function getDB() {
|
||
static $pdo = null;
|
||
if ($pdo === null) {
|
||
$pdo = new PDO("pgsql:host=localhost;dbname=adx_system", "admin", "admin123", [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
|
||
}
|
||
return $pdo;
|
||
}
|
||
|
||
function ensureTables() {
|
||
$pdo = getDB();
|
||
$pdo->exec("CREATE TABLE IF NOT EXISTS admin.telegram_config (id SERIAL PRIMARY KEY, bot_token VARCHAR(255), chat_id VARCHAR(100), is_active BOOLEAN DEFAULT true)");
|
||
$pdo->exec("CREATE TABLE IF NOT EXISTS admin.ai_config (id SERIAL PRIMARY KEY, provider VARCHAR(50), api_key VARCHAR(500), model VARCHAR(100), is_active BOOLEAN DEFAULT true)");
|
||
$pdo->exec("CREATE TABLE IF NOT EXISTS admin.imap_checkers (id SERIAL PRIMARY KEY, name VARCHAR(255), email VARCHAR(255), password VARCHAR(255), imap_host VARCHAR(255), imap_port INTEGER DEFAULT 993, spam_folder VARCHAR(100) DEFAULT 'Junk', last_check TIMESTAMP, inbox_count INTEGER DEFAULT 0, spam_count INTEGER DEFAULT 0, is_active BOOLEAN DEFAULT true)");
|
||
$pdo->exec("CREATE TABLE IF NOT EXISTS admin.wevads_config (id SERIAL PRIMARY KEY, api_url VARCHAR(500) DEFAULT 'http://api.weval.digital:58081', username VARCHAR(255), password VARCHAR(255), auth_cookie TEXT, is_active BOOLEAN DEFAULT true)");
|
||
}
|
||
|
||
class TelegramBot {
|
||
private $token, $chatId;
|
||
public function __construct() {
|
||
$pdo = getDB();
|
||
$config = $pdo->query("SELECT * FROM admin.telegram_config WHERE is_active = true LIMIT 1")->fetch(PDO::FETCH_ASSOC);
|
||
if ($config) { $this->token = $config['bot_token']; $this->chatId = $config['chat_id']; }
|
||
}
|
||
public function send($message, $parseMode = 'HTML') {
|
||
if (!$this->token || !$this->chatId) return false;
|
||
$ch = curl_init("https://api.telegram.org/bot{$this->token}/sendMessage");
|
||
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => ['chat_id' => $this->chatId, 'text' => $message, 'parse_mode' => $parseMode]]);
|
||
$result = curl_exec($ch); curl_close($ch);
|
||
return json_decode($result, true);
|
||
}
|
||
public function alert($title, $msg, $sev = 'info') {
|
||
$emoji = ['info' => 'ℹ️', 'warning' => '⚠️', 'error' => '🚨', 'success' => '✅'];
|
||
return $this->send("{$emoji[$sev]} <b>{$title}</b>\n\n{$msg}\n\n🕐 " . date('Y-m-d H:i:s'));
|
||
}
|
||
}
|
||
|
||
class AIHelper {
|
||
private $provider, $apiKey, $model;
|
||
public function __construct() {
|
||
$pdo = getDB();
|
||
$config = $pdo->query("SELECT * FROM admin.ai_config WHERE is_active = true LIMIT 1")->fetch(PDO::FETCH_ASSOC);
|
||
if ($config) { $this->provider = $config['provider']; $this->apiKey = $config['api_key']; $this->model = $config['model']; }
|
||
}
|
||
public function generate($prompt) {
|
||
if (!$this->apiKey) return ['success' => false, 'error' => 'No API key configured'];
|
||
switch ($this->provider) {
|
||
case 'anthropic': return $this->claude($prompt);
|
||
case 'openai': return $this->openai($prompt);
|
||
case 'groq': return $this->groq($prompt);
|
||
case 'deepseek': return $this->deepseek($prompt);
|
||
default: return ['success' => false, 'error' => 'Unknown provider'];
|
||
}
|
||
}
|
||
private function claude($prompt) {
|
||
$ch = curl_init('https://api.anthropic.com/v1/messages');
|
||
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'x-api-key: ' . $this->apiKey, 'anthropic-version: 2023-06-01'], CURLOPT_POSTFIELDS => json_encode(['model' => $this->model ?: 'claude-3-haiku-20240307', 'max_tokens' => 1024, 'messages' => [['role' => 'user', 'content' => $prompt]]])]);
|
||
$r = json_decode(curl_exec($ch), true); curl_close($ch);
|
||
return isset($r['content'][0]['text']) ? ['success' => true, 'text' => $r['content'][0]['text']] : ['success' => false, 'error' => $r['error']['message'] ?? 'Error'];
|
||
}
|
||
private function openai($prompt) {
|
||
$ch = curl_init('https://api.openai.com/v1/chat/completions');
|
||
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'Authorization: Bearer ' . $this->apiKey], CURLOPT_POSTFIELDS => json_encode(['model' => $this->model ?: 'gpt-3.5-turbo', 'messages' => [['role' => 'user', 'content' => $prompt]], 'max_tokens' => 1024])]);
|
||
$r = json_decode(curl_exec($ch), true); curl_close($ch);
|
||
return isset($r['choices'][0]['message']['content']) ? ['success' => true, 'text' => $r['choices'][0]['message']['content']] : ['success' => false, 'error' => $r['error']['message'] ?? 'Error'];
|
||
}
|
||
private function groq($prompt) {
|
||
$ch = curl_init('https://api.groq.com/openai/v1/chat/completions');
|
||
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'Authorization: Bearer ' . $this->apiKey], CURLOPT_POSTFIELDS => json_encode(['model' => $this->model ?: 'llama3-8b-8192', 'messages' => [['role' => 'user', 'content' => $prompt]], 'max_tokens' => 1024])]);
|
||
$r = json_decode(curl_exec($ch), true); curl_close($ch);
|
||
return isset($r['choices'][0]['message']['content']) ? ['success' => true, 'text' => $r['choices'][0]['message']['content']] : ['success' => false, 'error' => $r['error']['message'] ?? 'Error'];
|
||
}
|
||
private function deepseek($prompt) {
|
||
$ch = curl_init('https://api.deepseek.com/v1/chat/completions');
|
||
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'Authorization: Bearer ' . $this->apiKey], CURLOPT_POSTFIELDS => json_encode(['model' => $this->model ?: 'deepseek-chat', 'messages' => [['role' => 'user', 'content' => $prompt]], 'max_tokens' => 1024])]);
|
||
$r = json_decode(curl_exec($ch), true); curl_close($ch);
|
||
return isset($r['choices'][0]['message']['content']) ? ['success' => true, 'text' => $r['choices'][0]['message']['content']] : ['success' => false, 'error' => $r['error']['message'] ?? 'Error'];
|
||
}
|
||
}
|
||
|
||
class InboxChecker {
|
||
public static function check($acc) {
|
||
$mailbox = "{" . $acc['imap_host'] . ":" . $acc['imap_port'] . "/imap/ssl/novalidate-cert}";
|
||
$result = ['success' => false, 'inbox' => 0, 'spam' => 0, 'recent' => []];
|
||
$imap = @imap_open($mailbox . "INBOX", $acc['email'], $acc['password'], 0, 1);
|
||
if (!$imap) return ['success' => false, 'error' => imap_last_error()];
|
||
$info = imap_check($imap);
|
||
$result['inbox'] = $info->Nmsgs ?? 0;
|
||
if ($result['inbox'] > 0) {
|
||
$start = max(1, $result['inbox'] - 10);
|
||
$emails = imap_fetch_overview($imap, "$start:{$result['inbox']}");
|
||
foreach ($emails as $e) $result['recent'][] = ['subject' => imap_utf8($e->subject ?? ''), 'from' => imap_utf8($e->from ?? ''), 'date' => $e->date ?? ''];
|
||
}
|
||
imap_close($imap);
|
||
$imapSpam = @imap_open($mailbox . ($acc['spam_folder'] ?: 'Junk'), $acc['email'], $acc['password'], 0, 1);
|
||
if ($imapSpam) { $spamInfo = imap_check($imapSpam); $result['spam'] = $spamInfo->Nmsgs ?? 0; imap_close($imapSpam); }
|
||
$result['success'] = true;
|
||
return $result;
|
||
}
|
||
}
|
||
|
||
class WevadsAPI {
|
||
private $baseUrl, $cookie;
|
||
public function __construct() {
|
||
$pdo = getDB();
|
||
$config = $pdo->query("SELECT * FROM admin.wevads_config WHERE is_active = true LIMIT 1")->fetch(PDO::FETCH_ASSOC);
|
||
if ($config) { $this->baseUrl = $config['api_url']; $this->cookie = $config['auth_cookie']; }
|
||
}
|
||
public function request($endpoint, $method = 'GET', $data = null) {
|
||
$ch = curl_init($this->baseUrl . $endpoint);
|
||
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_COOKIE => $this->cookie, CURLOPT_CUSTOMREQUEST => $method, CURLOPT_TIMEOUT => 30]);
|
||
if ($data) { curl_setopt($ch, CURLOPT_POSTFIELDS, is_array($data) ? http_build_query($data) : $data); }
|
||
$response = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
|
||
return ['code' => $code, 'data' => json_decode($response, true) ?: $response];
|
||
}
|
||
public function getServers() { return $this->request('/api/servers'); }
|
||
public function getVMTAs() { return $this->request('/api/vmtas'); }
|
||
public function sendTest($params) { return $this->request('/api/send/test', 'POST', $params); }
|
||
}
|
||
|
||
if (isset($_GET['action']) || isset($_POST['action'])) {
|
||
header('Content-Type: application/json');
|
||
ensureTables();
|
||
$action = $_GET['action'] ?? $_POST['action'];
|
||
$pdo = getDB();
|
||
try {
|
||
switch ($action) {
|
||
case 'stats':
|
||
$stats = [
|
||
'campaigns' => ['total' => $pdo->query("SELECT COUNT(*) FROM admin.campaigns")->fetchColumn(), 'running' => $pdo->query("SELECT COUNT(*) FROM admin.campaigns WHERE status = 'running'")->fetchColumn(), 'completed' => $pdo->query("SELECT COUNT(*) FROM admin.campaigns WHERE status = 'completed'")->fetchColumn()],
|
||
'warmup' => ['accounts' => $pdo->query("SELECT COUNT(*) FROM admin.warmup_accounts")->fetchColumn(), 'active' => $pdo->query("SELECT COUNT(*) FROM admin.warmup_accounts WHERE status = 'active'")->fetchColumn(), 'sent_today' => $pdo->query("SELECT COALESCE(SUM(emails_sent_today), 0) FROM admin.warmup_accounts")->fetchColumn()],
|
||
'pmta' => ['servers' => $pdo->query("SELECT COUNT(*) FROM admin.pmta_servers")->fetchColumn(), 'queued' => $pdo->query("SELECT COALESCE(SUM(queued_emails), 0) FROM admin.pmta_servers")->fetchColumn()],
|
||
'cloud' => ['huawei' => $pdo->query("SELECT COUNT(*) FROM admin.huawei_accounts")->fetchColumn(), 'scaleway' => $pdo->query("SELECT COUNT(*) FROM admin.scaleway_accounts")->fetchColumn()],
|
||
'dns' => ['cloudflare' => $pdo->query("SELECT COUNT(*) FROM admin.cloudflare_zones")->fetchColumn(), 'freedns' => $pdo->query("SELECT COUNT(*) FROM admin.freedns_domains")->fetchColumn()],
|
||
'alerts' => $pdo->query("SELECT COUNT(*) FROM admin.monitoring_alerts WHERE acknowledged = false")->fetchColumn()
|
||
];
|
||
echo json_encode(['success' => true, 'stats' => $stats]);
|
||
break;
|
||
case 'tg_get': echo json_encode(['success' => true, 'config' => $pdo->query("SELECT bot_token, chat_id FROM admin.telegram_config LIMIT 1")->fetch(PDO::FETCH_ASSOC)]); break;
|
||
case 'tg_save': $pdo->exec("DELETE FROM admin.telegram_config"); $stmt = $pdo->prepare("INSERT INTO admin.telegram_config (bot_token, chat_id) VALUES (?, ?)"); $stmt->execute([$_POST['bot_token'], $_POST['chat_id']]); echo json_encode(['success' => true]); break;
|
||
case 'tg_test': $bot = new TelegramBot(); $r = $bot->alert('Test Alert', 'WEVAL SEND Dashboard is working!', 'success'); echo json_encode(['success' => isset($r['ok']) && $r['ok']]); break;
|
||
case 'tg_send': $bot = new TelegramBot(); $r = $bot->send($_POST['message']); echo json_encode(['success' => isset($r['ok']) && $r['ok']]); break;
|
||
case 'ai_get': echo json_encode(['success' => true, 'config' => $pdo->query("SELECT provider, model FROM admin.ai_config LIMIT 1")->fetch(PDO::FETCH_ASSOC)]); break;
|
||
case 'ai_save': $pdo->exec("DELETE FROM admin.ai_config"); $stmt = $pdo->prepare("INSERT INTO admin.ai_config (provider, api_key, model) VALUES (?, ?, ?)"); $stmt->execute([$_POST['provider'], $_POST['api_key'], $_POST['model']]); echo json_encode(['success' => true]); break;
|
||
case 'ai_generate': $ai = new AIHelper(); echo json_encode($ai->generate($_POST['prompt'])); break;
|
||
case 'ai_email': $ai = new AIHelper(); $prompt = "Generate email marketing subject line and from name for:\nOffer: {$_POST['offer']}\nSponsor: {$_POST['sponsor']}\n\nFormat:\nSUBJECT: [subject]\nFROM: [from name]"; echo json_encode($ai->generate($prompt)); break;
|
||
case 'imap_list': echo json_encode(['success' => true, 'checkers' => $pdo->query("SELECT id, name, email, imap_host, last_check, inbox_count, spam_count FROM admin.imap_checkers ORDER BY id")->fetchAll(PDO::FETCH_ASSOC)]); break;
|
||
case 'imap_add': $stmt = $pdo->prepare("INSERT INTO admin.imap_checkers (name, email, password, imap_host, imap_port, spam_folder) VALUES (?, ?, ?, ?, ?, ?)"); $stmt->execute([$_POST['name'], $_POST['email'], $_POST['password'], $_POST['imap_host'], $_POST['imap_port'] ?? 993, $_POST['spam_folder'] ?? 'Junk']); echo json_encode(['success' => true]); break;
|
||
case 'imap_check': $stmt = $pdo->prepare("SELECT * FROM admin.imap_checkers WHERE id = ?"); $stmt->execute([$_POST['id']]); $acc = $stmt->fetch(PDO::FETCH_ASSOC); $r = InboxChecker::check($acc); if ($r['success']) $pdo->exec("UPDATE admin.imap_checkers SET inbox_count = {$r['inbox']}, spam_count = {$r['spam']}, last_check = NOW() WHERE id = {$acc['id']}"); echo json_encode($r); break;
|
||
case 'imap_delete': $pdo->exec("DELETE FROM admin.imap_checkers WHERE id = " . intval($_POST['id'])); echo json_encode(['success' => true]); break;
|
||
case 'wevads_get': echo json_encode(['success' => true, 'config' => $pdo->query("SELECT api_url FROM admin.wevads_config LIMIT 1")->fetch(PDO::FETCH_ASSOC)]); break;
|
||
case 'wevads_save': $pdo->exec("DELETE FROM admin.wevads_config"); $stmt = $pdo->prepare("INSERT INTO admin.wevads_config (api_url, username, password) VALUES (?, ?, ?)"); $stmt->execute([$_POST['api_url'], $_POST['username'], $_POST['password']]); echo json_encode(['success' => true]); break;
|
||
case 'activity': $activity = $pdo->query("SELECT 'campaign' as type, name as title, status, created_at FROM admin.campaigns UNION ALL SELECT 'alert', title, severity, created_at FROM admin.monitoring_alerts ORDER BY created_at DESC LIMIT 15")->fetchAll(PDO::FETCH_ASSOC); echo json_encode(['success' => true, 'activity' => $activity]); break;
|
||
default: echo json_encode(['success' => false, 'error' => 'Unknown action']);
|
||
}
|
||
} catch (Exception $e) { echo json_encode(['success' => false, 'error' => $e->getMessage()]); }
|
||
exit;
|
||
}
|
||
ensureTables();
|
||
?>
|
||
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>WEVAL SEND - Central Dashboard</title>
|
||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||
<style>
|
||
:root{--bg:#0a0a0f;--bg2:#12121a;--bg3:#1a1a25;--primary:#6366f1;--success:#10b981;--warning:#f59e0b;--danger:#ef4444;--text:#e2e8f0;--text2:#94a3b8;--border:#2a2a3a}
|
||
*{margin:0;padding:0;box-sizing:border-box}body{font-family:'Inter',sans-serif;background:var(--bg);color:var(--text);min-height:100vh}
|
||
.header{background:linear-gradient(135deg,#6366f1,#8b5cf6);padding:1.25rem 2rem;display:flex;justify-content:space-between;align-items:center}
|
||
.header h1{font-size:1.4rem;color:white;display:flex;align-items:center;gap:.5rem}
|
||
.header-links{display:flex;gap:.5rem}.header-links a{padding:.4rem .8rem;background:rgba(255,255,255,.15);border-radius:6px;color:white;text-decoration:none;font-size:.75rem}
|
||
.header-links a:hover{background:rgba(255,255,255,.25)}
|
||
.container{max-width:1600px;margin:0 auto;padding:1.5rem}
|
||
.grid-4{display:grid;grid-template-columns:repeat(4,1fr);gap:1rem;margin-bottom:1.5rem}
|
||
.grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:1rem}
|
||
.grid-2{display:grid;grid-template-columns:1fr 1fr;gap:1rem}
|
||
.stat{background:var(--bg2);border:1px solid var(--border);border-radius:10px;padding:1rem}
|
||
.stat h4{color:var(--text2);font-size:.7rem;margin-bottom:.5rem;display:flex;align-items:center;gap:.3rem}
|
||
.stat .main{font-size:1.8rem;font-weight:700}.stat .sub{font-size:.75rem;color:var(--text2)}
|
||
.stat.purple .main{color:#8b5cf6}.stat.orange .main{color:#ff6b35}.stat.green .main{color:#10b981}.stat.blue .main{color:#3b82f6}
|
||
.card{background:var(--bg2);border:1px solid var(--border);border-radius:10px;padding:1.25rem;margin-bottom:1rem}
|
||
.card h3{margin-bottom:1rem;font-size:.95rem;display:flex;align-items:center;gap:.5rem}
|
||
.form-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:.75rem;margin-bottom:.75rem}
|
||
.form-group{display:flex;flex-direction:column;gap:.2rem}
|
||
.form-group label{font-size:.65rem;color:var(--text2)}
|
||
.form-group input,.form-group select,.form-group textarea{padding:.45rem .6rem;background:var(--bg3);border:1px solid var(--border);border-radius:5px;color:var(--text);font-size:.8rem}
|
||
.form-group textarea{min-height:70px}
|
||
.btn{padding:.45rem .9rem;border:none;border-radius:5px;font-weight:600;cursor:pointer;font-size:.75rem;display:inline-flex;align-items:center;gap:.3rem}
|
||
.btn:hover{opacity:.9}.btn-primary{background:var(--primary);color:white}.btn-success{background:var(--success);color:white}
|
||
.btn-danger{background:var(--danger);color:white}.btn-telegram{background:#0088cc;color:white}.btn-ai{background:linear-gradient(135deg,#8b5cf6,#a855f7);color:white}
|
||
.btn-sm{padding:.3rem .5rem;font-size:.7rem}
|
||
.modules{display:grid;grid-template-columns:repeat(6,1fr);gap:.75rem;margin-bottom:1.5rem}
|
||
.module{background:var(--bg2);border:1px solid var(--border);border-radius:8px;padding:1rem;text-align:center;text-decoration:none;color:var(--text);transition:all .2s}
|
||
.module:hover{transform:translateY(-2px);border-color:var(--primary)}
|
||
.module i{font-size:1.5rem;margin-bottom:.5rem;display:block}
|
||
.module span{font-size:.75rem}
|
||
.module.m1 i{color:#8b5cf6}.module.m2 i{color:#ff6b35}.module.m3 i{color:#10b981}.module.m4 i{color:#3b82f6}.module.m5 i{color:#f59e0b}.module.m6 i{color:#ec4899}
|
||
table{width:100%;border-collapse:collapse;font-size:.75rem}
|
||
th,td{padding:.4rem .5rem;text-align:left;border-bottom:1px solid var(--border)}
|
||
th{color:var(--text2);font-size:.65rem}
|
||
.badge{padding:.15rem .4rem;border-radius:8px;font-size:.6rem;font-weight:600}
|
||
.badge-running{background:rgba(99,102,241,.15);color:var(--primary)}.badge-completed{background:rgba(16,185,129,.15);color:var(--success)}
|
||
.tabs{display:flex;gap:.4rem;margin-bottom:.75rem}.tab{padding:.4rem .8rem;background:var(--bg3);border-radius:5px;cursor:pointer;font-size:.75rem}.tab.active{background:var(--primary);color:white}
|
||
.activity-item{display:flex;align-items:center;gap:.6rem;padding:.5rem;background:var(--bg3);border-radius:5px;margin-bottom:.4rem;font-size:.75rem}
|
||
.activity-item i{width:26px;height:26px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.7rem}
|
||
.activity-item.campaign i{background:rgba(139,92,246,.15);color:#8b5cf6}.activity-item.alert i{background:rgba(239,68,68,.15);color:#ef4444}
|
||
.ai-out{background:var(--bg3);border-radius:6px;padding:.75rem;margin-top:.75rem;white-space:pre-wrap;font-family:monospace;font-size:.75rem;max-height:200px;overflow-y:auto}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="header">
|
||
<h1><i class="fas fa-rocket"></i> WEVAL SEND</h1>
|
||
<div class="header-links">
|
||
<a href="http://89.167.40.150:5678" target="_blank"><i class="fas fa-project-diagram"></i> n8n</a>
|
||
<a href="campaign-orchestrator.php"><i class="fas fa-play"></i> Orchestrator</a>
|
||
<a href="automation-hub.php"><i class="fas fa-robot"></i> Automation</a>
|
||
</div>
|
||
</div>
|
||
<div class="container">
|
||
<div class="grid-4">
|
||
<div class="stat purple"><h4><i class="fas fa-rocket"></i> Campaigns</h4><div class="main" id="sCamp">0</div><div class="sub"><span id="sCampRun">0</span> running</div></div>
|
||
<div class="stat orange"><h4><i class="fas fa-fire"></i> Warmup</h4><div class="main" id="sWarm">0</div><div class="sub"><span id="sWarmSent">0</span> sent today</div></div>
|
||
<div class="stat green"><h4><i class="fas fa-server"></i> PMTA</h4><div class="main" id="sPmta">0</div><div class="sub"><span id="sPmtaQ">0</span> queued</div></div>
|
||
<div class="stat blue"><h4><i class="fas fa-cloud"></i> Cloud</h4><div class="main" id="sCloud">0</div><div class="sub">Huawei + Scaleway</div></div>
|
||
</div>
|
||
<div class="modules">
|
||
<a href="campaign-orchestrator.php" class="module m1"><i class="fas fa-rocket"></i><span>Orchestrator</span></a>
|
||
<a href="warmup-system.php" class="module m2"><i class="fas fa-fire"></i><span>Warmup</span></a>
|
||
<a href="automation-hub.php" class="module m3"><i class="fas fa-robot"></i><span>Automation</span></a>
|
||
<a href="cloud-manager.php" class="module m4"><i class="fas fa-cloud"></i><span>Cloud</span></a>
|
||
<a href="dns-manager.php" class="module m5"><i class="fas fa-globe"></i><span>DNS</span></a>
|
||
<a href="import-system.php" class="module m6"><i class="fas fa-upload"></i><span>Import</span></a>
|
||
</div>
|
||
<div class="grid-2">
|
||
<div>
|
||
<div class="card"><h3><i class="fab fa-telegram" style="color:#0088cc"></i> Telegram</h3>
|
||
<div class="form-row"><div class="form-group"><label>Bot Token</label><input type="text" id="tgToken" placeholder="123456:ABC..."></div><div class="form-group"><label>Chat ID</label><input type="text" id="tgChat" placeholder="-100..."></div></div>
|
||
<div style="display:flex;gap:.5rem"><button class="btn btn-telegram" onclick="saveTg()"><i class="fas fa-save"></i> Save</button><button class="btn btn-telegram" onclick="testTg()"><i class="fas fa-paper-plane"></i> Test</button></div></div>
|
||
<div class="card"><h3><i class="fas fa-brain" style="color:#8b5cf6"></i> AI Integration</h3>
|
||
<div class="form-row"><div class="form-group"><label>Provider</label><select id="aiProv"><option value="anthropic">Claude</option><option value="openai">OpenAI</option><option value="groq">Groq</option><option value="deepseek">DeepSeek</option></select></div><div class="form-group"><label>API Key</label><input type="password" id="aiKey" placeholder="sk-..."></div><div class="form-group"><label>Model</label><input type="text" id="aiModel" placeholder="claude-3-haiku"></div></div>
|
||
<button class="btn btn-ai" onclick="saveAi()"><i class="fas fa-save"></i> Save</button>
|
||
<div style="margin-top:1rem"><div class="form-row"><div class="form-group"><input type="text" id="aiOffer" placeholder="Offer"></div><div class="form-group"><input type="text" id="aiSponsor" placeholder="Sponsor"></div><div class="form-group"><button class="btn btn-ai" onclick="genEmail()"><i class="fas fa-magic"></i> Generate</button></div></div><div class="ai-out" id="aiOut" style="display:none"></div></div></div>
|
||
<div class="card"><h3><i class="fas fa-link" style="color:#3b82f6"></i> WEVAL API</h3>
|
||
<div class="form-row"><div class="form-group"><label>API URL</label><input type="text" id="wevUrl" value="http://api.weval.digital:58081"></div><div class="form-group"><label>Username</label><input type="text" id="wevUser"></div><div class="form-group"><label>Password</label><input type="password" id="wevPass"></div></div>
|
||
<button class="btn btn-primary" onclick="saveWev()"><i class="fas fa-save"></i> Save</button></div>
|
||
</div>
|
||
<div>
|
||
<div class="card"><h3><i class="fas fa-inbox" style="color:#10b981"></i> Inbox Checkers</h3>
|
||
<div class="tabs"><div class="tab active" onclick="showImap('list')">Accounts</div><div class="tab" onclick="showImap('add')">Add</div></div>
|
||
<div id="imapList"><table><thead><tr><th>Name</th><th>Email</th><th>Inbox</th><th>Spam</th><th>Actions</th></tr></thead><tbody id="imapTbl"></tbody></table></div>
|
||
<div id="imapAdd" style="display:none">
|
||
<div class="form-row"><div class="form-group"><label>Name</label><input type="text" id="imName"></div><div class="form-group"><label>Email</label><input type="email" id="imEmail"></div></div>
|
||
<div class="form-row"><div class="form-group"><label>Password</label><input type="password" id="imPass"></div><div class="form-group"><label>IMAP Host</label><input type="text" id="imHost"></div></div>
|
||
<div class="form-row"><div class="form-group"><label>Port</label><input type="number" id="imPort" value="993"></div><div class="form-group"><label>Spam Folder</label><input type="text" id="imSpam" value="Junk"></div></div>
|
||
<button class="btn btn-success" onclick="addImap()"><i class="fas fa-plus"></i> Add</button></div></div>
|
||
<div class="card"><h3><i class="fas fa-history"></i> Recent Activity</h3><div id="actList"></div></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<script>
|
||
function load(){fetch('?action=stats').then(r=>r.json()).then(d=>{if(d.success){const s=d.stats;document.getElementById('sCamp').textContent=s.campaigns.total;document.getElementById('sCampRun').textContent=s.campaigns.running;document.getElementById('sWarm').textContent=s.warmup.accounts;document.getElementById('sWarmSent').textContent=s.warmup.sent_today;document.getElementById('sPmta').textContent=s.pmta.servers;document.getElementById('sPmtaQ').textContent=Number(s.pmta.queued).toLocaleString();document.getElementById('sCloud').textContent=Number(s.cloud.huawei)+Number(s.cloud.scaleway);}});}
|
||
function loadTg(){fetch('?action=tg_get').then(r=>r.json()).then(d=>{if(d.success&&d.config){document.getElementById('tgToken').value=d.config.bot_token||'';document.getElementById('tgChat').value=d.config.chat_id||'';}});}
|
||
function saveTg(){const fd=new FormData();fd.append('action','tg_save');fd.append('bot_token',document.getElementById('tgToken').value);fd.append('chat_id',document.getElementById('tgChat').value);fetch('',{method:'POST',body:fd}).then(r=>r.json()).then(d=>alert(d.success?'Saved!':'Error'));}
|
||
function testTg(){fetch('',{method:'POST',body:new URLSearchParams({action:'tg_test'})}).then(r=>r.json()).then(d=>alert(d.success?'✅ Sent!':'❌ Failed'));}
|
||
function loadAi(){fetch('?action=ai_get').then(r=>r.json()).then(d=>{if(d.success&&d.config){document.getElementById('aiProv').value=d.config.provider||'anthropic';document.getElementById('aiModel').value=d.config.model||'';}});}
|
||
function saveAi(){const fd=new FormData();fd.append('action','ai_save');fd.append('provider',document.getElementById('aiProv').value);fd.append('api_key',document.getElementById('aiKey').value);fd.append('model',document.getElementById('aiModel').value);fetch('',{method:'POST',body:fd}).then(r=>r.json()).then(d=>alert(d.success?'Saved!':'Error'));}
|
||
function genEmail(){const fd=new FormData();fd.append('action','ai_email');fd.append('offer',document.getElementById('aiOffer').value);fd.append('sponsor',document.getElementById('aiSponsor').value);document.getElementById('aiOut').style.display='block';document.getElementById('aiOut').textContent='Generating...';fetch('',{method:'POST',body:fd}).then(r=>r.json()).then(d=>{document.getElementById('aiOut').textContent=d.success?d.text:'Error: '+d.error;});}
|
||
function loadWev(){fetch('?action=wevads_get').then(r=>r.json()).then(d=>{if(d.success&&d.config)document.getElementById('wevUrl').value=d.config.api_url||'';});}
|
||
function saveWev(){const fd=new FormData();fd.append('action','wevads_save');fd.append('api_url',document.getElementById('wevUrl').value);fd.append('username',document.getElementById('wevUser').value);fd.append('password',document.getElementById('wevPass').value);fetch('',{method:'POST',body:fd}).then(r=>r.json()).then(d=>alert(d.success?'Saved!':'Error'));}
|
||
function loadImap(){fetch('?action=imap_list').then(r=>r.json()).then(d=>{if(d.success){document.getElementById('imapTbl').innerHTML=d.checkers.length?d.checkers.map(c=>'<tr><td>'+c.name+'</td><td>'+c.email+'</td><td style="color:var(--success)">'+c.inbox_count+'</td><td style="color:var(--danger)">'+c.spam_count+'</td><td><button class="btn btn-success btn-sm" onclick="checkImap('+c.id+')"><i class="fas fa-sync"></i></button> <button class="btn btn-danger btn-sm" onclick="delImap('+c.id+')"><i class="fas fa-trash"></i></button></td></tr>').join(''):'<tr><td colspan="5" style="text-align:center;color:var(--text2)">No accounts</td></tr>';}});}
|
||
function showImap(t){document.querySelectorAll('.tabs .tab').forEach(x=>x.classList.remove('active'));event.target.classList.add('active');document.getElementById('imapList').style.display=t==='list'?'block':'none';document.getElementById('imapAdd').style.display=t==='add'?'block':'none';}
|
||
function addImap(){const fd=new FormData();fd.append('action','imap_add');fd.append('name',document.getElementById('imName').value);fd.append('email',document.getElementById('imEmail').value);fd.append('password',document.getElementById('imPass').value);fd.append('imap_host',document.getElementById('imHost').value);fd.append('imap_port',document.getElementById('imPort').value);fd.append('spam_folder',document.getElementById('imSpam').value);fetch('',{method:'POST',body:fd}).then(()=>{loadImap();showImap('list');});}
|
||
function checkImap(id){fetch('',{method:'POST',body:new URLSearchParams({action:'imap_check',id:id})}).then(r=>r.json()).then(d=>{alert(d.success?'✅ Inbox: '+d.inbox+' | Spam: '+d.spam:'❌ '+d.error);loadImap();});}
|
||
function delImap(id){if(!confirm('Delete?'))return;fetch('',{method:'POST',body:new URLSearchParams({action:'imap_delete',id:id})}).then(()=>loadImap());}
|
||
function loadAct(){fetch('?action=activity').then(r=>r.json()).then(d=>{if(d.success){document.getElementById('actList').innerHTML=d.activity.length?d.activity.slice(0,10).map(a=>'<div class="activity-item '+a.type+'"><i class="fas fa-'+(a.type==='campaign'?'rocket':'bell')+'"></i><div style="flex:1"><div>'+a.title+'</div><div style="font-size:.65rem;color:var(--text2)">'+new Date(a.created_at).toLocaleString()+'</div></div><span class="badge badge-'+a.status+'">'+a.status+'</span></div>').join(''):'<div style="text-align:center;color:var(--text2);padding:1rem">No activity</div>';}});}
|
||
load();loadTg();loadAi();loadWev();loadImap();loadAct();setInterval(load,30000);
|
||
</script>
|
||
</body>
|
||
</html>
|