103 lines
4.5 KiB
PHP
Executable File
103 lines
4.5 KiB
PHP
Executable File
#!/usr/bin/env php
|
|
<?php
|
|
/**
|
|
* BRAIN TEST CYCLE CRON
|
|
* Runs every hour: picks untested configs, sends via PMTA, logs results
|
|
* Cron: 0 * * * * php /opt/wevads/scripts/brain-test-cycle.php >> /var/log/wevads/brain-cycle.log 2>&1
|
|
*/
|
|
$pdo = new PDO("pgsql:host=localhost;dbname=adx_system","admin","admin123");
|
|
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
|
|
$maxTests = 10;
|
|
$jobId = 'CYCLE_' . date('YmdHis');
|
|
|
|
echo "[" . date('Y-m-d H:i:s') . "] Brain Test Cycle START ($jobId)\n";
|
|
|
|
// Create job
|
|
$pdo->prepare("INSERT INTO admin.brain_test_jobs (job_id, status, total_configs, started_at, created_at) VALUES (?,?,?,NOW(),NOW())")->execute([$jobId, 'running', $maxTests]);
|
|
|
|
// Pick configs to test (least tested first)
|
|
$configs = $pdo->query("SELECT * FROM admin.brain_configs WHERE is_active=true ORDER BY total_sent ASC, RANDOM() LIMIT $maxTests")->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
$sent = 0; $failed = 0;
|
|
|
|
foreach ($configs as $c) {
|
|
// Find matching seed
|
|
$ispTarget = strtoupper($c['isp_target']);
|
|
$ispMap = [
|
|
'T-ONLINE' => "'T-ONLINE','TONLINE'", 'GMX' => "'GMX'", 'GMAIL' => "'GMAIL','GOOGLE'",
|
|
'OUTLOOK' => "'HOTMAIL','MICROSOFT','OUTLOOK'", 'WEB.DE' => "'GMX','WEBDE'",
|
|
'ZIGGO' => "'ZIGGO'", 'ALICE' => "'ALICE','LIBERO'", 'YAHOO' => "'YAHOO'",
|
|
'ORANGE' => "'ORANGE'", 'SFR' => "'SFR'", 'FREE' => "'FREE'"
|
|
];
|
|
$ispList = $ispMap[$ispTarget] ?? "'$ispTarget'";
|
|
|
|
$seed = $pdo->query("SELECT id, email, isp FROM admin.brain_seeds WHERE is_active=true AND UPPER(isp) IN ($ispList) ORDER BY RANDOM() LIMIT 1")->fetch(PDO::FETCH_ASSOC);
|
|
if (!$seed) $seed = $pdo->query("SELECT id, email, isp FROM admin.brain_seeds WHERE is_active=true ORDER BY RANDOM() LIMIT 1")->fetch(PDO::FETCH_ASSOC);
|
|
if (!$seed) continue;
|
|
|
|
// Build email
|
|
$domain = $c['domain_used'] ?: 'wevads.com';
|
|
$fromEmail = $c['from_email'] ?: "test@$domain";
|
|
$fromName = $c['from_name'] ?: 'Newsletter';
|
|
$subject = ($c['subject_template'] ?: 'Update') . ' #' . rand(100,999);
|
|
$returnPath = $c['return_path'] ?: "bounce@$domain";
|
|
$contentType = $c['content_type'] ?: 'text/html; charset=UTF-8';
|
|
$body = $c['body_template'] ?: "<html><body><p>Test config #{$c['id']} - {$c['isp_target']}</p></body></html>";
|
|
|
|
// Send via PMTA
|
|
$sock = @fsockopen('127.0.0.1', 25, $en, $es, 5);
|
|
if (!$sock) { echo " ❌ PMTA down\n"; $failed++; continue; }
|
|
|
|
fgets($sock, 512);
|
|
foreach (["EHLO $domain\r\n", "MAIL FROM:<$returnPath>\r\n", "RCPT TO:<{$seed['email']}>\r\n", "DATA\r\n"] as $cmd) {
|
|
fwrite($sock, $cmd); fgets($sock, 512);
|
|
}
|
|
|
|
$msg = "From: $fromName <$fromEmail>\r\n";
|
|
$msg .= "To: {$seed['email']}\r\n";
|
|
$msg .= "Subject: $subject\r\n";
|
|
$msg .= "Content-Type: $contentType\r\n";
|
|
$msg .= "MIME-Version: 1.0\r\n";
|
|
$msg .= "Date: " . date('r') . "\r\n";
|
|
// Custom headers from config
|
|
for ($i = 1; $i <= 5; $i++) {
|
|
$hn = $c["header_{$i}_name"] ?? '';
|
|
$hv = $c["header_{$i}_value"] ?? '';
|
|
if ($hn && $hv) $msg .= "$hn: $hv\r\n";
|
|
}
|
|
$msg .= "\r\n$body\r\n.\r\n";
|
|
|
|
fwrite($sock, $msg);
|
|
$resp = fgets($sock, 512);
|
|
fwrite($sock, "QUIT\r\n");
|
|
fclose($sock);
|
|
|
|
$ok = strpos($resp, '250') !== false;
|
|
|
|
// Log result
|
|
$pdo->prepare("INSERT INTO admin.brain_test_results (job_id, config_id, seed_id, send_status, send_time, subject_used, created_at) VALUES (?,?,?,?,NOW(),?,NOW())")
|
|
->execute([$jobId, $c['id'], $seed['id'], $ok ? 'sent' : 'failed', $subject]);
|
|
|
|
// Update config stats
|
|
if ($ok) {
|
|
$pdo->exec("UPDATE admin.brain_configs SET total_sent = total_sent + 1, last_tested_at = NOW() WHERE id = {$c['id']}");
|
|
$sent++;
|
|
echo " ✅ #{$c['id']} {$c['isp_target']} → {$seed['email']}\n";
|
|
} else {
|
|
$pdo->prepare("UPDATE admin.brain_test_results SET error_message=? WHERE job_id=? AND config_id=?")->execute([trim($resp), $jobId, $c['id']]);
|
|
$failed++;
|
|
echo " ❌ #{$c['id']} {$c['isp_target']}: $resp\n";
|
|
}
|
|
|
|
usleep(500000); // 0.5s between sends
|
|
}
|
|
|
|
// Update job
|
|
$pdo->prepare("UPDATE admin.brain_test_jobs SET status='completed', tested_count=?, inbox_count=?, completed_at=NOW() WHERE job_id=?")->execute([$sent + $failed, $sent, $jobId]);
|
|
|
|
// Auto-promote winners: configs with inbox_rate >= 85% and total_sent >= 5
|
|
$newWinners = $pdo->exec("UPDATE admin.brain_configs SET status='winner', is_winner=true WHERE total_sent >= 5 AND inbox_rate >= 85 AND is_winner=false");
|
|
|
|
echo "[" . date('Y-m-d H:i:s') . "] DONE: sent=$sent failed=$failed newWinners=$newWinners\n";
|