426 lines
20 KiB
PHP
Executable File
426 lines
20 KiB
PHP
Executable File
<?php
|
|
// MTA Helper V4 — Brain-Driven Smart Routing
|
|
// Reads ALL methods from brain_configs (134 configs, 45 methods, 22 types)
|
|
// Brain picks winner per ISP, falls back to exploration
|
|
require_once("/opt/wevads/config/pipeline_hooks.php");
|
|
|
|
function smart_route_send($to, $subject, $html, $domain='wevup.app', $from_name='Info', $from_email='') {
|
|
$isp = strtoupper(detect_isp($to));
|
|
$db = @pg_connect("host=localhost dbname=adx_system user=admin password=admin123");
|
|
if(!$db) return mta_eu_send($to, $subject, $html, $domain, $from_name, $from_email);
|
|
@pg_query($db, "SET search_path TO admin,public");
|
|
|
|
// 1. Check brain_configs for a winner config for this ISP
|
|
$r = @pg_query_params($db, "SELECT id, send_method, from_name as cfg_from_name, from_email as cfg_from_email,
|
|
domain_used, smtp_type, smtp_account_id, inbox_rate,
|
|
header_1_name, header_1_value, header_2_name, header_2_value,
|
|
header_3_name, header_3_value, header_4_name, header_4_value,
|
|
content_type, encoding, charset, dkim_selector, ip_used, return_path
|
|
FROM brain_configs
|
|
WHERE isp_target=$1 AND is_winner=true AND is_active=true
|
|
ORDER BY inbox_rate DESC, consecutive_inbox DESC LIMIT 1", [$isp]);
|
|
$winner = $r ? @pg_fetch_assoc($r) : null;
|
|
|
|
// 2. If no winner, check isp_methods for default method
|
|
if(!$winner) {
|
|
$r2 = @pg_query_params($db, "SELECT method FROM isp_methods WHERE isp_name=$1 LIMIT 1", [$isp]);
|
|
$isp_method = $r2 ? @pg_fetch_assoc($r2) : null;
|
|
if($isp_method) {
|
|
// Get best config for this ISP+method combo
|
|
$r3 = @pg_query_params($db, "SELECT id, send_method, from_name as cfg_from_name, from_email as cfg_from_email,
|
|
domain_used, smtp_type, smtp_account_id, inbox_rate,
|
|
header_1_name, header_1_value, header_2_name, header_2_value,
|
|
header_3_name, header_3_value, header_4_name, header_4_value,
|
|
content_type, encoding, charset, dkim_selector, ip_used, return_path
|
|
FROM brain_configs
|
|
WHERE isp_target=$1 AND send_method=$2 AND is_active=true
|
|
ORDER BY inbox_rate DESC LIMIT 1", [$isp, $isp_method['method']]);
|
|
$winner = $r3 ? @pg_fetch_assoc($r3) : null;
|
|
}
|
|
}
|
|
|
|
// 3. If still no config, explore least-tested method
|
|
if(!$winner) {
|
|
$r4 = @pg_query_params($db, "SELECT id, send_method, from_name as cfg_from_name, from_email as cfg_from_email,
|
|
domain_used, smtp_type, smtp_account_id, inbox_rate,
|
|
header_1_name, header_1_value, header_2_name, header_2_value,
|
|
header_3_name, header_3_value, header_4_name, header_4_value,
|
|
content_type, encoding, charset, dkim_selector, ip_used, return_path
|
|
FROM brain_configs
|
|
WHERE isp_target=$1 AND is_active=true
|
|
ORDER BY total_sent ASC, inbox_rate DESC LIMIT 1", [$isp]);
|
|
$winner = $r4 ? @pg_fetch_assoc($r4) : null;
|
|
}
|
|
|
|
// Execute the chosen method
|
|
$method = $winner ? $winner['send_method'] : 'MTA_EU_RELAY';
|
|
$config_id = $winner ? $winner['id'] : 0;
|
|
|
|
$result = execute_send_method($to, $subject, $html, $domain, $from_name, $from_email, $method, $winner, $db);
|
|
|
|
// Log for brain learning
|
|
$status = strpos($result, 'OK') !== false ? 'sent' : 'failed';
|
|
@pg_query_params($db, "UPDATE brain_configs SET total_sent=COALESCE(total_sent,0)+1, updated_at=NOW() WHERE id=$1", [$config_id]);
|
|
brain_log_send(strtolower($isp), $method, $to, $status);
|
|
|
|
return $result;
|
|
}
|
|
|
|
function execute_send_method($to, $subject, $html, $domain, $from_name, $from_email, $method, $config, $db) {
|
|
// Template vars
|
|
$html = process_template_vars($html, $to);
|
|
$subject = process_template_vars($subject, $to);
|
|
|
|
switch($method) {
|
|
case 'O365_GRAPH':
|
|
case 'GRAPH_API':
|
|
return o365_graph_send($to, $subject, $html);
|
|
|
|
case 'OFFICE_365':
|
|
case 'O365_SMTP':
|
|
case 'O365_EXCHANGE':
|
|
case 'PMTA_O365':
|
|
return o365_smtp_send($to, $subject, $html, $config, $db);
|
|
|
|
case 'GSUITE_RELAY':
|
|
case 'GSUITE_SMTP':
|
|
return gsuite_relay_send($to, $subject, $html, $config);
|
|
|
|
case 'DOMAIN_IP':
|
|
case 'DIRECT_MX':
|
|
case 'PMTA_DIRECT':
|
|
return mta_eu_send($to, $subject, $html, $domain, $from_name, $from_email);
|
|
|
|
case 'MTA_EU_RELAY':
|
|
return mta_eu_send($to, $subject, $html, $domain, $from_name, $from_email);
|
|
|
|
case 'SENDGRID':
|
|
case 'MAILGUN':
|
|
case 'AMAZON_SES':
|
|
case 'BREVO':
|
|
case 'MAILJET':
|
|
case 'SPARKPOST':
|
|
case 'POSTMARK':
|
|
case 'ELASTICEMAIL':
|
|
case 'TURBOSMTP':
|
|
case 'SMTP2GO':
|
|
case 'ZOHO':
|
|
return smtp_api_send($to, $subject, $html, $method, $config, $db);
|
|
|
|
case 'FIREBASE':
|
|
return "SKIP:firebase_not_email";
|
|
|
|
default:
|
|
// Try MTA-EU as universal fallback
|
|
return mta_eu_send($to, $subject, $html, $domain, $from_name, $from_email);
|
|
}
|
|
}
|
|
|
|
// O365 SMTP Send (for accounts without Graph API — uses SMTP auth)
|
|
function o365_smtp_send($to, $subject, $html, $config, $db) {
|
|
// Pick a valid O365 account
|
|
$r = @pg_query($db, "SELECT admin_email, admin_password FROM office_accounts
|
|
WHERE status='Active' AND (password_status='valid' OR password_status='graph_ok')
|
|
AND admin_password IS NOT NULL AND admin_password != ''
|
|
ORDER BY RANDOM() LIMIT 1");
|
|
$acc = $r ? @pg_fetch_assoc($r) : null;
|
|
if(!$acc || !$acc['admin_password']) return "FAIL:no_o365_smtp_account";
|
|
|
|
$from = $acc['admin_email'];
|
|
$pass = $acc['admin_password'];
|
|
|
|
// Check if password is encrypted
|
|
if(function_exists('wevads_decrypt')) $pass = wevads_decrypt($pass);
|
|
|
|
// Build headers from config
|
|
$headers = build_headers_from_config($from, $to, $subject, $config);
|
|
|
|
// Connect via SMTP to O365
|
|
$fp = @fsockopen('ssl://smtp.office365.com', 587, $errno, $errstr, 10);
|
|
if(!$fp) {
|
|
// Try STARTTLS on 587
|
|
$fp = @fsockopen('tcp://smtp.office365.com', 587, $errno, $errstr, 10);
|
|
if(!$fp) return "FAIL:O365_SMTP:$errstr";
|
|
$resp = fgets($fp, 512);
|
|
fputs($fp, "EHLO wevup.app\r\n");
|
|
while($l = fgets($fp, 512)) { if(substr($l,3,1)==' ') break; }
|
|
fputs($fp, "STARTTLS\r\n"); $resp = fgets($fp, 512);
|
|
stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
|
|
}
|
|
|
|
fputs($fp, "EHLO wevup.app\r\n");
|
|
while($l = fgets($fp, 512)) { if(substr($l,3,1)==' ') break; }
|
|
fputs($fp, "AUTH LOGIN\r\n"); $resp = fgets($fp, 512);
|
|
fputs($fp, base64_encode($from)."\r\n"); $resp = fgets($fp, 512);
|
|
fputs($fp, base64_encode($pass)."\r\n"); $resp = fgets($fp, 512);
|
|
if(substr($resp,0,3)!='235') { fclose($fp); return "FAIL:O365_AUTH:$resp"; }
|
|
|
|
fputs($fp, "MAIL FROM:<$from>\r\n"); $resp = fgets($fp, 512);
|
|
fputs($fp, "RCPT TO:<$to>\r\n"); $resp = fgets($fp, 512);
|
|
fputs($fp, "DATA\r\n"); $resp = fgets($fp, 512);
|
|
fputs($fp, $headers . "\r\n" . $html . "\r\n.\r\n"); $resp = fgets($fp, 512);
|
|
fputs($fp, "QUIT\r\n"); fclose($fp);
|
|
|
|
return substr($resp,0,3)=='250' ? "OK:O365_SMTP:$from" : "FAIL:O365_SMTP:$resp";
|
|
}
|
|
|
|
// GSuite Relay Send
|
|
function gsuite_relay_send($to, $subject, $html, $config) {
|
|
// Uses smtp-relay.gmail.com with authorized IP
|
|
$fp = @fsockopen('smtp-relay.gmail.com', 25, $errno, $errstr, 10);
|
|
if(!$fp) return "FAIL:GSUITE:$errstr";
|
|
|
|
$domain = $config['domain_used'] ?? 'wevup.app';
|
|
$from = $config['cfg_from_email'] ?? "info@$domain";
|
|
|
|
$resp = fgets($fp, 512);
|
|
fputs($fp, "EHLO $domain\r\n"); $resp = fgets($fp, 512);
|
|
while(substr($resp,3,1)=='-') $resp = fgets($fp, 512);
|
|
fputs($fp, "MAIL FROM:<$from>\r\n"); $resp = fgets($fp, 512);
|
|
fputs($fp, "RCPT TO:<$to>\r\n"); $resp = fgets($fp, 512);
|
|
fputs($fp, "DATA\r\n"); $resp = fgets($fp, 512);
|
|
|
|
$headers = "From: " . ($config['cfg_from_name'] ?? 'Info') . " <$from>\r\n";
|
|
$headers .= "To: $to\r\nSubject: $subject\r\nDate: " . date('r') . "\r\n";
|
|
$headers .= "MIME-Version: 1.0\r\nContent-Type: text/html; charset=utf-8\r\n";
|
|
|
|
fputs($fp, $headers . "\r\n" . $html . "\r\n.\r\n"); $resp = fgets($fp, 512);
|
|
fputs($fp, "QUIT\r\n"); fclose($fp);
|
|
|
|
return substr($resp,0,3)=='250' ? "OK:GSUITE_RELAY" : "FAIL:GSUITE:$resp";
|
|
}
|
|
|
|
// Generic SMTP/API Send for third-party providers
|
|
function smtp_api_send($to, $subject, $html, $method, $config, $db) {
|
|
// Get SMTP config from send_methods table
|
|
$r = @pg_query_params($db, "SELECT config FROM send_methods WHERE method_key=$1", [$method]);
|
|
$sm = $r ? @pg_fetch_assoc($r) : null;
|
|
if(!$sm) return "FAIL:no_config_for_$method";
|
|
|
|
$cfg = json_decode($sm['config'], true);
|
|
$host = $cfg['host'] ?? '';
|
|
$port = $cfg['port'] ?? 587;
|
|
if(!$host) return "FAIL:no_host_for_$method";
|
|
|
|
// Check smtp_configs for credentials
|
|
$r2 = @pg_query_params($db, "SELECT username, password, api_key FROM smtp_configs WHERE provider=$1 AND is_active=true LIMIT 1", [strtolower($method)]);
|
|
$creds = $r2 ? @pg_fetch_assoc($r2) : null;
|
|
if(!$creds) return "FAIL:no_creds_for_$method";
|
|
|
|
$from = $creds['username'] ?? "info@wevup.app";
|
|
|
|
// SMTP connect
|
|
$fp = @fsockopen("tcp://$host", $port, $errno, $errstr, 10);
|
|
if(!$fp) return "FAIL:{$method}_CONNECT:$errstr";
|
|
|
|
$resp = fgets($fp, 512);
|
|
fputs($fp, "EHLO wevup.app\r\n");
|
|
while($l = fgets($fp, 512)) { if(substr($l,3,1)==' ') break; }
|
|
fputs($fp, "STARTTLS\r\n"); $resp = fgets($fp, 512);
|
|
if(substr($resp,0,3)=='220') stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
|
|
|
|
fputs($fp, "EHLO wevup.app\r\n");
|
|
while($l = fgets($fp, 512)) { if(substr($l,3,1)==' ') break; }
|
|
|
|
// AUTH
|
|
$user = $creds['api_key'] ?? $creds['username'] ?? '';
|
|
$pass = $creds['password'] ?? '';
|
|
fputs($fp, "AUTH LOGIN\r\n"); fgets($fp, 512);
|
|
fputs($fp, base64_encode($user)."\r\n"); fgets($fp, 512);
|
|
fputs($fp, base64_encode($pass)."\r\n"); $resp = fgets($fp, 512);
|
|
if(substr($resp,0,3)!='235') { fclose($fp); return "FAIL:{$method}_AUTH:$resp"; }
|
|
|
|
fputs($fp, "MAIL FROM:<$from>\r\n"); fgets($fp, 512);
|
|
fputs($fp, "RCPT TO:<$to>\r\n"); fgets($fp, 512);
|
|
fputs($fp, "DATA\r\n"); fgets($fp, 512);
|
|
|
|
$headers = "From: Info <$from>\r\nTo: $to\r\nSubject: $subject\r\n";
|
|
$headers .= "Date: ".date('r')."\r\nMIME-Version: 1.0\r\nContent-Type: text/html; charset=utf-8\r\n";
|
|
|
|
fputs($fp, $headers . "\r\n" . $html . "\r\n.\r\n"); $resp = fgets($fp, 512);
|
|
fputs($fp, "QUIT\r\n"); fclose($fp);
|
|
|
|
return substr($resp,0,3)=='250' ? "OK:$method" : "FAIL:$method:$resp";
|
|
}
|
|
|
|
// Build headers from brain_config
|
|
function build_headers_from_config($from, $to, $subject, $config) {
|
|
$headers = "From: " . ($config['cfg_from_name'] ?? 'Info') . " <$from>\r\n";
|
|
$headers .= "To: $to\r\nSubject: $subject\r\nDate: " . date('r') . "\r\n";
|
|
$headers .= "MIME-Version: 1.0\r\n";
|
|
|
|
// Add custom headers from config
|
|
for($i=1; $i<=4; $i++) {
|
|
$name = $config["header_{$i}_name"] ?? '';
|
|
$value = $config["header_{$i}_value"] ?? '';
|
|
if($name && $value) $headers .= "$name: $value\r\n";
|
|
}
|
|
|
|
$ct = $config['content_type'] ?? 'text/html; charset=utf-8';
|
|
$headers .= "Content-Type: $ct\r\n";
|
|
|
|
return $headers;
|
|
}
|
|
|
|
// ============================================================
|
|
// EXISTING FUNCTIONS (preserved from V3)
|
|
// ============================================================
|
|
|
|
function mta_eu_send($to, $subject, $html, $domain='wevup.app', $from_name='Info', $from_email='') {
|
|
if(!$from_email) $from_email = "info@$domain";
|
|
$html = process_template_vars($html, $to);
|
|
$subject = process_template_vars($subject, $to);
|
|
|
|
$payload = json_encode(['to'=>$to,'subject'=>$subject,'body'=>$html,'domain'=>$domain,'from_name'=>$from_name,'from_email'=>$from_email]);
|
|
$tmpLocal = tempnam('/tmp', 'mta_');
|
|
file_put_contents($tmpLocal, $payload);
|
|
|
|
$b64 = base64_encode($payload);
|
|
$remoteFile = '/tmp/send_' . basename($tmpLocal);
|
|
$cmd = "sshpass -p 'HLkFvJJf3uJv' ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 root@89.167.1.139 " .
|
|
"'echo " . escapeshellarg($b64) . " | base64 -d > " . $remoteFile .
|
|
" && python3 /opt/bcg_local.py " . $remoteFile .
|
|
" && rm -f " . $remoteFile . "' 2>&1";
|
|
$result = trim(shell_exec($cmd));
|
|
@unlink($tmpLocal);
|
|
|
|
if(strpos($result, 'OK') !== false) return "OK:MTA-EU-89.167.1.139";
|
|
|
|
// Fallback raw SMTP
|
|
return mta_eu_smtp_fallback($to, $subject, $html, $domain, $from_name, $from_email);
|
|
}
|
|
|
|
function mta_eu_smtp_fallback($to, $subject, $html, $domain, $from_name, $from_email) {
|
|
$mc_user = substr(md5(uniqid()), 0, 25);
|
|
$msg_id = "<$mc_user." . substr(uniqid(),0,14) . "@mail.$domain>";
|
|
$headers = "From: $from_name <$from_email>\r\n";
|
|
$headers .= "To: $to\r\nSubject: $subject\r\nDate: ".date('r')."\r\n";
|
|
$headers .= "Message-ID: $msg_id\r\nMIME-Version: 1.0\r\n";
|
|
$headers .= "List-Unsubscribe: <mailto:unsub@$domain?subject=unsubscribe>\r\n";
|
|
$headers .= "List-Unsubscribe-Post: List-Unsubscribe=One-Click\r\n";
|
|
$headers .= "Content-Type: text/html; charset=utf-8\r\n";
|
|
$fp = @fsockopen('89.167.1.139', 25, $errno, $errstr, 10);
|
|
if(!$fp) return "FAIL:MTA-EU:$errstr";
|
|
$resp = fgets($fp, 512);
|
|
fputs($fp, "EHLO $domain\r\n"); $resp = fgets($fp, 512);
|
|
while(substr($resp,3,1)=='-') $resp = fgets($fp, 512);
|
|
fputs($fp, "MAIL FROM:<$from_email>\r\n"); $resp = fgets($fp, 512);
|
|
if(substr($resp,0,3)!='250') { fclose($fp); return "FAIL:MAIL_FROM:$resp"; }
|
|
fputs($fp, "RCPT TO:<$to>\r\n"); $resp = fgets($fp, 512);
|
|
if(substr($resp,0,3)!='250') { fclose($fp); return "FAIL:RCPT_TO:$resp"; }
|
|
fputs($fp, "DATA\r\n"); $resp = fgets($fp, 512);
|
|
if(substr($resp,0,3)!='354') { fclose($fp); return "FAIL:DATA:$resp"; }
|
|
fputs($fp, $headers . "\r\n" . $html . "\r\n.\r\n"); $resp = fgets($fp, 512);
|
|
fputs($fp, "QUIT\r\n"); fclose($fp);
|
|
return substr($resp,0,3)=='250' ? "OK:MTA-EU-FALLBACK" : "FAIL:$resp";
|
|
}
|
|
|
|
function o365_graph_send($to, $subject, $html, $from_name=null, $from_email=null) {
|
|
static $last_brand = [];
|
|
$db = pg_connect("host=localhost dbname=adx_system user=admin password=admin123");
|
|
pg_query($db, "SET search_path TO admin,public");
|
|
$html = process_template_vars($html, $to);
|
|
$subject = process_template_vars($subject, $to);
|
|
|
|
// Pick a sending account (graph_send = has mailbox)
|
|
$r = pg_query($db, "SELECT admin_email, tenant_id, app_id, app_secret, brand FROM office_accounts WHERE password_status='graph_send' ORDER BY RANDOM() LIMIT 1");
|
|
$acc = $r ? pg_fetch_assoc($r) : null;
|
|
if(!$acc) return "FAIL:no_graph_send_account";
|
|
|
|
// Get OAuth token
|
|
$ch = curl_init("https://login.microsoftonline.com/{$acc['tenant_id']}/oauth2/v2.0/token");
|
|
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true,CURLOPT_POST=>true,CURLOPT_TIMEOUT=>10,
|
|
CURLOPT_POSTFIELDS=>http_build_query(['client_id'=>$acc['app_id'],'client_secret'=>$acc['app_secret'],
|
|
'scope'=>'https://graph.microsoft.com/.default','grant_type'=>'client_credentials'])]);
|
|
$token = json_decode(curl_exec($ch),true)['access_token'] ?? null;
|
|
if(!$token) return "FAIL:O365_TOKEN";
|
|
|
|
// Update displayName if brand changed for this account
|
|
$brand = $from_name ?: 'Service';
|
|
$key = $acc['admin_email'];
|
|
if(!isset($last_brand[$key]) || $last_brand[$key] !== $brand) {
|
|
$ch = curl_init("https://graph.microsoft.com/v1.0/users/" . urlencode($acc['admin_email']));
|
|
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_CUSTOMREQUEST=>"PATCH", CURLOPT_TIMEOUT=>5,
|
|
CURLOPT_HTTPHEADER=>["Authorization: Bearer $token", "Content-Type: application/json"],
|
|
CURLOPT_POSTFIELDS=>json_encode(["displayName"=>$brand])]);
|
|
curl_exec($ch);
|
|
$last_brand[$key] = $brand;
|
|
usleep(500000); // 500ms for propagation
|
|
}
|
|
|
|
// Send
|
|
$payload = json_encode(['message'=>['subject'=>$subject,'body'=>['contentType'=>'HTML','content'=>$html],
|
|
'toRecipients'=>[['emailAddress'=>['address'=>$to]]]],'saveToSentItems'=>false]);
|
|
|
|
$ch = curl_init("https://graph.microsoft.com/v1.0/users/" . urlencode($acc['admin_email']) . "/sendMail");
|
|
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true,CURLOPT_POST=>true,CURLOPT_TIMEOUT=>15,
|
|
CURLOPT_HTTPHEADER=>["Authorization: Bearer $token","Content-Type: application/json"],
|
|
CURLOPT_POSTFIELDS=>$payload]);
|
|
$resp = curl_exec($ch);
|
|
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
|
|
return $code==202 ? "OK:O365-GRAPH:{$brand}<{$acc['admin_email']}>" : "FAIL:O365:HTTP{$code}:" . substr($resp,0,200);
|
|
}
|
|
|
|
function process_template_vars($text, $to) {
|
|
$parts = explode('@', $to);
|
|
$local = $parts[0] ?? '';
|
|
$first = ucfirst(preg_replace('/[^a-z]/i', '', explode('.', $local)[0] ?? 'Customer'));
|
|
if(strlen($first)<2 || strlen($first)>20) $first = 'Customer';
|
|
$tid = 'T_' . bin2hex(random_bytes(8));
|
|
return str_replace(
|
|
['{tid}','{first_name}','{email}','{domain}','{date}','{unsubscribe}'],
|
|
[$tid, $first, $to, $parts[1]??'', date('d.m.Y'), '#'],
|
|
$text
|
|
);
|
|
}
|
|
|
|
function inject_tracking($html, $tid) { return inject_tracking_full($html, $tid, 0, ''); }
|
|
|
|
function inject_tracking_full($html, $tid, $offer_id=0, $offer_url='') {
|
|
$td = 'https://track.wevup.app';
|
|
$pixel = "<img src=\"{$td}/api/open.php?t={$tid}\" width=\"1\" height=\"1\" style=\"display:none\" />";
|
|
$html = strpos($html,'</body>')!==false ? str_replace('</body>',$pixel.'</body>',$html) : $html.$pixel;
|
|
if($offer_url) {
|
|
$click = "{$td}/api/click.php?t={$tid}&o={$offer_id}";
|
|
$html = preg_replace('/href=["\']([^"\']+)["\']/', 'href="'.$click.'"', $html, 1);
|
|
}
|
|
return $html;
|
|
}
|
|
|
|
if(!function_exists('detect_isp')) {
|
|
function detect_isp($email) {
|
|
$d = strtolower(substr(strrchr($email, "@"), 1));
|
|
$map = ['gmail.com'=>'gmail','googlemail.com'=>'gmail',
|
|
'outlook.com'=>'outlook','hotmail.com'=>'outlook','live.com'=>'outlook','msn.com'=>'outlook',
|
|
'yahoo.com'=>'yahoo','yahoo.de'=>'yahoo','yahoo.fr'=>'yahoo','ymail.com'=>'yahoo',
|
|
'gmx.de'=>'gmx','gmx.net'=>'gmx','gmx.at'=>'gmx','gmx.ch'=>'gmx',
|
|
'web.de'=>'web.de','t-online.de'=>'t-online','aol.com'=>'aol',
|
|
'icloud.com'=>'icloud','me.com'=>'icloud',
|
|
'protonmail.com'=>'protonmail','proton.me'=>'protonmail',
|
|
'mail.ru'=>'mail.ru','freenet.de'=>'freenet','arcor.de'=>'arcor',
|
|
'alice.it'=>'alice','tin.it'=>'alice','virgilio.it'=>'alice','tim.it'=>'alice',
|
|
'ziggo.nl'=>'ziggo','home.nl'=>'ziggo','chello.nl'=>'ziggo',
|
|
'videotron.ca'=>'videotron','videotron.qc.ca'=>'videotron',
|
|
'virginmedia.com'=>'virginmedia','ntlworld.com'=>'virginmedia',
|
|
'kpnmail.nl'=>'kpn','orange.fr'=>'orange','sfr.fr'=>'sfr',
|
|
'laposte.net'=>'laposte','libero.it'=>'libero',
|
|
'o2online.de'=>'o2','bluewin.ch'=>'bluewin',
|
|
];
|
|
return $map[$d] ?? explode('.', $d)[0];
|
|
}
|
|
}
|
|
|
|
function brain_log_send($isp, $method, $to, $status) {
|
|
$db = @pg_connect("host=localhost dbname=adx_system user=admin password=admin123");
|
|
if(!$db) return;
|
|
@pg_query($db, "SET search_path TO admin,public");
|
|
@pg_query_params($db, "INSERT INTO brain_method_scores (isp, method_name, tests_total, tests_delivered, last_test)
|
|
VALUES ($1, $2, 1, CASE WHEN $3='sent' THEN 1 ELSE 0 END, NOW())
|
|
ON CONFLICT (isp, method_name) DO UPDATE SET
|
|
tests_total = brain_method_scores.tests_total + 1,
|
|
tests_delivered = brain_method_scores.tests_delivered + CASE WHEN $3='sent' THEN 1 ELSE 0 END,
|
|
delivery_rate = ROUND(100.0 * (brain_method_scores.tests_delivered + CASE WHEN $3='sent' THEN 1 ELSE 0 END) / (brain_method_scores.tests_total + 1), 2),
|
|
last_test = NOW(), updated_at = NOW()", [$isp, $method, $status]);
|
|
}
|