503 lines
19 KiB
PHP
Executable File
503 lines
19 KiB
PHP
Executable File
|
|
<?php
|
|
/**
|
|
* WEVAL SEND BRAIN ENGINE v2.0
|
|
* Autonomous Decision Making + Self-Learning System
|
|
*/
|
|
header('Content-Type: application/json');
|
|
error_reporting(0);
|
|
|
|
$pdo = new PDO("pgsql:host=localhost;dbname=adx_system", "admin", "admin123", [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
|
|
|
|
// Create Brain Tables
|
|
$pdo->exec("
|
|
CREATE TABLE IF NOT EXISTS admin.brain_knowledge (
|
|
id SERIAL PRIMARY KEY,
|
|
category VARCHAR(100),
|
|
key VARCHAR(255),
|
|
value TEXT,
|
|
confidence FLOAT DEFAULT 0.5,
|
|
last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
UNIQUE(category, key)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS admin.brain_decisions (
|
|
id SERIAL PRIMARY KEY,
|
|
decision_type VARCHAR(100),
|
|
input_data TEXT,
|
|
decision TEXT,
|
|
outcome VARCHAR(50),
|
|
feedback_score FLOAT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS admin.brain_isp_profiles (
|
|
id SERIAL PRIMARY KEY,
|
|
isp_name VARCHAR(100) UNIQUE,
|
|
filter_type VARCHAR(100),
|
|
max_volume_hour INTEGER DEFAULT 1000,
|
|
best_send_hours VARCHAR(100) DEFAULT '9,10,11,14,15,16',
|
|
required_warmup_days INTEGER DEFAULT 30,
|
|
header_preferences TEXT,
|
|
content_rules TEXT,
|
|
success_rate FLOAT DEFAULT 0,
|
|
last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS admin.brain_offer_profiles (
|
|
id SERIAL PRIMARY KEY,
|
|
offer_id VARCHAR(100),
|
|
offer_name VARCHAR(255),
|
|
vertical VARCHAR(100),
|
|
best_isps TEXT,
|
|
best_subjects TEXT,
|
|
best_send_times TEXT,
|
|
avg_open_rate FLOAT DEFAULT 0,
|
|
avg_click_rate FLOAT DEFAULT 0,
|
|
avg_conversion_rate FLOAT DEFAULT 0,
|
|
total_sends INTEGER DEFAULT 0,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS admin.brain_data_segments (
|
|
id SERIAL PRIMARY KEY,
|
|
segment_name VARCHAR(255),
|
|
criteria TEXT,
|
|
size INTEGER DEFAULT 0,
|
|
best_offers TEXT,
|
|
avg_response_rate FLOAT DEFAULT 0,
|
|
last_used TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS admin.brain_send_methods (
|
|
id SERIAL PRIMARY KEY,
|
|
method_name VARCHAR(100) UNIQUE,
|
|
description TEXT,
|
|
required_resources TEXT,
|
|
best_for_isps TEXT,
|
|
success_rate FLOAT DEFAULT 0,
|
|
config_template TEXT
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS admin.brain_learning_log (
|
|
id SERIAL PRIMARY KEY,
|
|
event_type VARCHAR(100),
|
|
data TEXT,
|
|
lesson_learned TEXT,
|
|
applied BOOLEAN DEFAULT false,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
");
|
|
|
|
class BrainEngine {
|
|
private $pdo;
|
|
private $hamidApi = 'http://localhost:5821/api/hamid-api.php';
|
|
|
|
public function __construct($pdo) {
|
|
$this->pdo = $pdo;
|
|
$this->initializeKnowledge();
|
|
}
|
|
|
|
private function initializeKnowledge() {
|
|
// ISP Profiles
|
|
$isps = [
|
|
['Videotron', 'Cloudmark', 2000, '9,10,11,14,15', 21],
|
|
['Gmail', 'Google AI', 500, '10,11,14,15,16', 45],
|
|
['Outlook', 'Microsoft SmartScreen', 1000, '9,10,11,15,16', 30],
|
|
['Yahoo', 'Yahoo SpamGuard', 800, '10,11,12,14,15', 30],
|
|
['GMX', 'Cloudmark', 1500, '8,9,10,14,15', 21],
|
|
['Orange', 'Vade Secure', 1000, '9,10,11,14,15', 25],
|
|
['SFR', 'Vade Secure', 1200, '9,10,11,14,15', 25],
|
|
['Free', 'SpamAssassin', 2000, '8,9,10,14,15,16', 14],
|
|
['LaPoste', 'Vade Secure', 800, '9,10,11,14,15', 30],
|
|
['AOL', 'Oath/Verizon', 600, '10,11,14,15', 30]
|
|
];
|
|
|
|
foreach ($isps as $isp) {
|
|
$this->pdo->prepare("INSERT INTO admin.brain_isp_profiles (isp_name, filter_type, max_volume_hour, best_send_hours, required_warmup_days) VALUES (?, ?, ?, ?, ?) ON CONFLICT (isp_name) DO NOTHING")
|
|
->execute($isp);
|
|
}
|
|
|
|
// Send Methods
|
|
$methods = [
|
|
['PMTA_Direct', 'Direct send via PowerMTA', '{"pmta_server": true, "dedicated_ip": true}', 'Videotron,GMX,Free', '{}'],
|
|
['O365_Relay', 'Office 365 SMTP Relay', '{"o365_tenant": true, "connector": true}', 'Gmail,Outlook,Yahoo', '{}'],
|
|
['GSuite_Relay', 'Google Workspace Relay', '{"gsuite_workspace": true, "relay_ip": true}', 'Gmail,Yahoo,AOL', '{}'],
|
|
['Hybrid_Rotation', 'Rotating between methods', '{"pmta_server": true, "o365_tenant": true}', 'All', '{}'],
|
|
['Warmerless', 'Pre-warmed accounts instant send', '{"warmed_accounts": true}', 'All', '{}']
|
|
];
|
|
|
|
foreach ($methods as $m) {
|
|
$this->pdo->prepare("INSERT INTO admin.brain_send_methods (method_name, description, required_resources, best_for_isps, config_template) VALUES (?, ?, ?, ?, ?) ON CONFLICT (method_name) DO NOTHING")
|
|
->execute($m);
|
|
}
|
|
}
|
|
|
|
// ============================================
|
|
// AUTONOMOUS CAMPAIGN PLANNING
|
|
// ============================================
|
|
|
|
public function planCampaign($params) {
|
|
$offer = $params['offer'] ?? [];
|
|
$targetIsp = $params['isp'] ?? 'auto';
|
|
$volume = $params['volume'] ?? 10000;
|
|
$budget = $params['budget'] ?? 'optimal';
|
|
|
|
$plan = [
|
|
'status' => 'planned',
|
|
'created_at' => date('Y-m-d H:i:s'),
|
|
'input' => $params
|
|
];
|
|
|
|
// 1. Analyze ISP and get profile
|
|
if ($targetIsp == 'auto') {
|
|
$plan['isp'] = $this->selectBestISP($offer);
|
|
} else {
|
|
$plan['isp'] = $this->getISPProfile($targetIsp);
|
|
}
|
|
|
|
// 2. Select best send method
|
|
$plan['method'] = $this->selectSendMethod($plan['isp'], $volume);
|
|
|
|
// 3. Allocate resources (servers, IPs, domains)
|
|
$plan['resources'] = $this->allocateResources($plan['method'], $volume);
|
|
|
|
// 4. Generate optimized content
|
|
$plan['content'] = $this->generateOptimizedContent($offer, $plan['isp']);
|
|
|
|
// 5. Segment data
|
|
$plan['segments'] = $this->segmentData($offer, $plan['isp'], $volume);
|
|
|
|
// 6. Schedule send times
|
|
$plan['schedule'] = $this->optimizeSchedule($plan['isp'], $volume);
|
|
|
|
// 7. Predict outcome
|
|
$plan['prediction'] = $this->predictOutcome($plan);
|
|
|
|
// Save decision
|
|
$this->logDecision('campaign_plan', json_encode($params), json_encode($plan));
|
|
|
|
return $plan;
|
|
}
|
|
|
|
private function selectBestISP($offer) {
|
|
// Get ISP with best success rate for this vertical
|
|
$vertical = $offer['vertical'] ?? 'general';
|
|
$stmt = $this->pdo->query("SELECT * FROM admin.brain_isp_profiles ORDER BY success_rate DESC LIMIT 1");
|
|
return $stmt->fetch(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
private function getISPProfile($ispName) {
|
|
$stmt = $this->pdo->prepare("SELECT * FROM admin.brain_isp_profiles WHERE isp_name = ?");
|
|
$stmt->execute([$ispName]);
|
|
return $stmt->fetch(PDO::FETCH_ASSOC) ?: ['isp_name' => $ispName, 'filter_type' => 'unknown'];
|
|
}
|
|
|
|
private function selectSendMethod($isp, $volume) {
|
|
$ispName = $isp['isp_name'] ?? 'unknown';
|
|
$stmt = $this->pdo->query("SELECT * FROM admin.brain_send_methods WHERE best_for_isps LIKE '%$ispName%' OR best_for_isps = 'All' ORDER BY success_rate DESC LIMIT 1");
|
|
$method = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
|
|
if (!$method) {
|
|
$method = ['method_name' => 'PMTA_Direct', 'description' => 'Default method'];
|
|
}
|
|
|
|
return $method;
|
|
}
|
|
|
|
private function allocateResources($method, $volume) {
|
|
$resources = [
|
|
'servers' => [],
|
|
'ips' => [],
|
|
'domains' => [],
|
|
'accounts' => []
|
|
];
|
|
|
|
// Calculate needed servers (15000 emails per server max)
|
|
$serversNeeded = ceil($volume / 15000);
|
|
|
|
// Get available IPs
|
|
$ips = $this->pdo->query("SELECT * FROM admin.ip_pool WHERE status = 'active' ORDER BY sends_today ASC LIMIT $serversNeeded")->fetchAll(PDO::FETCH_ASSOC);
|
|
$resources['ips'] = $ips;
|
|
|
|
// Get available domains
|
|
$domains = $this->pdo->query("SELECT * FROM admin.rotation_domains WHERE status = 'active' ORDER BY sends_today ASC LIMIT " . ($serversNeeded * 3))->fetchAll(PDO::FETCH_ASSOC);
|
|
$resources['domains'] = $domains;
|
|
|
|
// Server recommendation
|
|
$resources['server_config'] = [
|
|
'count' => $serversNeeded,
|
|
'type' => 't6.medium.2',
|
|
'provider' => 'huawei',
|
|
'region' => 'af-south-1',
|
|
'specs' => ['vcpus' => 2, 'ram' => '4GB', 'bandwidth' => '300Mbps']
|
|
];
|
|
|
|
return $resources;
|
|
}
|
|
|
|
private function generateOptimizedContent($offer, $isp) {
|
|
$filterType = $isp['filter_type'] ?? 'generic';
|
|
|
|
// Content rules based on filter
|
|
$rules = [
|
|
'Cloudmark' => ['avoid' => ['free', 'click here', 'act now'], 'prefer' => ['personal tone', 'short subjects']],
|
|
'Google AI' => ['avoid' => ['ALL CAPS', 'excessive punctuation'], 'prefer' => ['conversational', 'relevant content']],
|
|
'Microsoft SmartScreen' => ['avoid' => ['suspicious links', 'hidden text'], 'prefer' => ['professional tone', 'clear CTA']],
|
|
'Vade Secure' => ['avoid' => ['generic greetings', 'urgency words'], 'prefer' => ['personalization', 'local language']]
|
|
];
|
|
|
|
$contentRules = $rules[$filterType] ?? $rules['Cloudmark'];
|
|
|
|
return [
|
|
'rules' => $contentRules,
|
|
'recommended_subject_style' => $this->getSubjectStyle($filterType),
|
|
'recommended_from_style' => $this->getFromStyle($filterType),
|
|
'header_config' => $this->getHeaderConfig($isp)
|
|
];
|
|
}
|
|
|
|
private function getSubjectStyle($filterType) {
|
|
$styles = [
|
|
'Cloudmark' => ['max_length' => 50, 'personalization' => true, 'emoji' => false],
|
|
'Google AI' => ['max_length' => 60, 'personalization' => true, 'emoji' => 'moderate'],
|
|
'Microsoft SmartScreen' => ['max_length' => 55, 'personalization' => true, 'emoji' => false],
|
|
'Vade Secure' => ['max_length' => 45, 'personalization' => true, 'emoji' => false]
|
|
];
|
|
return $styles[$filterType] ?? $styles['Cloudmark'];
|
|
}
|
|
|
|
private function getFromStyle($filterType) {
|
|
return [
|
|
'use_real_name' => true,
|
|
'avoid_generic' => true,
|
|
'match_domain' => true
|
|
];
|
|
}
|
|
|
|
private function getHeaderConfig($isp) {
|
|
$ispName = strtolower($isp['isp_name'] ?? 'generic');
|
|
|
|
// Dynamic header generation based on ISP
|
|
return [
|
|
'boundary' => '----=_Part_' . bin2hex(random_bytes(8)),
|
|
'message_id_domain' => 'auto', // Will use sending domain
|
|
'x_mailer' => $this->getRandomMailer(),
|
|
'x_priority' => 3,
|
|
'return_path' => 'bounce-' . bin2hex(random_bytes(4)) . '@{domain}',
|
|
'list_unsubscribe' => true,
|
|
'dkim' => true,
|
|
'custom_headers' => $this->getISPSpecificHeaders($ispName)
|
|
];
|
|
}
|
|
|
|
private function getRandomMailer() {
|
|
$mailers = [
|
|
'Microsoft Outlook 16.0',
|
|
'Apple Mail (2.3654)',
|
|
'Mozilla Thunderbird 91.0',
|
|
'Gmail',
|
|
null // No X-Mailer
|
|
];
|
|
return $mailers[array_rand($mailers)];
|
|
}
|
|
|
|
private function getISPSpecificHeaders($isp) {
|
|
$headers = [];
|
|
|
|
if (in_array($isp, ['gmail', 'yahoo'])) {
|
|
$headers['Feedback-ID'] = uniqid() . ':campaign:' . uniqid();
|
|
}
|
|
|
|
if ($isp == 'outlook' || $isp == 'hotmail') {
|
|
$headers['X-MS-Exchange-Organization-SCL'] = '-1';
|
|
}
|
|
|
|
return $headers;
|
|
}
|
|
|
|
private function segmentData($offer, $isp, $volume) {
|
|
$vertical = $offer['vertical'] ?? 'general';
|
|
|
|
return [
|
|
'strategy' => 'engagement_based',
|
|
'tiers' => [
|
|
['name' => 'hot', 'percentage' => 20, 'criteria' => 'opened_last_7_days', 'send_first' => true],
|
|
['name' => 'warm', 'percentage' => 30, 'criteria' => 'opened_last_30_days', 'send_second' => true],
|
|
['name' => 'cold', 'percentage' => 50, 'criteria' => 'no_recent_activity', 'send_last' => true]
|
|
],
|
|
'volume_per_tier' => [
|
|
'hot' => round($volume * 0.2),
|
|
'warm' => round($volume * 0.3),
|
|
'cold' => round($volume * 0.5)
|
|
]
|
|
];
|
|
}
|
|
|
|
private function optimizeSchedule($isp, $volume) {
|
|
$bestHours = explode(',', $isp['best_send_hours'] ?? '9,10,11,14,15');
|
|
$maxPerHour = $isp['max_volume_hour'] ?? 1000;
|
|
|
|
$schedule = [];
|
|
$remaining = $volume;
|
|
$hourIndex = 0;
|
|
|
|
while ($remaining > 0 && $hourIndex < count($bestHours) * 3) {
|
|
$hour = $bestHours[$hourIndex % count($bestHours)];
|
|
$day = floor($hourIndex / count($bestHours));
|
|
|
|
$toSend = min($remaining, $maxPerHour);
|
|
$schedule[] = [
|
|
'day' => $day,
|
|
'hour' => (int)$hour,
|
|
'volume' => $toSend
|
|
];
|
|
|
|
$remaining -= $toSend;
|
|
$hourIndex++;
|
|
}
|
|
|
|
return $schedule;
|
|
}
|
|
|
|
private function predictOutcome($plan) {
|
|
$isp = $plan['isp'];
|
|
$method = $plan['method'];
|
|
|
|
$baseInboxRate = $isp['success_rate'] ?? 70;
|
|
$methodBonus = $method['success_rate'] ?? 0;
|
|
|
|
$predictedInbox = min(100, $baseInboxRate + $methodBonus);
|
|
|
|
return [
|
|
'predicted_inbox_rate' => $predictedInbox,
|
|
'predicted_open_rate' => $predictedInbox * 0.15,
|
|
'predicted_click_rate' => $predictedInbox * 0.02,
|
|
'confidence' => 0.7
|
|
];
|
|
}
|
|
|
|
// ============================================
|
|
// LEARNING & FEEDBACK
|
|
// ============================================
|
|
|
|
public function recordFeedback($campaignId, $results) {
|
|
// Update ISP profile based on results
|
|
if (isset($results['isp']) && isset($results['inbox_rate'])) {
|
|
$this->pdo->prepare("UPDATE admin.brain_isp_profiles SET success_rate = (success_rate + ?) / 2, last_updated = NOW() WHERE isp_name = ?")
|
|
->execute([$results['inbox_rate'], $results['isp']]);
|
|
}
|
|
|
|
// Update method success rate
|
|
if (isset($results['method']) && isset($results['inbox_rate'])) {
|
|
$this->pdo->prepare("UPDATE admin.brain_send_methods SET success_rate = (success_rate + ?) / 2 WHERE method_name = ?")
|
|
->execute([$results['inbox_rate'], $results['method']]);
|
|
}
|
|
|
|
// Log learning
|
|
$lesson = $this->analyzeFeedback($results);
|
|
$this->pdo->prepare("INSERT INTO admin.brain_learning_log (event_type, data, lesson_learned) VALUES (?, ?, ?)")
|
|
->execute(['campaign_feedback', json_encode($results), $lesson]);
|
|
|
|
return ['success' => true, 'lesson' => $lesson];
|
|
}
|
|
|
|
private function analyzeFeedback($results) {
|
|
$inboxRate = $results['inbox_rate'] ?? 0;
|
|
|
|
if ($inboxRate >= 90) {
|
|
return "Excellent performance. Replicate this configuration for similar campaigns.";
|
|
} elseif ($inboxRate >= 70) {
|
|
return "Good performance. Minor optimizations possible in content or timing.";
|
|
} elseif ($inboxRate >= 50) {
|
|
return "Moderate performance. Review content triggers and sending patterns.";
|
|
} else {
|
|
return "Poor performance. Major changes needed. Check IP reputation, content, and warmup status.";
|
|
}
|
|
}
|
|
|
|
public function getInsights() {
|
|
return [
|
|
'top_isps' => $this->pdo->query("SELECT isp_name, success_rate FROM admin.brain_isp_profiles ORDER BY success_rate DESC LIMIT 5")->fetchAll(PDO::FETCH_ASSOC),
|
|
'top_methods' => $this->pdo->query("SELECT method_name, success_rate FROM admin.brain_send_methods ORDER BY success_rate DESC LIMIT 5")->fetchAll(PDO::FETCH_ASSOC),
|
|
'recent_learnings' => $this->pdo->query("SELECT event_type, lesson_learned, created_at FROM admin.brain_learning_log ORDER BY created_at DESC LIMIT 10")->fetchAll(PDO::FETCH_ASSOC),
|
|
'decisions_today' => $this->pdo->query("SELECT COUNT(*) FROM admin.brain_decisions WHERE DATE(created_at) = CURRENT_DATE")->fetchColumn()
|
|
];
|
|
}
|
|
|
|
private function logDecision($type, $input, $decision) {
|
|
$this->pdo->prepare("INSERT INTO admin.brain_decisions (decision_type, input_data, decision) VALUES (?, ?, ?)")
|
|
->execute([$type, $input, $decision]);
|
|
}
|
|
|
|
// ============================================
|
|
// WEVAL MIND INTEGRATION
|
|
// ============================================
|
|
|
|
public function askHamid($question, $context = []) {
|
|
$ch = curl_init($this->hamidApi);
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_POST => true,
|
|
CURLOPT_POSTFIELDS => http_build_query([
|
|
'action' => 'ask',
|
|
'question' => $question,
|
|
'context' => json_encode($context)
|
|
]),
|
|
CURLOPT_TIMEOUT => 30
|
|
]);
|
|
$response = curl_exec($ch);
|
|
curl_close($ch);
|
|
return json_decode($response, true);
|
|
}
|
|
|
|
public function generateWithAI($type, $params) {
|
|
$prompts = [
|
|
'subject' => "Generate 5 email subject lines for: {$params['offer']}. Target: {$params['isp']}. Avoid spam triggers. Be creative and personal.",
|
|
'from_name' => "Generate 5 professional sender names for: {$params['offer']}. Should look trustworthy.",
|
|
'body' => "Generate email body HTML for: {$params['offer']}. Keep it short, engaging, with clear CTA."
|
|
];
|
|
|
|
$prompt = $prompts[$type] ?? $prompts['subject'];
|
|
return $this->askHamid($prompt, $params);
|
|
}
|
|
}
|
|
|
|
// API Handler
|
|
$brain = new BrainEngine($pdo);
|
|
$action = $_POST['action'] ?? $_GET['action'] ?? '';
|
|
|
|
switch ($action) {
|
|
case 'plan':
|
|
echo json_encode($brain->planCampaign($_POST));
|
|
break;
|
|
case 'feedback':
|
|
echo json_encode($brain->recordFeedback($_POST['campaign_id'], $_POST));
|
|
break;
|
|
case 'insights':
|
|
echo json_encode($brain->getInsights());
|
|
break;
|
|
case 'ask_ai':
|
|
echo json_encode($brain->askHamid($_POST['question'], $_POST['context'] ?? []));
|
|
break;
|
|
case 'generate':
|
|
echo json_encode($brain->generateWithAI($_POST['type'], $_POST));
|
|
break;
|
|
case 'isp_profiles':
|
|
echo json_encode(['profiles' => $pdo->query("SELECT * FROM admin.brain_isp_profiles ORDER BY success_rate DESC")->fetchAll(PDO::FETCH_ASSOC)]);
|
|
break;
|
|
case 'methods':
|
|
echo json_encode(['methods' => $pdo->query("SELECT * FROM admin.brain_send_methods ORDER BY success_rate DESC")->fetchAll(PDO::FETCH_ASSOC)]);
|
|
break;
|
|
case 'learnings':
|
|
echo json_encode(['learnings' => $pdo->query("SELECT * FROM admin.brain_learning_log ORDER BY created_at DESC LIMIT 50")->fetchAll(PDO::FETCH_ASSOC)]);
|
|
break;
|
|
default:
|
|
echo json_encode([
|
|
'name' => 'WEVAL SEND Brain Engine v2.0',
|
|
'actions' => ['plan', 'feedback', 'insights', 'ask_ai', 'generate', 'isp_profiles', 'methods', 'learnings'],
|
|
'description' => 'Autonomous AI-powered campaign planning and optimization'
|
|
]);
|
|
}
|
|
|