Files
html/api/ethica-consent-campaign.php
2026-04-13 17:00:04 +02:00

99 lines
5.8 KiB
PHP

<?php
/**
* Ethica Consent Campaign Launcher
* P0-1: Sends consent requests via Email (O365) + SMS (OVH) + WhatsApp (Meta)
*/
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
$TOKEN = 'ETHICA_API_2026_SECURE';
if (($_GET['token'] ?? $_POST['token'] ?? '') !== $TOKEN) { echo json_encode(['error'=>'Unauthorized']); exit; }
$pdo = new PDO("pgsql:host=127.0.0.1;dbname=adx_system", "postgres", "");
$pdo->exec("SET search_path TO ethica, public");
$action = $_POST['action'] ?? $_GET['action'] ?? 'status';
if ($action === 'status') {
$total = $pdo->query("SELECT COUNT(*) FROM medecins")->fetchColumn();
$consented = $pdo->query("SELECT COUNT(*) FROM consentements WHERE consent_type='accepted'")->fetchColumn();
$pending = $pdo->query("SELECT COUNT(*) FROM consentements WHERE consent_type='pending'")->fetchColumn();
$campaigns = $pdo->query("SELECT COUNT(*) FROM campaigns")->fetchColumn();
echo json_encode(['ok'=>true, 'total_hcps'=>(int)$total, 'consented'=>(int)$consented, 'pending'=>(int)$pending, 'campaigns'=>(int)$campaigns,
'channels'=>['email'=>true, 'sms'=>false, 'whatsapp'=>false], 'consent_url'=>'https://consent.wevup.app/ethica-consent-landing.html']);
}
elseif ($action === 'launch') {
// === SAFETY LOCK: No send while campaigns are in draft ===
$lock = $pdo->query("SELECT COUNT(*) FROM campaigns WHERE status='active'")->fetchColumn();
if ((int)$lock === 0) { echo json_encode(['ok'=>false, 'error'=>'SAFETY_LOCK: All campaigns are in DRAFT mode. Set campaign status to active to enable sending. Waiting for Ethica confirmation.']); exit; }
$country = $_POST['country'] ?? 'MA';
$channel = $_POST['channel'] ?? 'email';
$limit = min((int)($_POST['limit'] ?? 50), 500);
$brand = $_POST['brand'] ?? 'Ethica Group';
// Get HCPs who haven't been contacted yet
$stmt = $pdo->prepare("SELECT m.id, m.nom, m.prenom, m.email, m.telephone, m.specialite
FROM medecins m LEFT JOIN consentements c ON m.id = c.medecin_id
WHERE m.country = ? AND c.id IS NULL AND m.email IS NOT NULL AND m.email != ''
LIMIT ?");
$stmt->execute([$country, $limit]);
$hcps = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (empty($hcps)) { echo json_encode(['ok'=>false, 'error'=>'No untouched HCPs for '.$country]); exit; }
$sent = 0; $errors = 0;
$consentUrl = 'https://consent.wevup.app/ethica-consent-landing.html';
foreach ($hcps as $hcp) {
$token = bin2hex(random_bytes(16));
$personalUrl = $consentUrl . '?t=' . $token . '&id=' . $hcp['id'];
// Store consent token
$pdo->prepare("INSERT INTO consent_tokens (medecin_id, token, channel, created_at) VALUES (?,?,?,NOW()) ON CONFLICT DO NOTHING")
->execute([$hcp['id'], $token, $channel]);
if ($channel === 'email') {
// Use O365 sender via existing Ethica email API
$subject = "Dr. {$hcp['nom']}{$brand} souhaite vous informer";
$body = "Bonjour Dr. {$hcp['prenom']} {$hcp['nom']},\n\n{$brand} souhaite vous tenir informé(e) des dernières avancées dans votre domaine ({$hcp['specialite']}).\n\nPour recevoir nos communications, veuillez donner votre consentement :\n{$personalUrl}\n\nEthica Group · WEVAL · Conformité loi 09-08";
$emailPayload = json_encode(['to'=>$hcp['email'], 'subject'=>$subject, 'body'=>$body, 'token'=>$TOKEN]);
$ch = curl_init("http://127.0.0.1/api/ethica-api.php?action=send_email&token=$TOKEN");
curl_setopt_array($ch, [CURLOPT_POST=>true, CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>10, CURLOPT_POSTFIELDS=>$emailPayload, CURLOPT_HTTPHEADER=>['Content-Type: application/json']]);
$r = curl_exec($ch); curl_close($ch);
$d = json_decode($r, true);
if ($d && ($d['ok'] ?? false)) { $sent++; } else { $errors++; }
}
elseif ($channel === 'sms') {
if (!$hcp['telephone']) { $errors++; continue; }
$smsMsg = "Dr. {$hcp['nom']}, {$brand} vous invite. Consentement: {$personalUrl}";
$ch = curl_init("http://127.0.0.1/api/ethica-sms-api.php?token=$TOKEN");
curl_setopt_array($ch, [CURLOPT_POST=>true, CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>10,
CURLOPT_POSTFIELDS=>http_build_query(['action'=>'send','phone'=>$hcp['telephone'],'message'=>$smsMsg])]);
curl_exec($ch); curl_close($ch);
$sent++;
}
// Log
$pdo->prepare("INSERT INTO consentements (medecin_id, consent_type, channel, created_at) VALUES (?,?,?,NOW()) ON CONFLICT DO NOTHING")
->execute([$hcp['id'], 'pending', $channel]);
usleep(200000); // 200ms throttle
}
// Create campaign record
$pdo->prepare("INSERT INTO campaigns (name, country, channel, target_count, sent_count, error_count, status, created_at) VALUES (?,?,?,?,?,?,?,NOW())")
->execute(["Consent $country ".date('Y-m-d H:i'), $country, $channel, count($hcps), $sent, $errors, 'completed']);
echo json_encode(['ok'=>true, 'targeted'=>count($hcps), 'sent'=>$sent, 'errors'=>$errors, 'channel'=>$channel, 'country'=>$country]);
}
elseif ($action === 'stats') {
$stats = $pdo->query("SELECT channel, consent_type as status, COUNT(*) as cnt FROM consentements GROUP BY channel, consent_type ORDER BY channel, status")->fetchAll(PDO::FETCH_ASSOC);
$campaigns = $pdo->query("SELECT * FROM campaigns ORDER BY created_at DESC LIMIT 10")->fetchAll(PDO::FETCH_ASSOC);
echo json_encode(['ok'=>true, 'consent_stats'=>$stats, 'recent_campaigns'=>$campaigns]);
}
else {
echo json_encode(['actions'=>['status','launch','stats'], 'example'=>'POST action=launch&country=MA&channel=email&limit=50&brand=Ethica+Group']);
}