235 lines
11 KiB
PHP
235 lines
11 KiB
PHP
<?php
|
|
/**
|
|
* Test ALL send engines to ymahboub@weval-consulting.com
|
|
* Each engine sends 1 email with a real ADX creative
|
|
*/
|
|
error_reporting(E_ALL);
|
|
ini_set('display_errors', 1);
|
|
|
|
$TO = 'ymahboub@weval-consulting.com';
|
|
$TRACK_DOMAIN = 'culturellemejean.charity';
|
|
$TRACK_SERVER = '151.80.235.110';
|
|
|
|
$pdo = new PDO('pgsql:host=localhost;dbname=adx_system', 'admin', 'admin123');
|
|
$pdo->exec('SET search_path TO admin, affiliate, production, public');
|
|
|
|
// Pick a real creative
|
|
$creative = $pdo->query("SELECT oc.*, o.name as offer_name, o.payout
|
|
FROM admin.offer_creatives oc
|
|
LEFT JOIN admin.offers o ON o.id = oc.offer_id
|
|
WHERE oc.status='active' AND oc.html_body IS NOT NULL AND oc.html_body != ''
|
|
ORDER BY RANDOM() LIMIT 1")->fetch(PDO::FETCH_ASSOC);
|
|
|
|
echo "Creative: #{['id']} - {['creative_name']}\n";
|
|
echo "Landing: {['landing_url']}\n";
|
|
echo "Subject: {['subject_line']}\n\n";
|
|
|
|
// Build the proper body with all replacements
|
|
function buildBody($creative, $to, $trackServer, $trackDomain, $engineTag) {
|
|
$sendId = uniqid('wv');
|
|
$contactId = 999999;
|
|
|
|
// Open pixel
|
|
$pixel = '<img src="http://' . $trackServer . '/op/0_md/1/0/' . intval($creative['offer_id'] ?? 1) . '/0/' . $contactId . '" width="1" height="1" style="display:none" />';
|
|
|
|
// Replace [open] and other ADX tags
|
|
$body = str_replace(
|
|
['[open]', '[unsub]', '[email]', '[domain]'],
|
|
[$pixel, 'https://' . $trackDomain . '/unsub/' . $contactId, $to, $trackDomain],
|
|
$creative['html_body']
|
|
);
|
|
|
|
// Inject sub_ids in offer URLs
|
|
$body = preg_replace_callback(
|
|
'/href="(https?:\/\/(?:www\.)?(?:rivoweb\.com|e36lbat\.com)[^"]*)"/',
|
|
function($m) use ($contactId, $creative, $sendId) {
|
|
$url = $m[1];
|
|
$sep = strpos($url, '?') !== false ? '&' : '?';
|
|
if (strpos($url, 'rivoweb') !== false) {
|
|
$url .= $sep . 'sub1=' . $contactId . '&sub2=' . ($creative['offer_id'] ?? 0) . '&sub3=wevads_' . $sendId;
|
|
} elseif (strpos($url, 'e36lbat') !== false) {
|
|
$url .= $sep . 's1=' . $contactId . '&s2=' . ($creative['offer_id'] ?? 0);
|
|
}
|
|
return 'href="' . $url . '"';
|
|
},
|
|
$body
|
|
);
|
|
|
|
// Add engine tag watermark
|
|
$body .= '<p style="font-size:10px;color:#666;margin-top:20px">Engine: ' . $engineTag . ' | Send ID: ' . $sendId . '</p>';
|
|
|
|
return '<!DOCTYPE html><html><head><meta charset="utf-8"></head><body>' . $body . '</body></html>';
|
|
}
|
|
|
|
// ══════════ ENGINE 1: graph_productive (Graph API with delegated token) ══════════
|
|
echo "--- ENGINE 1: graph_productive ---\n";
|
|
$sender = $pdo->query("SELECT ga.email, ga.object_id, ga.tenant_domain, gt.tenant_id, gt.client_id, gt.client_secret
|
|
FROM admin.graph_accounts ga
|
|
JOIN admin.graph_tenants gt ON gt.tenant_domain = ga.tenant_domain
|
|
WHERE ga.can_send=true AND ga.object_id IS NOT NULL AND ga.status='active' AND gt.status='active'
|
|
ORDER BY RANDOM() LIMIT 1")->fetch(PDO::FETCH_ASSOC);
|
|
|
|
if ($sender) {
|
|
// Get token
|
|
$ch = curl_init("https://login.microsoftonline.com/{$sender['tenant_id']}/oauth2/v2.0/token");
|
|
curl_setopt_array($ch, [CURLOPT_POST=>true, CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>10,
|
|
CURLOPT_POSTFIELDS=>http_build_query([
|
|
'client_id'=>$sender['client_id'], 'client_secret'=>$sender['client_secret'],
|
|
'scope'=>'https://graph.microsoft.com/.default', 'grant_type'=>'client_credentials'
|
|
])]);
|
|
$tok = json_decode(curl_exec($ch), true); curl_close($ch);
|
|
|
|
if (!empty($tok['access_token'])) {
|
|
$body = buildBody($creative, $TO, $TRACK_SERVER, $TRACK_DOMAIN, 'graph_productive');
|
|
$subject = '[TEST-1 graph_productive] ' . ($creative['subject_line'] ?: 'Offer');
|
|
|
|
$msg = json_encode([
|
|
'message' => [
|
|
'subject' => $subject,
|
|
'body' => ['contentType' => 'HTML', 'content' => $body],
|
|
'toRecipients' => [['emailAddress' => ['address' => $TO]]],
|
|
'from' => ['emailAddress' => ['name' => $creative['from_name'] ?: 'Member Services', 'address' => $sender['email']]]
|
|
],
|
|
'saveToSentItems' => false
|
|
]);
|
|
|
|
$ch = curl_init("https://graph.microsoft.com/v1.0/users/{$sender['object_id']}/sendMail");
|
|
curl_setopt_array($ch, [CURLOPT_POST=>true, CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>15,
|
|
CURLOPT_HTTPHEADER=>["Authorization: Bearer {$tok['access_token']}", "Content-Type: application/json"],
|
|
CURLOPT_POSTFIELDS=>$msg]);
|
|
$resp = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
|
|
echo " graph_productive: " . ($code == 202 ? "✅ SENT" : "❌ FAIL $code") . " from {$sender['email']}\n";
|
|
if ($code != 202) echo " Error: " . substr($resp, 0, 200) . "\n";
|
|
} else {
|
|
echo " ❌ Token failed: " . ($tok['error_description'] ?? 'unknown') . "\n";
|
|
}
|
|
} else {
|
|
echo " ❌ No graph sender found\n";
|
|
}
|
|
|
|
// ══════════ ENGINE 2: O365 SMTP (brain-unified-send sendViaO365) ══════════
|
|
echo "\n--- ENGINE 2: o365_smtp ---\n";
|
|
$acct = $pdo->query("SELECT admin_email, admin_password, tenant_domain FROM admin.office_accounts WHERE LOWER(status) IN ('verified','active') AND admin_password IS NOT NULL AND admin_password != '' ORDER BY RANDOM() LIMIT 1")->fetch(PDO::FETCH_ASSOC);
|
|
|
|
if ($acct) {
|
|
$body = buildBody($creative, $TO, $TRACK_SERVER, $TRACK_DOMAIN, 'o365_smtp');
|
|
$subject = '[TEST-2 o365_smtp] ' . ($creative['subject_line'] ?: 'Offer');
|
|
$from = $acct['admin_email'];
|
|
|
|
$sock = @fsockopen('smtp.office365.com', 587, $errno, $errstr, 10);
|
|
if ($sock) {
|
|
fgets($sock, 1024);
|
|
fputs($sock, "EHLO wevads.local\r\n");
|
|
while ($l = fgets($sock, 1024)) { if (substr(trim($l),3,1)===' ') break; }
|
|
|
|
fputs($sock, "STARTTLS\r\n");
|
|
$tlsR = fgets($sock, 1024);
|
|
if (strpos($tlsR, '220') !== false) {
|
|
stream_socket_enable_crypto($sock, true, STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT);
|
|
fputs($sock, "EHLO wevads.local\r\n");
|
|
while ($l = fgets($sock, 1024)) { if (substr(trim($l),3,1)===' ') break; }
|
|
|
|
fputs($sock, "AUTH LOGIN\r\n"); fgets($sock, 1024);
|
|
fputs($sock, base64_encode($from) . "\r\n"); fgets($sock, 1024);
|
|
fputs($sock, base64_encode($acct['admin_password']) . "\r\n");
|
|
$auth = fgets($sock, 1024);
|
|
|
|
if (strpos($auth, '235') !== false) {
|
|
$msgId = '<' . uniqid('o365_') . '@' . $acct['tenant_domain'] . '>';
|
|
$raw = "From: {$from}\r\nTo: {$TO}\r\nSubject: {$subject}\r\nMessage-ID: {$msgId}\r\nDate: " . date('r') . "\r\nMIME-Version: 1.0\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n" . $body;
|
|
|
|
fputs($sock, "MAIL FROM:<{$from}>\r\n"); fgets($sock, 1024);
|
|
fputs($sock, "RCPT TO:<{$TO}>\r\n"); fgets($sock, 1024);
|
|
fputs($sock, "DATA\r\n"); fgets($sock, 1024);
|
|
fputs($sock, $raw . "\r\n.\r\n");
|
|
$sendR = fgets($sock, 1024);
|
|
echo " o365_smtp: " . (strpos($sendR,'250')!==false ? "✅ SENT" : "❌ FAIL") . " from {$from}\n";
|
|
if (strpos($sendR,'250')===false) echo " SMTP: " . trim($sendR) . "\n";
|
|
} else {
|
|
echo " ❌ AUTH failed: " . trim($auth) . "\n";
|
|
}
|
|
}
|
|
fputs($sock, "QUIT\r\n"); fclose($sock);
|
|
} else {
|
|
echo " ❌ Connect failed: $errstr\n";
|
|
}
|
|
} else {
|
|
echo " ❌ No O365 account found\n";
|
|
}
|
|
|
|
// ══════════ ENGINE 3: PMTA (local port 25) ══════════
|
|
echo "\n--- ENGINE 3: pmta ---\n";
|
|
$body = buildBody($creative, $TO, $TRACK_SERVER, $TRACK_DOMAIN, 'pmta');
|
|
$subject = '[TEST-3 pmta] ' . ($creative['subject_line'] ?: 'Offer');
|
|
$pmtaFrom = 'test@' . $TRACK_DOMAIN;
|
|
|
|
$sock = @fsockopen('127.0.0.1', 25, $errno, $errstr, 5);
|
|
if ($sock) {
|
|
fgets($sock, 1024);
|
|
fputs($sock, "EHLO wevads.local\r\n");
|
|
stream_set_timeout($sock, 2);
|
|
while ($l = fgets($sock, 1024)) { if (substr(trim($l),3,1)===' ') break; }
|
|
|
|
$raw = "From: {$pmtaFrom}\r\nTo: {$TO}\r\nSubject: {$subject}\r\nDate: " . date('r') . "\r\nMIME-Version: 1.0\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n" . $body;
|
|
|
|
fputs($sock, "MAIL FROM:<{$pmtaFrom}>\r\n"); fgets($sock, 1024);
|
|
fputs($sock, "RCPT TO:<{$TO}>\r\n"); fgets($sock, 1024);
|
|
fputs($sock, "DATA\r\n"); fgets($sock, 1024);
|
|
fputs($sock, $raw . "\r\n.\r\n");
|
|
$sendR = fgets($sock, 1024);
|
|
echo " pmta: " . (strpos($sendR,'250')!==false ? "✅ SENT" : "❌ " . trim($sendR)) . " from {$pmtaFrom}\n";
|
|
fputs($sock, "QUIT\r\n"); fclose($sock);
|
|
} else {
|
|
echo " ❌ PMTA not running: $errstr\n";
|
|
}
|
|
|
|
// ══════════ ENGINE 4: Direct SMTP (MX lookup) ══════════
|
|
echo "\n--- ENGINE 4: direct_smtp (MX → weval-consulting.com) ---\n";
|
|
$body = buildBody($creative, $TO, $TRACK_SERVER, $TRACK_DOMAIN, 'direct_smtp');
|
|
$subject = '[TEST-4 direct] ' . ($creative['subject_line'] ?: 'Offer');
|
|
$directFrom = 'noreply@' . $TRACK_DOMAIN;
|
|
|
|
$domain = explode('@', $TO)[1];
|
|
$mxRecords = []; $mxWeights = [];
|
|
if (getmxrr($domain, $mxRecords, $mxWeights)) {
|
|
$mx = $mxRecords[0];
|
|
echo " MX: $mx\n";
|
|
$sock = @fsockopen($mx, 25, $errno, $errstr, 10);
|
|
if ($sock) {
|
|
fgets($sock, 1024);
|
|
fputs($sock, "EHLO {$TRACK_DOMAIN}\r\n");
|
|
stream_set_timeout($sock, 3);
|
|
while ($l = fgets($sock, 1024)) { if (substr(trim($l),3,1)===' ') break; }
|
|
|
|
// Try STARTTLS
|
|
fputs($sock, "STARTTLS\r\n");
|
|
$tls = fgets($sock, 1024);
|
|
if (strpos($tls, '220') !== false) {
|
|
stream_socket_enable_crypto($sock, true, STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT);
|
|
fputs($sock, "EHLO {$TRACK_DOMAIN}\r\n");
|
|
while ($l = fgets($sock, 1024)) { if (substr(trim($l),3,1)===' ') break; }
|
|
}
|
|
|
|
$raw = "From: {$directFrom}\r\nTo: {$TO}\r\nSubject: {$subject}\r\nDate: " . date('r') . "\r\nMIME-Version: 1.0\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n" . $body;
|
|
|
|
fputs($sock, "MAIL FROM:<{$directFrom}>\r\n"); $r1 = fgets($sock, 1024);
|
|
fputs($sock, "RCPT TO:<{$TO}>\r\n"); $r2 = fgets($sock, 1024);
|
|
|
|
if (strpos($r2, '250') !== false || strpos($r2, '251') !== false) {
|
|
fputs($sock, "DATA\r\n"); fgets($sock, 1024);
|
|
fputs($sock, $raw . "\r\n.\r\n");
|
|
$sendR = fgets($sock, 1024);
|
|
echo " direct: " . (strpos($sendR,'250')!==false ? "✅ SENT" : "❌ " . trim($sendR)) . " from {$directFrom}\n";
|
|
} else {
|
|
echo " ❌ RCPT rejected: " . trim($r2) . "\n";
|
|
}
|
|
fputs($sock, "QUIT\r\n"); fclose($sock);
|
|
} else {
|
|
echo " ❌ MX connect failed: $errstr\n";
|
|
}
|
|
} else {
|
|
echo " ❌ No MX records for $domain\n";
|
|
}
|
|
|
|
echo "\n=== DONE ===\n";
|