[ '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);