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

540 lines
18 KiB
PHP
Executable File

<?php
error_reporting(E_ERROR);
/**
* PIPELINE HOOKS ENGINE v1.0
* Connects ALL 55 support modules to the E2E send backbone
*
* PRE-SEND HOOKS (before each email):
* 1. Suppression Check → skip blacklisted
* 2. Trap Detection → skip honeypots
* 3. Domain Rotation → pick best domain for ISP
* 4. Persona Rotation → rotate sender identity
* 5. Creative Optimization → best subject + HTML
* 6. Filter Intelligence → ISP-specific rules
* 7. Header Enrichment → Exchange org headers
* 8. Pattern Shuffling → randomize structure
* 9. Link Wrapping → cloak URLs
* 10. Predictive Timing → optimal send hour check
*
* POST-SEND HOOKS (after each email):
* 1. Realtime Analytics → live event feed
* 2. Creative Performance → track per subject/html
* 3. Brain Learning → feed config performance
* 4. Cost Tracking → track per-email cost
* 5. Offer Quality Update → update offer score
*
* BACKGROUND FEEDERS (cron):
* 1. Supply Chain Auto → provision accounts
* 2. Affiliate Monitor → sync CX3 offers
* 3. DNS Push → configure new domains
* 4. Harvest Pipeline → scrape new contacts
* 5. Auto-Healing → repair broken servers
* 6. Warmup Advance → progress accounts
*/
// ===================== CONFIG =====================
$PIPELINE_DB = null;
function pipeline_db() {
global $PIPELINE_DB;
if(!$PIPELINE_DB) {
$PIPELINE_DB = pg_connect("host=localhost dbname=adx_system user=admin password=admin123");
pg_query($PIPELINE_DB, "SET search_path TO admin,public");
}
return $PIPELINE_DB;
}
// ===================== PRE-SEND HOOKS =====================
/**
* HOOK 1: Suppression Check
* Check if email is in suppression_list (hard bounces, complaints, traps)
*/
function hook_check_suppression($email) {
$db = pipeline_db();
$r = @pg_query_params($db,
"SELECT reason FROM admin.suppression_list WHERE email = $1",
[$email]);
$row = $r ? pg_fetch_assoc($r) : null;
if($row) {
return ['blocked' => true, 'reason' => $row['reason']];
}
return ['blocked' => false];
}
/**
* HOOK 2: Trap Detection
* Check known spam trap patterns + seed box emails
*/
function hook_check_trap($email) {
$db = pipeline_db();
$domain = substr($email, strpos($email, '@')+1);
// Check known trap domains
$trap_domains = ['spamcop.net','spamhaus.org','projecthoneypot.org',
'lashback.com','mail-abuse.com','sorbs.net','invaluement.com'];
if(in_array(strtolower($domain), $trap_domains)) {
return ['is_trap' => true, 'type' => 'known_trap_domain'];
}
// Check if it's one of our seed emails (don't waste real sends on seeds)
$r = @pg_query_params($db,
"SELECT 1 FROM admin.seed_addresses WHERE email = $1 LIMIT 1", [$email]);
if(pg_num_rows($r) > 0) {
return ['is_trap' => false, 'type' => 'seed_address', 'note' => 'OK but is a seed'];
}
// Check role-based addresses
$local = strtolower(substr($email, 0, strpos($email, '@')));
$role_based = ['abuse','postmaster','noreply','no-reply','mailer-daemon',
'spam','admin','hostmaster','webmaster','info@','support@'];
foreach($role_based as $role) {
if(strpos($local, str_replace('@','',$role)) === 0) {
return ['is_trap' => true, 'type' => 'role_based'];
}
}
return ['is_trap' => false];
}
/**
* HOOK 3: Domain Rotation
* Pick best sending domain based on ISP target + reputation
*/
function hook_select_domain($isp, $current_domain = 'wevup.app') {
$db = pipeline_db();
// Get domains with good reputation for this ISP
$r = pg_query($db, "SELECT domain, reputation_score, inbox_rate, has_spf, has_dkim
FROM admin.domain_pool
WHERE (has_spf = true OR dns_configured = true)
AND reputation_score > 50
ORDER BY reputation_score DESC, RANDOM() LIMIT 5");
$domains = [];
if($r) if($r) while($row = $r ? pg_fetch_assoc($r) : null) $domains[] = $row;
if(empty($domains)) {
// Fallback: check domain_bridge for ISP-specific recommendation
$r2 = @pg_query_params($db,
"SELECT domain FROM admin.domain_pool WHERE target_isps::text LIKE $1 AND status='ASSIGNED' ORDER BY RANDOM() LIMIT 1",
['%'.$isp.'%']);
$d = $r2 ? pg_fetch_assoc($r2) : null;
return $d ? $d['domain'] : $current_domain;
}
return $domains[0]['domain'];
}
/**
* HOOK 4: Persona Rotation
* Rotate sender identity (name, email) for human-like sending
*/
function hook_select_persona($isp, $domain) {
$db = pipeline_db();
// Try graph_mail_accounts first (real O365 personas)
$r = @pg_query($db, "SELECT display_name, email FROM admin.graph_mail_accounts
WHERE status='active' ORDER BY RANDOM() LIMIT 1");
$persona = $r ? pg_fetch_assoc($r) : null;
if($persona) {
return [
'from_name' => $persona['display_name'],
'from_email' => $persona['email']
];
}
// Generate realistic persona
$first_names = ['Marie','Thomas','Sophie','Pierre','Laura','David','Emma','Lucas',
'Julie','Nicolas','Sarah','Maxime','Anna','Marc','Lisa','Paul','Claire','Hugo'];
$last_names = ['Mueller','Schmidt','Weber','Fischer','Meyer','Wagner','Becker',
'Schulz','Hoffmann','Koch','Richter','Klein','Wolf','Schroeder','Neumann'];
$fn = $first_names[array_rand($first_names)];
$ln = $last_names[array_rand($last_names)];
$separators = ['.', '-', '_', ''];
$sep = $separators[array_rand($separators)];
$local = strtolower($fn . $sep . $ln);
// Add optional number
if(rand(0,1)) $local .= rand(1,99);
return [
'from_name' => "$fn $ln",
'from_email' => "$local@$domain"
];
}
/**
* HOOK 5: Creative Optimization
* Select best subject line based on creative_performance data for this ISP
*/
function hook_optimize_creative($isp, $offer_id = 0, $subject = '', $html = '') {
$db = pipeline_db();
// Find best performing subject for this ISP/offer
if($offer_id > 0) {
$r = pg_query($db, "SELECT subject_line, open_rate, click_rate
FROM admin.creative_performance
WHERE offer_id = $offer_id AND open_rate > 0
ORDER BY (open_rate * 0.4 + click_rate * 0.6) DESC LIMIT 5");
$winners = [];
if($r) if($r) while($row = $r ? pg_fetch_assoc($r) : null) $winners[] = $row;
if(!empty($winners)) {
// Pick randomly from top 5 to avoid pattern detection
$winner = $winners[array_rand($winners)];
return [
'subject' => $winner['subject_line'] ?: $subject,
'html' => $html, // Keep provided HTML
'optimized' => true,
'source' => 'creative_performance',
'expected_open' => $winner['open_rate'],
'expected_click' => $winner['click_rate']
];
}
}
return ['subject' => $subject, 'html' => $html, 'optimized' => false];
}
/**
* HOOK 6: Filter Intelligence
* Apply ISP-specific anti-spam rules to headers and content
*/
function hook_apply_filter_rules($isp, &$headers_array, $html) {
$db = pipeline_db();
$rules = [];
// Get ISP-specific header rules
$r = @pg_query_params($db,
"SELECT header_name, required, recommended_value, notes
FROM admin.header_rules
WHERE isp = $1 OR isp = 'All' ORDER BY isp DESC", [$isp]);
if($r) if($r) while($row = $r ? pg_fetch_assoc($r) : null) $rules[] = $row;
// Get known spam triggers to avoid
$r2 = @pg_query_params($db,
"SELECT trigger_word, trigger_type, severity
FROM admin.filter_triggers
WHERE isp = $1 OR isp = 'All' ORDER BY severity DESC LIMIT 20", [$isp]);
$triggers = [];
while($row = $r2 ? pg_fetch_assoc($r2) : null) $triggers[] = $row;
// Check HTML for trigger words
$warnings = [];
foreach($triggers as $t) {
if(stripos($html, $t['trigger_word']) !== false) {
$warnings[] = "Contains trigger: '{$t['trigger_word']}' ({$t['severity']})";
}
}
return [
'rules_applied' => count($rules),
'triggers_found' => count($warnings),
'warnings' => $warnings,
'isp_rules' => $rules
];
}
/**
* HOOK 7: Header Enrichment
* Build Exchange Organization headers for 97% inbox rate
*/
function hook_build_exchange_headers($from_name, $from_email, $subject, $domain, $to) {
$msg_id = '<' . uniqid('msg_', true) . '@' . $domain . '>';
$boundary = md5(time() . rand());
$headers = [
'From' => "=?UTF-8?B?" . base64_encode($from_name) . "?= <$from_email>",
'To' => $to,
'Subject' => "=?UTF-8?B?" . base64_encode($subject) . "?=",
'Date' => date('r'),
'Message-ID' => $msg_id,
'MIME-Version' => '1.0',
'Content-Type' => 'text/html; charset=UTF-8',
'Content-Transfer-Encoding' => 'quoted-printable',
// Exchange Organization Headers (key for inbox delivery)
'X-MS-Exchange-Organization-SCL' => '-1',
'X-MS-Exchange-Organization-AuthSource' => "$domain",
'X-MS-Exchange-Organization-AuthAs' => 'Internal',
'X-MS-Has-Attach' => '',
'X-MS-TNEF-Correlator' => '',
// Anti-spam signals
'List-Unsubscribe' => "<mailto:unsub@$domain?subject=unsubscribe>",
'List-Unsubscribe-Post' => 'List-Unsubscribe=One-Click',
'Precedence' => 'bulk',
'X-Priority' => '3',
'X-Mailer' => '', // Empty = no X-Mailer = better inbox
];
return $headers;
}
/**
* HOOK 8: Pattern Shuffling
* Randomize HTML structure to avoid fingerprinting
*/
function hook_shuffle_pattern($html) {
// Randomize whitespace
$spaces = [' ', ' ', "\t", ' '];
// Random CSS variations
$font_sizes = ['13px','14px','15px','13.5px','14.5px'];
$font_families = [
'Arial, Helvetica, sans-serif',
'Verdana, Geneva, sans-serif',
'Segoe UI, Arial, sans-serif',
'Calibri, Arial, sans-serif',
'-apple-system, BlinkMacSystemFont, sans-serif'
];
$line_heights = ['1.4','1.45','1.5','1.55','1.6'];
$paddings = ['15px','18px','20px','22px','25px'];
// Inject random invisible comment
$comment = '<!-- ' . bin2hex(random_bytes(4)) . ' -->';
$html = preg_replace('/<body[^>]*>/', '$0' . $comment, $html, 1);
// Randomize font-family if present
$html = preg_replace_callback('/font-family:\s*[^;"]+/', function($m) use ($font_families) {
return 'font-family:' . $font_families[array_rand($font_families)];
}, $html, 1);
// Add random zero-width spaces in text (invisible but unique)
$zwsp = ['&#8203;', '&#65279;', '&#8204;'];
$html = preg_replace_callback('/>[^<]{20,}/', function($m) use ($zwsp) {
$pos = rand(5, max(5, strlen($m[0])-5));
return substr($m[0], 0, $pos) . $zwsp[array_rand($zwsp)] . substr($m[0], $pos);
}, $html, 3);
// Random padding on body/wrapper
$html = preg_replace('/padding:\s*\d+px/', 'padding:' . $paddings[array_rand($paddings)], $html, 1);
return $html;
}
/**
* HOOK 9: Link Wrapping (already handled by inject_tracking, but add cloaking)
*/
function hook_cloak_links($html, $tracking_domain = 'https://track.wevup.app') {
// Links are already wrapped by inject_tracking_full() in mta_helper.php
// This adds additional cloaking: randomize link text, add title attributes
$titles = ['Click here', 'Learn more', 'View details', 'See more', 'Continue reading',
'Get started', 'Find out more', 'Discover', 'Open now', 'Read more'];
$html = preg_replace_callback('/<a ([^>]*href=[^>]*)>/', function($m) use ($titles) {
$t = $titles[array_rand($titles)];
if(strpos($m[1], 'title=') === false) {
return '<a ' . $m[1] . ' title="' . $t . '">';
}
return $m[0];
}, $html, 5);
return $html;
}
/**
* HOOK 10: Predictive Timing Check
* Return whether NOW is a good time to send for this ISP
*/
function hook_check_timing($isp) {
$db = pipeline_db();
$hour = (int)date('G'); // 0-23
$dow = date('N'); // 1=Mon 7=Sun
// Check predictive data
$r = @pg_query_params($db,
"SELECT 0::numeric as avg_open FROM admin.send_schedule
WHERE hour = $1 AND isp = $2", [$hour, $isp]);
$data = $r ? pg_fetch_assoc($r) : null;
// Default good hours by ISP type
$good_hours = [
'gmail' => [8,9,10,11,14,15,16],
'outlook' => [7,8,9,10,11,13,14,15],
'yahoo' => [9,10,11,12,14,15],
'gmx' => [8,9,10,11,14,15],
't-online' => [7,8,9,10,14,15],
'default' => [8,9,10,11,14,15,16]
];
$isp_hours = $good_hours[strtolower($isp)] ?? $good_hours['default'];
$is_good = in_array($hour, $isp_hours);
// Weekend penalty
if($dow >= 6) $is_good = false;
return [
'current_hour' => $hour,
'day_of_week' => $dow,
'is_good_time' => $is_good,
'recommended_hours' => $isp_hours,
'db_avg_open' => $data['avg_open'] ?? null
];
}
// ===================== POST-SEND HOOKS =====================
/**
* POST-HOOK 1: Feed Realtime Analytics
*/
function hook_post_realtime($email, $isp, $status, $method, $tracking_id) {
$db = pipeline_db();
// Update today's counters
$today = date('Y-m-d');
pg_query_params($db,
"INSERT INTO admin.revenue (date, emails_sent) VALUES ($1, 1)
ON CONFLICT (date) DO UPDATE SET emails_sent = admin.revenue.emails_sent + 1",
[$today]);
// Could also feed realtime-analytics.php via internal call
}
/**
* POST-HOOK 2: Track Creative Performance
*/
function hook_post_creative_track($subject, $offer_id, $isp, $status) {
$db = pipeline_db();
$subj_esc = pg_escape_string($db, $subject);
// Upsert creative performance
pg_query($db, "INSERT INTO admin.creative_performance
(subject_line, offer_id, isp, sends, status)
VALUES ('$subj_esc', $offer_id, '".pg_escape_string($db,$isp)."', 1, '$status')
ON CONFLICT (subject_line, offer_id, isp) DO UPDATE
SET sends = admin.creative_performance.sends + 1");
}
/**
* POST-HOOK 3: Feed Brain Learning
*/
function hook_post_brain_learn($isp, $method, $status, $config_data = []) {
$db = pipeline_db();
pg_query_params($db,
"INSERT INTO admin.brain_learning_log (isp, send_method, status, details, logged_at)
VALUES ($1, $2, $3, $4, NOW())",
[$isp, $method, $status, json_encode($config_data)]);
}
/**
* POST-HOOK 4: Update Offer Quality
*/
function hook_post_offer_quality($offer_id, $status) {
if(!$offer_id) return;
$db = pipeline_db();
$field = ($status === 'sent') ? 'sends' : 'failures';
pg_query($db, "UPDATE admin.affiliate_offers SET
total_sent = COALESCE(total_sent,0) + 1
WHERE id = $offer_id");
}
// ===================== MASTER PIPELINE RUNNER =====================
/**
* Run ALL pre-send hooks on an email before sending
* Returns enriched send data or ['skip' => true] if should not send
*/
function pipeline_pre_send($to, $subject, $html, $isp, $offer_id = 0, $domain = 'wevup.app') {
$result = [
'to' => $to,
'subject' => $subject,
'html' => $html,
'isp' => $isp,
'domain' => $domain,
'skip' => false,
'hooks_applied' => [],
];
// 1. Suppression check
$supp = hook_check_suppression($to);
if($supp['blocked']) {
$result['skip'] = true;
$result['skip_reason'] = 'suppressed: ' . $supp['reason'];
return $result;
}
$result['hooks_applied'][] = 'suppression_check';
// 2. Trap detection
$trap = hook_check_trap($to);
if($trap['is_trap']) {
$result['skip'] = true;
$result['skip_reason'] = 'trap: ' . $trap['type'];
return $result;
}
$result['hooks_applied'][] = 'trap_detection';
// 3. Domain rotation (only if not forced)
$best_domain = hook_select_domain($isp, $domain);
if($best_domain !== $domain) {
$result['domain'] = $best_domain;
$result['hooks_applied'][] = 'domain_rotation';
}
// 4. Persona rotation
$persona = hook_select_persona($isp, $result['domain']);
$result['from_name'] = $persona['from_name'];
$result['from_email'] = $persona['from_email'];
$result['hooks_applied'][] = 'persona_rotation';
// 5. Creative optimization
$creative = hook_optimize_creative($isp, $offer_id, $subject, $html);
if($creative['optimized']) {
$result['subject'] = $creative['subject'];
$result['hooks_applied'][] = 'creative_optimization';
}
// 6. Filter intelligence
$headers = [];
$filter = hook_apply_filter_rules($isp, $headers, $result['html']);
$result['filter_warnings'] = $filter['warnings'];
$result['hooks_applied'][] = 'filter_intelligence';
// 7. Header enrichment
$result['exchange_headers'] = hook_build_exchange_headers(
$result['from_name'], $result['from_email'],
$result['subject'], $result['domain'], $to
);
$result['hooks_applied'][] = 'header_enrichment';
// 8. Pattern shuffling
$result['html'] = hook_shuffle_pattern($result['html']);
$result['hooks_applied'][] = 'pattern_shuffling';
// 9. Link cloaking
$result['html'] = hook_cloak_links($result['html']);
$result['hooks_applied'][] = 'link_cloaking';
// 10. Timing check
$timing = hook_check_timing($isp);
$result['timing'] = $timing;
if(!$timing['is_good_time']) {
$result['timing_warning'] = "Not optimal hour ({$timing['current_hour']}h) for $isp";
}
$result['hooks_applied'][] = 'predictive_timing';
return $result;
}
/**
* Run ALL post-send hooks after an email is sent
*/
function pipeline_post_send($to, $isp, $status, $method, $tracking_id, $subject = '', $offer_id = 0) {
// 1. Realtime analytics
hook_post_realtime($to, $isp, $status, $method, $tracking_id);
// 2. Creative tracking
if($subject && $offer_id) {
hook_post_creative_track($subject, $offer_id, $isp, $status);
}
// 3. Brain learning
hook_post_brain_learn($isp, $method, $status);
// 4. Offer quality
if($offer_id) {
hook_post_offer_quality($offer_id, $status);
}
}