Files
weval-l99/wevialife-sync.php
2026-04-15 01:38:46 +02:00

98 lines
5.5 KiB
PHP
Executable File

<?php
// WEVIA Life Email Sync - Direct IMAP to DB
// Runs via cron every 30 min
set_time_limit(120);
$pdo = new PDO("pgsql:host=127.0.0.1;dbname=wevia_db;options='--search_path=admin,public'", "postgres", "");
$pdo->exec("SET search_path TO admin,public");
$sourcesFile = '/var/www/weval/wevia-ia/wevialife-data/email-sources.json';
$sources = json_decode(@file_get_contents($sourcesFile) ?: '[]', true) ?: [];
$log = function($msg) { echo date('H:i:s')." $msg\n"; };
$inserted = 0;
$skipped = 0;
foreach ($sources as $s) {
if (($s['status'] ?? '') !== 'active') continue;
$pwd = base64_decode($s['password'] ?? '');
$server = $s['server'] ?? 'server105.web-hosting.com';
$port = $s['port'] ?? 993;
$email = $s['email'];
foreach (['INBOX'] as $folder) {
$mb = "{{$server}:{$port}/imap/ssl/novalidate-cert}{$folder}";
$conn = @imap_open($mb, $email, $pwd, 0, 1);
if (!$conn) { $log("FAIL $email: ".imap_last_error()); continue; }
$info = imap_check($conn);
$total = $info->Nmsgs;
$start = max(1, $total - 99); // last 100
$ov = imap_fetch_overview($conn, "$start:$total", 0);
// Get existing UIDs
$existingUids = [];
$stmt = $pdo->query("SELECT uid FROM email_classifications WHERE folder='$folder'");
foreach ($stmt->fetchAll(PDO::FETCH_COLUMN) as $u) $existingUids[$u] = true;
$ins = $pdo->prepare("INSERT INTO email_classifications
(uid, folder, from_email, from_name, subject, received_at, category, eisenhower_quadrant, summary, resolved)
VALUES (?,?,?,?,?,?,?,?,?,false) ON CONFLICT DO NOTHING");
foreach (array_reverse($ov ?: []) as $o) {
$uid = $o->uid;
if (isset($existingUids[$uid])) { $skipped++; continue; }
$from = isset($o->from) ? mb_decode_mimeheader($o->from) : '';
$subj = isset($o->subject) ? mb_decode_mimeheader($o->subject) : '';
$date = isset($o->date) ? date('Y-m-d H:i:s', strtotime($o->date)) : null;
// Extract email from "Name <email>" format
preg_match('/<([^>]+)>/', $from, $m);
$fromEmail = $m[1] ?? $from;
$fromName = trim(preg_replace('/<[^>]+>/', '', $from));
// AI Classification via Sovereign (Opus wire 15avr)
$cat = 'fyi'; $quad = 'schedule'; $summary = $subj;
$urgScore = 1; $impScore = 1; $reqAction = false;
$isVIP = preg_match('/kaouther|vistex|cedric|ella.*scarlett|cx3|ray.*wu|chris.*cen|huawei|scaleway|arrow|belchkar|gassama|golemba|hannemann/i', $fromName.$fromEmail);
if ($isVIP) {
$cat = 'action_required'; $quad = 'do_first'; $urgScore = 10; $impScore = 9; $reqAction = true;
} else {
$aiP = json_encode(['messages'=>[['role'=>'system','content'=>'Classificateur email CEO WEVAL. JSON ONLY sans backticks: {"category":"action_required|opportunity|risk|transactional|newsletter|fyi|spam","urgency_score":1-10,"importance_score":1-10,"eisenhower":"do_first|schedule|delegate|eliminate","requires_action":true,"summary":"1 phrase"}. Promos/newsletters=1-2. VIP=7+. Payments=8+.'],['role'=>'user','content'=>"From: $fromName <$fromEmail> Subject: $subj"]],'max_tokens'=>200,'stream'=>false]);
$aiC = curl_init('http://127.0.0.1:4000/v1/chat/completions');
curl_setopt_array($aiC, [CURLOPT_POST=>true, CURLOPT_HTTPHEADER=>['Content-Type: application/json'], CURLOPT_POSTFIELDS=>$aiP, CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>10]);
$aiR = curl_exec($aiC); curl_close($aiC);
$aiD = @json_decode($aiR, true);
$aiT = preg_replace('/```json\s*|```\s*/', '', trim($aiD['choices'][0]['message']['content'] ?? ''));
$aiJ = @json_decode($aiT, true);
if ($aiJ && isset($aiJ['urgency_score'])) {
$cat = $aiJ['category'] ?? 'fyi';
$urgScore = intval($aiJ['urgency_score']);
$impScore = intval($aiJ['importance_score'] ?? 1);
$quad = $aiJ['eisenhower'] ?? 'schedule';
$reqAction = !empty($aiJ['requires_action']);
$summary = $aiJ['summary'] ?? $subj;
} else {
$sL = strtolower($subj); $fL = strtolower($from);
if (preg_match('/noreply|newsletter|unsubscribe/i', $fL.$sL)) { $cat='newsletter'; $quad='eliminate'; }
elseif (preg_match('/urgent|asap|critical/i', $sL)) { $cat='action_required'; $quad='do_first'; $urgScore=7; $reqAction=true; }
}
}
$ins->execute([$uid, $folder, $fromEmail, $fromName, $subj, $date, $cat, $quad, $summary]);
$pdo->prepare("UPDATE email_classifications SET urgency_score=?, importance_score=?, requires_action=?, classified_at=NOW() WHERE uid=? AND folder=?")->execute([$urgScore, $impScore, $reqAction?'t':'f', $uid, $folder]);
$inserted++;
}
imap_close($conn);
$log("$email/$folder: total=$total, inserted=$inserted, skipped=$skipped");
}
}
$log("SYNC DONE: +$inserted new, $skipped existing");
// Update stats
$stats = $pdo->query("SELECT COUNT(*) as total,
SUM(CASE WHEN eisenhower_quadrant='do_first' THEN 1 ELSE 0 END) as urgent,
MAX(received_at) as latest
FROM email_classifications")->fetch(PDO::FETCH_ASSOC);
$log("DB: {$stats['total']} total, {$stats['urgent']} urgent, latest={$stats['latest']}");