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

236 lines
8.4 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
require_once("/opt/wevads/config/credentials.php");
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
// Configuration base de données
$db_config = [
'host' => 'localhost',
'dbname' => 'wevads',
'user' => 'admin',
'password' => WEVADS_DB_PASS
];
try {
$pdo = new PDO(
"pgsql:host={$db_config['host']};dbname={$db_config['dbname']}",
$db_config['user'],
$db_config['password'],
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_TIMEOUT => 10
]
);
$pdo->exec("SET search_path TO admin, public;");
$action = $_GET['action'] ?? 'windows';
switch ($action) {
case 'windows':
// Analyse par heure de la journée
$query = "
SELECT
EXTRACT(HOUR FROM send_date) as hour_of_day,
isp,
COUNT(*) as send_count,
ROUND(AVG(CASE WHEN status = 'inbox' THEN 1 ELSE 0 END) * 100, 2) as inbox_rate,
ROUND(AVG(CASE WHEN status = 'spam' THEN 1 ELSE 0 END) * 100, 2) as spam_rate
FROM admin.unified_send_log
WHERE send_date >= NOW() - INTERVAL '7 days'
GROUP BY EXTRACT(HOUR FROM send_date), isp
ORDER BY hour_of_day, isp
";
$stmt = $pdo->query($query);
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Formater pour affichage
$formatted = [];
foreach ($data as $row) {
$hour = str_pad($row['hour_of_day'], 2, '0', STR_PAD_LEFT) . ':00';
$formatted[] = [
'hour' => $hour,
'isp' => $row['isp'] ?? 'unknown',
'send_count' => (int)$row['send_count'],
'inbox_rate' => (float)$row['inbox_rate'],
'spam_rate' => (float)$row['spam_rate'],
'score' => round((float)$row['inbox_rate'] - (float)$row['spam_rate'], 2)
];
}
// Générer des recommandations
$byHour = [];
foreach ($formatted as $row) {
$hour = $row['hour'];
if (!isset($byHour[$hour])) {
$byHour[$hour] = ['total_score' => 0, 'count' => 0];
}
$byHour[$hour]['total_score'] += $row['score'];
$byHour[$hour]['count']++;
}
$avgScores = [];
foreach ($byHour as $hour => $stats) {
$avgScores[$hour] = $stats['total_score'] / $stats['count'];
}
arsort($avgScores);
$top3 = array_slice($avgScores, 0, 3, true);
echo json_encode([
'status' => 'success',
'period' => '7 days',
'data' => $formatted,
'recommendations' => [
'best_hours' => array_keys($top3),
'scores' => $top3,
'summary' => 'Basé sur les données des 7 derniers jours'
]
]);
break;
case 'heatmap':
// Matrice 24h × 7 jours
$query = "
SELECT
EXTRACT(DOW FROM send_date) as day_of_week,
EXTRACT(HOUR FROM send_date) as hour_of_day,
ROUND(AVG(CASE WHEN status = 'inbox' THEN 1 ELSE 0 END) * 100, 2) as inbox_rate
FROM admin.unified_send_log
WHERE send_date >= NOW() - INTERVAL '30 days'
GROUP BY EXTRACT(DOW FROM send_date), EXTRACT(HOUR FROM send_date)
ORDER BY day_of_week, hour_of_day
";
$stmt = $pdo->query($query);
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Créer la matrice 7x24
$heatmap = [];
$days = ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'];
// Initialiser avec des zéros
for ($day = 0; $day < 7; $day++) {
$heatmap[$days[$day]] = [];
for ($hour = 0; $hour < 24; $hour++) {
$heatmap[$days[$day]][str_pad($hour, 2, '0', STR_PAD_LEFT) . ':00'] = 0;
}
}
// Remplir avec les données
foreach ($data as $row) {
$dayIndex = (int)$row['day_of_week'];
$hour = str_pad($row['hour_of_day'], 2, '0', STR_PAD_LEFT) . ':00';
if ($dayIndex >= 0 && $dayIndex < 7) {
$heatmap[$days[$dayIndex]][$hour] = (float)$row['inbox_rate'];
}
}
// Trouver les meilleurs moments
$bestTimes = [];
foreach ($heatmap as $day => $hours) {
arsort($hours);
$bestHour = key($hours);
$bestTimes[$day] = [
'hour' => $bestHour,
'inbox_rate' => $hours[$bestHour]
];
}
// Trier par taux d'inbox
uasort($bestTimes, function($a, $b) {
return $b['inbox_rate'] <=> $a['inbox_rate'];
});
echo json_encode([
'status' => 'success',
'period' => '30 days',
'heatmap' => $heatmap,
'best_times' => array_slice($bestTimes, 0, 3)
]);
break;
case 'recommend':
$isp = $_GET['isp'] ?? 'all';
$query = "
SELECT
EXTRACT(HOUR FROM send_date) as hour,
COUNT(*) as volume,
ROUND(AVG(CASE WHEN status = 'inbox' THEN 1 ELSE 0 END) * 100, 2) as inbox_rate
FROM admin.unified_send_log
WHERE send_date >= NOW() - INTERVAL '14 days'
" . ($isp !== 'all' ? " AND isp = :isp" : "") . "
GROUP BY EXTRACT(HOUR FROM send_date)
ORDER BY inbox_rate DESC
LIMIT 5
";
$stmt = $pdo->prepare($query);
if ($isp !== 'all') {
$stmt->bindParam(':isp', $isp);
}
$stmt->execute();
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
$recommendations = [];
foreach ($data as $row) {
$confidence = 'low';
$volume = (int)$row['volume'];
if ($volume >= 1000) $confidence = 'high';
elseif ($volume >= 100) $confidence = 'medium';
$recommendations[] = [
'hour' => str_pad($row['hour'], 2, '0', STR_PAD_LEFT) . ':00',
'inbox_rate' => (float)$row['inbox_rate'],
'volume' => $volume,
'confidence' => $confidence
];
}
echo json_encode([
'status' => 'success',
'isp' => $isp,
'period' => '14 days',
'recommendations' => $recommendations,
'best_overall' => $recommendations[0] ?? null
]);
break;
default:
echo json_encode([
'status' => 'error',
'message' => 'Action non reconnue',
'available_actions' => ['windows', 'heatmap', 'recommend'],
'usage' => [
'GET ?action=windows' => 'Analyse par heure',
'GET ?action=heatmap' => 'Matrice 24h×7j',
'GET ?action=recommend&isp=gmail' => 'Meilleures heures pour un ISP'
]
]);
}
} catch (PDOException $e) {
// Générer un heatmap d'exemple en cas d'erreur
$sample = [];
$days = ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'];
foreach ($days as $day) {
for ($hour = 0; $hour < 24; $hour++) {
$time = str_pad($hour, 2, '0', STR_PAD_LEFT) . ':00';
$sample[$day][$time] = rand(70, 95);
}
}
echo json_encode([
'status' => 'error',
'message' => 'Erreur base de données: ' . $e->getMessage(),
'fallback' => [
'status' => 'fallback_mode',
'heatmap_sample' => $sample
]
]);
}
?>