Files
wevads-platform/scripts/api_intelligence-api.php
2026-02-26 04:53:11 +01:00

880 lines
37 KiB
PHP
Executable File

<?php
/**
* INTELLIGENCE API
* - Complete ISP Knowledge
* - Economic Equation
* - Anti-spam Watch
* - Advanced Learning
* - Smart Recommendations
*/
header('Content-Type: application/json');
$db = new PDO("pgsql:host=127.0.0.1;dbname=adx_system", "admin", "admin123");
// ==================== ISP COMPLETE DATABASE ====================
$ISP_DATABASE = [
// ============ MICROSOFT (Hotmail/Outlook) ============
'hotmail' => [
'names' => ['hotmail.com', 'outlook.com', 'live.com', 'msn.com'],
'filters' => [
['name' => 'SmartScreen', 'type' => 'reputation', 'severity' => 9, 'bypass' => 'Engagement-based warmup, clean IP history'],
['name' => 'Sender Reputation', 'type' => 'reputation', 'severity' => 8, 'bypass' => 'Consistent sending patterns, low complaints'],
['name' => 'Content Filtering', 'type' => 'content', 'severity' => 6, 'bypass' => 'Avoid spam words, balanced text/image ratio'],
['name' => 'Authentication Check', 'type' => 'authentication', 'severity' => 10, 'bypass' => 'SPF, DKIM, DMARC mandatory'],
],
'optimal' => [
'volume_per_hour' => 2000,
'volume_per_day' => 30000,
'warmup_days' => 21,
'best_hours' => [9, 10, 11, 14, 15, 16],
'worst_hours' => [0, 1, 2, 3, 4, 5, 22, 23],
'best_days' => ['tue', 'wed', 'thu'],
],
'requirements' => [
'dkim' => true, 'spf' => true, 'dmarc' => true, 'ptr' => true,
'list_unsubscribe' => true, 'one_click_unsubscribe' => true,
],
'weights' => ['engagement' => 0.45, 'complaints' => 0.30, 'bounces' => 0.15, 'traps' => 0.10],
'difficulty' => 8,
'countries' => ['US' => 'EST', 'UK' => 'GMT', 'DE' => 'CET', 'FR' => 'CET', 'CA' => 'EST'],
],
// ============ GOOGLE (Gmail) ============
'gmail' => [
'names' => ['gmail.com', 'googlemail.com'],
'filters' => [
['name' => 'ML Spam Filter', 'type' => 'ml', 'severity' => 10, 'bypass' => 'High engagement, personalization, legitimate content'],
['name' => 'Promotions Tab', 'type' => 'categorization', 'severity' => 5, 'bypass' => 'Personal tone, minimal marketing language'],
['name' => 'Postmaster Reputation', 'type' => 'reputation', 'severity' => 9, 'bypass' => 'Monitor via Google Postmaster Tools'],
['name' => 'User Signals', 'type' => 'engagement', 'severity' => 8, 'bypass' => 'High open rates, replies, not-spam marks'],
],
'optimal' => [
'volume_per_hour' => 3000,
'volume_per_day' => 50000,
'warmup_days' => 14,
'best_hours' => [8, 9, 10, 13, 14, 19, 20],
'worst_hours' => [0, 1, 2, 3, 4, 5],
'best_days' => ['tue', 'wed', 'thu'],
],
'requirements' => [
'dkim' => true, 'spf' => true, 'dmarc' => true, 'ptr' => true,
'list_unsubscribe' => true, 'one_click_unsubscribe' => true,
'arc' => false, 'bimi' => false,
],
'weights' => ['engagement' => 0.50, 'complaints' => 0.25, 'bounces' => 0.15, 'traps' => 0.10],
'difficulty' => 7,
'countries' => ['US' => 'PST', 'UK' => 'GMT', 'DE' => 'CET', 'FR' => 'CET'],
],
// ============ YAHOO/AOL ============
'yahoo' => [
'names' => ['yahoo.com', 'yahoo.fr', 'yahoo.co.uk', 'ymail.com', 'rocketmail.com'],
'filters' => [
['name' => 'SpamGuard', 'type' => 'reputation', 'severity' => 7, 'bypass' => 'Slow warmup, engagement focus'],
['name' => 'CFL (Complaint Feedback Loop)', 'type' => 'complaints', 'severity' => 9, 'bypass' => 'Process CFL, remove complainers immediately'],
['name' => 'Authentication', 'type' => 'authentication', 'severity' => 8, 'bypass' => 'Strict DKIM alignment'],
],
'optimal' => [
'volume_per_hour' => 2500,
'volume_per_day' => 40000,
'warmup_days' => 14,
'best_hours' => [9, 10, 11, 14, 15, 18, 19],
'worst_hours' => [0, 1, 2, 3, 4, 5],
'best_days' => ['mon', 'tue', 'wed', 'thu'],
],
'requirements' => [
'dkim' => true, 'spf' => true, 'dmarc' => true, 'ptr' => true,
'list_unsubscribe' => true,
],
'weights' => ['engagement' => 0.35, 'complaints' => 0.40, 'bounces' => 0.15, 'traps' => 0.10],
'difficulty' => 6,
'countries' => ['US' => 'PST', 'UK' => 'GMT', 'FR' => 'CET'],
],
'aol' => [
'names' => ['aol.com', 'aim.com'],
'filters' => [
['name' => 'Same as Yahoo', 'type' => 'reputation', 'severity' => 7, 'bypass' => 'Same rules as Yahoo (Verizon Media)'],
],
'optimal' => [
'volume_per_hour' => 2000,
'volume_per_day' => 30000,
'warmup_days' => 14,
'best_hours' => [9, 10, 11, 14, 15],
'worst_hours' => [0, 1, 2, 3, 4, 5],
'best_days' => ['tue', 'wed', 'thu'],
],
'requirements' => ['dkim' => true, 'spf' => true, 'dmarc' => true],
'weights' => ['engagement' => 0.35, 'complaints' => 0.40, 'bounces' => 0.15, 'traps' => 0.10],
'difficulty' => 5,
'countries' => ['US' => 'EST'],
],
// ============ GERMAN ISPs ============
'gmx' => [
'names' => ['gmx.de', 'gmx.net', 'gmx.at', 'gmx.ch'],
'filters' => [
['name' => 'UI Mail Filter', 'type' => 'content', 'severity' => 7, 'bypass' => 'German language, local sending time'],
['name' => 'Reputation System', 'type' => 'reputation', 'severity' => 8, 'bypass' => 'Consistent German IP, slow ramp'],
],
'optimal' => [
'volume_per_hour' => 1500,
'volume_per_day' => 20000,
'warmup_days' => 21,
'best_hours' => [8, 9, 10, 11, 14, 15, 16],
'worst_hours' => [0, 1, 2, 3, 4, 5, 6],
'best_days' => ['mon', 'tue', 'wed', 'thu'],
],
'requirements' => ['dkim' => true, 'spf' => true, 'dmarc' => true, 'german_ip' => true],
'weights' => ['engagement' => 0.30, 'complaints' => 0.35, 'bounces' => 0.25, 'traps' => 0.10],
'difficulty' => 8,
'countries' => ['DE' => 'CET', 'AT' => 'CET', 'CH' => 'CET'],
],
'webde' => [
'names' => ['web.de'],
'filters' => [
['name' => 'Same as GMX', 'type' => 'content', 'severity' => 7, 'bypass' => 'Same United Internet rules'],
],
'optimal' => [
'volume_per_hour' => 1500,
'volume_per_day' => 20000,
'warmup_days' => 21,
'best_hours' => [8, 9, 10, 11, 14, 15, 16],
'worst_hours' => [0, 1, 2, 3, 4, 5, 6],
'best_days' => ['mon', 'tue', 'wed', 'thu'],
],
'requirements' => ['dkim' => true, 'spf' => true, 'dmarc' => true],
'weights' => ['engagement' => 0.30, 'complaints' => 0.35, 'bounces' => 0.25, 'traps' => 0.10],
'difficulty' => 8,
'countries' => ['DE' => 'CET'],
],
'tonline' => [
'names' => ['t-online.de'],
'filters' => [
['name' => 'Deutsche Telekom Filter', 'type' => 'reputation', 'severity' => 9, 'bypass' => 'Very strict, German IP mandatory, slow warmup'],
['name' => 'Content Scan', 'type' => 'content', 'severity' => 8, 'bypass' => 'German content, no aggressive marketing'],
],
'optimal' => [
'volume_per_hour' => 1000,
'volume_per_day' => 15000,
'warmup_days' => 28,
'best_hours' => [9, 10, 11, 14, 15],
'worst_hours' => [0, 1, 2, 3, 4, 5, 6, 7, 22, 23],
'best_days' => ['tue', 'wed', 'thu'],
],
'requirements' => ['dkim' => true, 'spf' => true, 'dmarc' => true, 'german_ip' => true, 'reverse_dns' => true],
'weights' => ['engagement' => 0.25, 'complaints' => 0.40, 'bounces' => 0.25, 'traps' => 0.10],
'difficulty' => 9,
'countries' => ['DE' => 'CET'],
],
// ============ FRENCH ISPs ============
'orange_fr' => [
'names' => ['orange.fr', 'wanadoo.fr'],
'filters' => [
['name' => 'Orange Mail Filter', 'type' => 'reputation', 'severity' => 7, 'bypass' => 'French IP preferred, consistent sending'],
],
'optimal' => [
'volume_per_hour' => 2000,
'volume_per_day' => 25000,
'warmup_days' => 14,
'best_hours' => [9, 10, 11, 14, 15, 18, 19],
'worst_hours' => [0, 1, 2, 3, 4, 5, 6],
'best_days' => ['tue', 'wed', 'thu'],
],
'requirements' => ['dkim' => true, 'spf' => true],
'weights' => ['engagement' => 0.35, 'complaints' => 0.35, 'bounces' => 0.20, 'traps' => 0.10],
'difficulty' => 6,
'countries' => ['FR' => 'CET'],
],
'sfr' => [
'names' => ['sfr.fr', 'neuf.fr'],
'filters' => [
['name' => 'SFR AntiSpam', 'type' => 'content', 'severity' => 6, 'bypass' => 'Clean content, authentication'],
],
'optimal' => [
'volume_per_hour' => 2000,
'volume_per_day' => 25000,
'warmup_days' => 14,
'best_hours' => [9, 10, 11, 14, 15, 18, 19],
'worst_hours' => [0, 1, 2, 3, 4, 5, 6],
'best_days' => ['tue', 'wed', 'thu'],
],
'requirements' => ['dkim' => true, 'spf' => true],
'weights' => ['engagement' => 0.35, 'complaints' => 0.30, 'bounces' => 0.25, 'traps' => 0.10],
'difficulty' => 5,
'countries' => ['FR' => 'CET'],
],
'free_fr' => [
'names' => ['free.fr'],
'filters' => [
['name' => 'Free AntiSpam', 'type' => 'reputation', 'severity' => 6, 'bypass' => 'Standard best practices'],
],
'optimal' => [
'volume_per_hour' => 2000,
'volume_per_day' => 30000,
'warmup_days' => 10,
'best_hours' => [9, 10, 11, 14, 15, 18, 19, 20],
'worst_hours' => [0, 1, 2, 3, 4, 5],
'best_days' => ['mon', 'tue', 'wed', 'thu', 'fri'],
],
'requirements' => ['dkim' => true, 'spf' => true],
'weights' => ['engagement' => 0.40, 'complaints' => 0.30, 'bounces' => 0.20, 'traps' => 0.10],
'difficulty' => 4,
'countries' => ['FR' => 'CET'],
],
// ============ CANADIAN ISPs ============
'videotron' => [
'names' => ['videotron.ca', 'videotron.qc.ca'],
'filters' => [
['name' => 'Videotron Filter', 'type' => 'reputation', 'severity' => 6, 'bypass' => 'Canadian IP, bilingual content OK'],
],
'optimal' => [
'volume_per_hour' => 1500,
'volume_per_day' => 20000,
'warmup_days' => 14,
'best_hours' => [9, 10, 11, 14, 15, 19, 20],
'worst_hours' => [0, 1, 2, 3, 4, 5],
'best_days' => ['tue', 'wed', 'thu'],
],
'requirements' => ['dkim' => true, 'spf' => true, 'casl_compliant' => true],
'weights' => ['engagement' => 0.35, 'complaints' => 0.35, 'bounces' => 0.20, 'traps' => 0.10],
'difficulty' => 5,
'countries' => ['CA' => 'EST'],
],
// ============ APPLE ============
'icloud' => [
'names' => ['icloud.com', 'me.com', 'mac.com'],
'filters' => [
['name' => 'Apple Mail Privacy Protection', 'type' => 'privacy', 'severity' => 8, 'bypass' => 'Cannot track opens reliably since iOS 15'],
['name' => 'iCloud Filter', 'type' => 'reputation', 'severity' => 7, 'bypass' => 'Standard practices, engagement focus'],
],
'optimal' => [
'volume_per_hour' => 2000,
'volume_per_day' => 30000,
'warmup_days' => 14,
'best_hours' => [8, 9, 10, 12, 13, 18, 19, 20],
'worst_hours' => [0, 1, 2, 3, 4, 5],
'best_days' => ['tue', 'wed', 'thu'],
],
'requirements' => ['dkim' => true, 'spf' => true, 'dmarc' => true],
'weights' => ['engagement' => 0.30, 'complaints' => 0.40, 'bounces' => 0.20, 'traps' => 0.10],
'difficulty' => 6,
'countries' => ['US' => 'PST', 'UK' => 'GMT', 'DE' => 'CET', 'FR' => 'CET'],
'note' => 'Open tracking unreliable due to Mail Privacy Protection',
],
];
// ==================== ECONOMIC FORMULAS ====================
function calculateEconomicEquation($data) {
// Costs
$serverCost = $data['servers'] * $data['hours'] * 0.02; // €0.02/server/hour
$domainCost = $data['domains'] * 0.10; // €0.10/domain/day amortized
$ipCost = $data['ips'] * 0.05; // €0.05/IP/day
$listCost = $data['volume'] * 0.0001; // €0.0001/contact
$totalCost = $serverCost + $domainCost + $ipCost + $listCost;
// Revenue estimation
$inboxRate = $data['inbox_rate'] / 100;
$openRate = 0.15 * $inboxRate; // 15% of inbox
$clickRate = 0.03 * $inboxRate; // 3% of inbox
$conversionRate = 0.005 * $inboxRate; // 0.5% of inbox
$inboxCount = $data['volume'] * $inboxRate;
$openCount = $data['volume'] * $openRate;
$clickCount = $data['volume'] * $clickRate;
$conversionCount = $data['volume'] * $conversionRate;
$revenueGross = $conversionCount * ($data['payout'] ?? 5); // Default $5/conversion
$revenueNet = $revenueGross - $totalCost;
// Metrics
$costPerMail = $totalCost / max(1, $data['volume']);
$costPerInbox = $totalCost / max(1, $inboxCount);
$costPerClick = $totalCost / max(1, $clickCount);
$costPerConversion = $totalCost / max(1, $conversionCount);
$roi = $totalCost > 0 ? (($revenueNet / $totalCost) * 100) : 0;
$profitMargin = $revenueGross > 0 ? (($revenueNet / $revenueGross) * 100) : 0;
// Scores (1-100)
$profitabilityScore = min(100, max(0, 50 + $roi / 2));
$efficiencyScore = min(100, max(0, ($inboxRate * 100) * 0.5 + (100 - $costPerMail * 10000) * 0.5));
$sustainabilityScore = min(100, max(0, $data['stability_score'] ?? 50));
return [
'costs' => [
'server' => round($serverCost, 4),
'domain' => round($domainCost, 4),
'ip' => round($ipCost, 4),
'list' => round($listCost, 4),
'total' => round($totalCost, 4),
],
'metrics' => [
'inbox_count' => round($inboxCount),
'open_count' => round($openCount),
'click_count' => round($clickCount),
'conversion_count' => round($conversionCount),
],
'revenue' => [
'gross' => round($revenueGross, 2),
'net' => round($revenueNet, 2),
],
'unit_costs' => [
'per_mail' => round($costPerMail, 6),
'per_inbox' => round($costPerInbox, 6),
'per_click' => round($costPerClick, 4),
'per_conversion' => round($costPerConversion, 4),
],
'performance' => [
'roi_percent' => round($roi, 2),
'profit_margin' => round($profitMargin, 2),
'profitability_score' => round($profitabilityScore),
'efficiency_score' => round($efficiencyScore),
'sustainability_score' => round($sustainabilityScore),
],
'recommendation' => getRecommendation($roi, $inboxRate * 100, $data['stability_score'] ?? 50),
];
}
function getRecommendation($roi, $inboxRate, $stability) {
if ($roi > 200 && $inboxRate > 80 && $stability > 70) {
return ['action' => 'SCALE_UP', 'reason' => 'Excellent performance - increase volume'];
} elseif ($roi > 100 && $inboxRate > 70) {
return ['action' => 'MAINTAIN', 'reason' => 'Good performance - maintain current strategy'];
} elseif ($roi > 50 && $inboxRate > 60) {
return ['action' => 'OPTIMIZE', 'reason' => 'Acceptable performance - optimize for better results'];
} elseif ($inboxRate < 50) {
return ['action' => 'PAUSE', 'reason' => 'Poor inbox rate - investigate deliverability issues'];
} elseif ($roi < 0) {
return ['action' => 'STOP', 'reason' => 'Negative ROI - stop and reassess'];
} else {
return ['action' => 'ANALYZE', 'reason' => 'Mixed results - needs deeper analysis'];
}
}
// ==================== STABILITY EVALUATION ====================
function evaluateStability($inboxHistory) {
if (count($inboxHistory) < 3) {
return ['score' => 50, 'trend' => 'unknown', 'confidence' => 0.3];
}
$rates = array_column($inboxHistory, 'inbox_rate');
$avg = array_sum($rates) / count($rates);
// Variance
$variance = 0;
foreach ($rates as $r) {
$variance += pow($r - $avg, 2);
}
$variance /= count($rates);
$stdDev = sqrt($variance);
// Trend (linear regression)
$n = count($rates);
$sumX = $n * ($n - 1) / 2;
$sumY = array_sum($rates);
$sumXY = 0;
$sumX2 = 0;
for ($i = 0; $i < $n; $i++) {
$sumXY += $i * $rates[$i];
$sumX2 += $i * $i;
}
$slope = ($n * $sumXY - $sumX * $sumY) / ($n * $sumX2 - $sumX * $sumX);
// Stability score (lower variance = higher score)
$stabilityScore = max(0, min(100, 100 - ($stdDev * 2)));
// Trend classification
$trend = 'stable';
if ($slope > 2) $trend = 'improving';
elseif ($slope < -2) $trend = 'declining';
// Confidence based on sample size
$confidence = min(1, count($inboxHistory) / 10);
return [
'score' => round($stabilityScore),
'trend' => $trend,
'slope' => round($slope, 2),
'avg' => round($avg, 2),
'std_dev' => round($stdDev, 2),
'confidence' => round($confidence, 2),
'warning' => $trend == 'declining' ? 'Inbox rate declining - investigate' : null,
];
}
$action = $_POST['action'] ?? $_GET['action'] ?? '';
$response = ['success' => false];
switch ($action) {
// ==================== GET ISP INFO ====================
case 'get_isp_info':
$isp = $_GET['isp'] ?? '';
$country = $_GET['country'] ?? 'US';
if (isset($ISP_DATABASE[$isp])) {
$info = $ISP_DATABASE[$isp];
$info['timezone'] = $info['countries'][$country] ?? 'UTC';
$response = ['success' => true, 'isp' => $isp, 'info' => $info];
} else {
$response = ['success' => false, 'error' => 'Unknown ISP'];
}
break;
// ==================== GET ALL ISPs ====================
case 'list_all_isps':
$isps = [];
foreach ($ISP_DATABASE as $key => $data) {
$isps[] = [
'key' => $key,
'names' => $data['names'],
'difficulty' => $data['difficulty'],
'optimal_volume' => $data['optimal']['volume_per_day'],
'warmup_days' => $data['optimal']['warmup_days'],
'countries' => array_keys($data['countries']),
];
}
usort($isps, fn($a, $b) => $a['difficulty'] - $b['difficulty']);
$response = ['success' => true, 'isps' => $isps, 'count' => count($isps)];
break;
// ==================== CALCULATE ECONOMICS ====================
case 'calculate_economics':
$data = [
'volume' => intval($_POST['volume'] ?? 10000),
'servers' => intval($_POST['servers'] ?? 1),
'hours' => floatval($_POST['hours'] ?? 2),
'domains' => intval($_POST['domains'] ?? 1),
'ips' => intval($_POST['ips'] ?? 1),
'inbox_rate' => floatval($_POST['inbox_rate'] ?? 70),
'payout' => floatval($_POST['payout'] ?? 5),
'stability_score' => floatval($_POST['stability_score'] ?? 50),
];
$result = calculateEconomicEquation($data);
$response = ['success' => true, 'input' => $data, 'result' => $result];
break;
// ==================== EVALUATE STABILITY ====================
case 'evaluate_stability':
$config_id = intval($_GET['config_id'] ?? $_POST['config_id'] ?? 0);
if ($config_id) {
$history = $db->query("SELECT inbox_rate, check_time FROM admin.inbox_monitoring
WHERE send_config_id = $config_id ORDER BY check_time")->fetchAll(PDO::FETCH_ASSOC);
} else {
// Use provided data
$history = json_decode($_POST['history'] ?? '[]', true);
}
$stability = evaluateStability($history);
$response = ['success' => true, 'stability' => $stability, 'data_points' => count($history)];
break;
// ==================== WATCH ANTI-SPAM ====================
case 'antispam_watch':
$isp = $_GET['isp'] ?? '';
// Get recent send results for this ISP
$recentSends = $db->query("SELECT c.id, c.name, c.isp,
(SELECT AVG(inbox_rate) FROM admin.inbox_monitoring WHERE send_config_id = c.id) as avg_inbox,
(SELECT MIN(inbox_rate) FROM admin.inbox_monitoring WHERE send_config_id = c.id) as min_inbox,
(SELECT MAX(inbox_rate) FROM admin.inbox_monitoring WHERE send_config_id = c.id) as max_inbox,
c.created_at
FROM admin.send_configs c
WHERE c.isp = '$isp' AND c.status IN ('completed', 'running')
AND c.created_at > NOW() - INTERVAL '7 days'
ORDER BY c.created_at DESC")->fetchAll(PDO::FETCH_ASSOC);
// Detect anomalies
$alerts = [];
$avgRates = array_column($recentSends, 'avg_inbox');
if (count($avgRates) >= 3) {
$overallAvg = array_sum($avgRates) / count($avgRates);
// Check for sudden drop
if (count($avgRates) >= 2 && $avgRates[0] < $avgRates[1] * 0.7) {
$alerts[] = [
'type' => 'sudden_drop',
'severity' => 'high',
'message' => "Inbox rate dropped from {$avgRates[1]}% to {$avgRates[0]}%",
'possible_cause' => 'New filter or reputation damage',
];
}
// Check for consistent decline
if (count($avgRates) >= 3 && $avgRates[0] < $avgRates[1] && $avgRates[1] < $avgRates[2]) {
$alerts[] = [
'type' => 'declining_trend',
'severity' => 'medium',
'message' => 'Consistent decline in inbox rates detected',
'possible_cause' => 'Gradual reputation damage or filter adaptation',
];
}
// Check for below-threshold performance
if ($overallAvg < 50) {
$alerts[] = [
'type' => 'below_threshold',
'severity' => 'critical',
'message' => "Average inbox rate ({$overallAvg}%) is critically low",
'possible_cause' => 'Major deliverability issue or blacklisting',
];
}
}
// Get ISP filter info
$ispInfo = $ISP_DATABASE[$isp] ?? null;
$response = [
'success' => true,
'isp' => $isp,
'recent_sends' => $recentSends,
'alerts' => $alerts,
'filters' => $ispInfo['filters'] ?? [],
'recommendations' => $ispInfo ? [
'optimal_volume' => $ispInfo['optimal']['volume_per_day'],
'best_hours' => $ispInfo['optimal']['best_hours'],
'best_days' => $ispInfo['optimal']['best_days'],
'requirements' => $ispInfo['requirements'],
] : null,
];
break;
// ==================== LEARN FROM SEND ====================
case 'learn_from_send':
$config_id = intval($_POST['config_id']);
// Get send data
$config = $db->query("SELECT * FROM admin.send_configs WHERE id = $config_id")->fetch(PDO::FETCH_ASSOC);
$monitoring = $db->query("SELECT * FROM admin.inbox_monitoring WHERE send_config_id = $config_id ORDER BY check_time")->fetchAll(PDO::FETCH_ASSOC);
if (!$config || empty($monitoring)) {
$response = ['success' => false, 'error' => 'No data to learn from'];
break;
}
// Calculate averages
$avgInbox = array_sum(array_column($monitoring, 'inbox_rate')) / count($monitoring);
$stability = evaluateStability($monitoring);
// Determine success/failure
$success = $avgInbox >= 70 && $stability['score'] >= 60;
// Create learning entry
$learningData = [
'isp' => $config['isp'],
'country' => $config['country'],
'volume' => $config['mails_sent'],
'servers' => $config['servers_needed'],
'drops' => $config['drops_count'],
'speed' => $config['speed_per_server'],
'time_of_day' => date('H', strtotime($config['started_at'])),
'day_of_week' => date('l', strtotime($config['started_at'])),
];
$learningType = $success ? 'success_pattern' : 'failure_pattern';
$db->prepare("INSERT INTO admin.learning_history
(isp, country, send_config_id, learning_type, input_data, output_data, confidence)
VALUES (?, ?, ?, ?, ?, ?, ?)")
->execute([
$config['isp'],
$config['country'],
$config_id,
$learningType,
json_encode($learningData),
json_encode(['avg_inbox' => $avgInbox, 'stability' => $stability]),
$stability['confidence']
]);
// Update method scores
$methodName = "{$config['isp']}_{$config['country']}_{$config['servers_needed']}srv";
$existingMethod = $db->query("SELECT * FROM admin.method_scores WHERE method_name = '$methodName'")->fetch(PDO::FETCH_ASSOC);
if ($existingMethod) {
// Update existing
$newInboxScore = ($existingMethod['inbox_score'] * $existingMethod['total_uses'] + $avgInbox) / ($existingMethod['total_uses'] + 1);
$newStabilityScore = ($existingMethod['stability_score'] * $existingMethod['total_uses'] + $stability['score']) / ($existingMethod['total_uses'] + 1);
$db->prepare("UPDATE admin.method_scores SET
inbox_score = ?, stability_score = ?, total_uses = total_uses + 1,
success_count = success_count + ?, fail_count = fail_count + ?,
trend = ?, updated_at = NOW()
WHERE id = ?")
->execute([
$newInboxScore, $newStabilityScore,
$success ? 1 : 0, $success ? 0 : 1,
$stability['trend'],
$existingMethod['id']
]);
} else {
// Create new
$db->prepare("INSERT INTO admin.method_scores
(method_name, isp, country, inbox_score, stability_score, total_uses, success_count, fail_count, trend)
VALUES (?, ?, ?, ?, ?, 1, ?, ?, ?)")
->execute([
$methodName, $config['isp'], $config['country'],
$avgInbox, $stability['score'],
$success ? 1 : 0, $success ? 0 : 1,
$stability['trend']
]);
}
$response = [
'success' => true,
'learned' => [
'type' => $learningType,
'avg_inbox' => round($avgInbox, 2),
'stability' => $stability,
'method' => $methodName,
]
];
break;
// ==================== GET RECOMMENDATIONS ====================
case 'get_recommendations':
$isp = $_GET['isp'] ?? '';
$country = $_GET['country'] ?? '';
$volume = intval($_GET['volume'] ?? 10000);
$recommendations = [];
// 1. Best method based on learning
$bestMethod = $db->query("SELECT * FROM admin.method_scores
WHERE isp = '$isp' AND country = '$country' AND recommended = TRUE
ORDER BY (inbox_score * 0.4 + stability_score * 0.3 + cost_score * 0.3) DESC
LIMIT 1")->fetch(PDO::FETCH_ASSOC);
if ($bestMethod) {
$recommendations[] = [
'category' => 'method',
'priority' => 'high',
'title' => 'Recommended Method',
'description' => "Use method '{$bestMethod['method_name']}' with {$bestMethod['inbox_score']}% avg inbox",
'confidence' => $bestMethod['confidence_level'],
];
}
// 2. ISP-specific recommendations
$ispInfo = $ISP_DATABASE[$isp] ?? null;
if ($ispInfo) {
// Timing
$recommendations[] = [
'category' => 'timing',
'priority' => 'medium',
'title' => 'Optimal Send Time',
'description' => "Best hours: " . implode(', ', $ispInfo['optimal']['best_hours']) . ":00",
'data' => $ispInfo['optimal'],
];
// Volume
if ($volume > $ispInfo['optimal']['volume_per_day']) {
$recommendations[] = [
'category' => 'volume',
'priority' => 'high',
'title' => 'Volume Warning',
'description' => "Requested volume ($volume) exceeds optimal ({$ispInfo['optimal']['volume_per_day']})",
'action' => 'Split into multiple days or use more IPs',
];
}
// Technical
foreach ($ispInfo['requirements'] as $req => $needed) {
if ($needed) {
$recommendations[] = [
'category' => 'technical',
'priority' => 'critical',
'title' => strtoupper($req) . ' Required',
'description' => "$isp requires $req authentication",
];
}
}
}
// 3. Recent alerts
$alerts = $db->query("SELECT * FROM admin.antispam_watch
WHERE isp = '$isp' AND resolved = FALSE
ORDER BY detected_at DESC LIMIT 3")->fetchAll(PDO::FETCH_ASSOC);
foreach ($alerts as $alert) {
$recommendations[] = [
'category' => 'alert',
'priority' => $alert['severity'],
'title' => $alert['filter_name'] ?? 'Filter Alert',
'description' => $alert['description'],
'action' => $alert['recommended_action'],
];
}
// Sort by priority
$priorityOrder = ['critical' => 0, 'high' => 1, 'medium' => 2, 'low' => 3];
usort($recommendations, fn($a, $b) => ($priorityOrder[$a['priority']] ?? 9) - ($priorityOrder[$b['priority']] ?? 9));
$response = [
'success' => true,
'isp' => $isp,
'country' => $country,
'volume' => $volume,
'recommendations' => $recommendations,
'count' => count($recommendations),
];
break;
// ==================== FULL ANALYSIS ====================
case 'full_analysis':
$config_id = intval($_POST['config_id'] ?? $_GET['config_id'] ?? 0);
$analysis = [
'config_id' => $config_id,
'timestamp' => date('Y-m-d H:i:s'),
];
// Get config
$config = $db->query("SELECT c.*, s.name as sponsor_name, o.payout, o.epc
FROM admin.send_configs c
LEFT JOIN admin.sponsors s ON c.sponsor_id = s.id
LEFT JOIN admin.offers o ON c.offer_id = o.id
WHERE c.id = $config_id")->fetch(PDO::FETCH_ASSOC);
if (!$config) {
$response = ['success' => false, 'error' => 'Config not found'];
break;
}
$analysis['config'] = $config;
// Get monitoring data
$monitoring = $db->query("SELECT * FROM admin.inbox_monitoring WHERE send_config_id = $config_id ORDER BY check_time")->fetchAll(PDO::FETCH_ASSOC);
// 1. Stability Analysis
$analysis['stability'] = evaluateStability($monitoring);
// 2. Economic Analysis
$econData = [
'volume' => $config['mails_sent'] ?: $config['target_volume'] * 1000,
'servers' => $config['servers_needed'],
'hours' => 2, // Estimated
'domains' => 1,
'ips' => $config['servers_needed'],
'inbox_rate' => $analysis['stability']['avg'] ?? 70,
'payout' => $config['payout'] ?? 5,
'stability_score' => $analysis['stability']['score'],
];
$analysis['economics'] = calculateEconomicEquation($econData);
// 3. ISP Analysis
$ispInfo = $ISP_DATABASE[$config['isp']] ?? null;
if ($ispInfo) {
$analysis['isp'] = [
'name' => $config['isp'],
'difficulty' => $ispInfo['difficulty'],
'filters' => $ispInfo['filters'],
'compliance' => [
'volume_ok' => $config['mails_sent'] <= $ispInfo['optimal']['volume_per_day'],
'warmup_ok' => true, // Would check warmup table
],
];
}
// 4. Recommendations
$analysis['recommendations'] = [];
// Based on economics
$rec = $analysis['economics']['recommendation'];
$analysis['recommendations'][] = [
'source' => 'economics',
'action' => $rec['action'],
'reason' => $rec['reason'],
];
// Based on stability
if ($analysis['stability']['trend'] == 'declining') {
$analysis['recommendations'][] = [
'source' => 'stability',
'action' => 'INVESTIGATE',
'reason' => 'Inbox rates declining - check for filter changes',
];
}
// 5. Overall Score (1-100)
$overallScore = (
($analysis['stability']['score'] * 0.30) +
($analysis['economics']['performance']['profitability_score'] * 0.35) +
($analysis['economics']['performance']['efficiency_score'] * 0.20) +
($analysis['economics']['performance']['sustainability_score'] * 0.15)
);
$analysis['overall_score'] = round($overallScore);
// 6. Final Verdict
if ($overallScore >= 80) {
$analysis['verdict'] = ['status' => 'EXCELLENT', 'action' => 'Scale up recommended'];
} elseif ($overallScore >= 60) {
$analysis['verdict'] = ['status' => 'GOOD', 'action' => 'Continue and optimize'];
} elseif ($overallScore >= 40) {
$analysis['verdict'] = ['status' => 'FAIR', 'action' => 'Needs improvement'];
} else {
$analysis['verdict'] = ['status' => 'POOR', 'action' => 'Consider stopping or major changes'];
}
// Save analysis
$db->prepare("INSERT INTO admin.learning_history (send_config_id, learning_type, input_data, output_data, confidence)
VALUES (?, 'full_analysis', ?, ?, ?)")
->execute([$config_id, json_encode($config), json_encode($analysis), $analysis['stability']['confidence'] ?? 0.5]);
$response = ['success' => true, 'analysis' => $analysis];
break;
// ==================== SYNC ISP KNOWLEDGE ====================
case 'sync_isp_knowledge':
$synced = 0;
foreach ($ISP_DATABASE as $ispKey => $ispData) {
foreach ($ispData['countries'] as $country => $tz) {
$db->prepare("INSERT INTO admin.isp_knowledge
(isp, country, optimal_volume_per_hour, optimal_volume_per_day, warmup_days_needed,
best_send_hours, best_days, timezone, current_difficulty,
engagement_weight, complaint_weight, bounce_weight, spam_trap_weight)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON CONFLICT (isp, country) DO UPDATE SET
optimal_volume_per_hour = EXCLUDED.optimal_volume_per_hour,
optimal_volume_per_day = EXCLUDED.optimal_volume_per_day,
current_difficulty = EXCLUDED.current_difficulty,
updated_at = NOW()")
->execute([
$ispKey,
$country,
$ispData['optimal']['volume_per_hour'],
$ispData['optimal']['volume_per_day'],
$ispData['optimal']['warmup_days'],
json_encode($ispData['optimal']['best_hours']),
json_encode($ispData['optimal']['best_days']),
$tz,
$ispData['difficulty'],
$ispData['weights']['engagement'],
$ispData['weights']['complaints'],
$ispData['weights']['bounces'],
$ispData['weights']['traps'],
]);
$synced++;
}
}
$response = ['success' => true, 'synced' => $synced];
break;
}
echo json_encode($response, JSON_PRETTY_PRINT);