99 lines
5.8 KiB
PHP
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']);
|
|
}
|