Files
html/api/growth-engine-api.php
2026-04-12 22:57:03 +02:00

211 lines
10 KiB
PHP

<?php
// growth-engine-api.php v2 — Backend unifié Growth Engine
// Branche: CRM, Plausible, SearXNG (Dark Scout), Twenty, Ethica, Brain Engine
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Content-Type');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(200); exit; }
$action = $_GET['action'] ?? '';
$stateFile = '/opt/wevia-brain/growth-state.json';
$state = file_exists($stateFile) ? json_decode(file_get_contents($stateFile), true) : [
'actions_done' => [], 'last_scan' => null, 'proposals' => [],
'pipeline' => ['ideas'=>12,'planned'=>6,'active'=>3,'signed'=>0],
'revenue' => 0, 'target' => 1400000, 'leads' => [], 'intel' => []
];
switch ($action) {
case 'status':
$pages = (int)trim(shell_exec("find /var/www/html -maxdepth 2 -name '*.html' 2>/dev/null | wc -l"));
$apis = (int)trim(shell_exec("find /var/www/html/api -name '*.php' 2>/dev/null | wc -l"));
$products = (int)trim(shell_exec("ls /var/www/html/products/*.html 2>/dev/null | wc -l"));
$docker = (int)trim(shell_exec("docker ps -q 2>/dev/null | wc -l"));
$crons = (int)trim(shell_exec("crontab -l -u www-data 2>/dev/null | grep -cv '^#\|^$'"));
$ollama = (int)trim(shell_exec("curl -s http://localhost:11435/api/tags 2>/dev/null | python3 -c \"import sys,json;print(len(json.load(sys.stdin).get('models',[])))\" 2>&1"));
echo json_encode(['state'=>$state,'live'=>compact('pages','apis','products','docker','crons','ollama')+([ 'timestamp'=>date('c')])]);
break;
case 'crm_leads':
// CRM interne via crm-api.php
$r = @file_get_contents('https://127.0.0.1/api/crm-api.php?action=stats', false,
stream_context_create(['http'=>['timeout'=>10,'header'=>"Host: weval-consulting.com\n"],'ssl'=>['verify_peer'=>false,'verify_peer_name'=>false]]));
$crm = @json_decode($r, true) ?: ['error'=>'CRM unavailable'];
echo json_encode($crm);
break;
case 'ethica_stats':
$r = @file_get_contents('https://127.0.0.1/api/ethica-stats.php', false,
stream_context_create(['http'=>['timeout'=>10,'header'=>"Host: weval-consulting.com\n"],'ssl'=>['verify_peer'=>false,'verify_peer_name'=>false]]));
echo $r ?: json_encode(['error'=>'Ethica unavailable']);
break;
case 'dark_scout':
// Veille concurrentielle via SearXNG
$query = $_GET['q'] ?? $_POST['q'] ?? 'email marketing pharma Maghreb';
$r = @file_get_contents("http://localhost:8888/search?q=" . urlencode($query) . "&format=json&categories=general&language=fr", false,
stream_context_create(['http'=>['timeout'=>15]]));
$data = @json_decode($r, true);
$results = [];
foreach (array_slice($data['results'] ?? [], 0, 10) as $res) {
$results[] = [
'title' => $res['title'] ?? '',
'url' => $res['url'] ?? '',
'content' => substr($res['content'] ?? '', 0, 300),
'engine' => $res['engine'] ?? ''
];
}
echo json_encode(['query'=>$query,'results'=>$results,'count'=>count($results),'source'=>'searxng']);
break;
case 'seo_audit':
// SEO quick audit du site
$url = $_GET['url'] ?? 'https://weval-consulting.com';
$ch = curl_init($url);
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>15, CURLOPT_FOLLOWLOCATION=>true,
CURLOPT_HEADER=>true, CURLOPT_SSL_VERIFYPEER=>false, CURLOPT_USERAGENT=>'WEVAL-SEO-Bot/1.0']);
$resp = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
$headerSize = $info['header_size'];
$body = substr($resp, $headerSize);
$seo = [
'url' => $url,
'http_code' => $info['http_code'],
'load_time' => round($info['total_time'], 2),
'size_kb' => round(strlen($body)/1024, 1),
'has_title' => (bool)preg_match('/<title>([^<]+)/', $body, $m) ? $m[1] : false,
'has_meta_desc' => (bool)preg_match('/meta.*description.*content="([^"]+)/', $body),
'has_og_tags' => (bool)preg_match('/og:title/', $body),
'has_h1' => (bool)preg_match('/<h1/', $body),
'has_structured_data' => (bool)preg_match('/application\/ld\+json/', $body),
'has_sitemap' => false,
'has_robots' => false,
];
// Check sitemap
$sm = @file_get_contents($url . '/sitemap.xml', false, stream_context_create(['http'=>['timeout'=>5],'ssl'=>['verify_peer'=>false]]));
$seo['has_sitemap'] = $sm && strpos($sm, '<urlset') !== false;
// Check robots
$rb = @file_get_contents($url . '/robots.txt', false, stream_context_create(['http'=>['timeout'=>5],'ssl'=>['verify_peer'=>false]]));
$seo['has_robots'] = $rb && strlen($rb) > 10;
$score = 0;
if ($seo['http_code'] == 200) $score += 15;
if ($seo['has_title']) $score += 15;
if ($seo['has_meta_desc']) $score += 15;
if ($seo['has_og_tags']) $score += 10;
if ($seo['has_h1']) $score += 10;
if ($seo['has_structured_data']) $score += 10;
if ($seo['has_sitemap']) $score += 10;
if ($seo['has_robots']) $score += 5;
if ($seo['load_time'] < 3) $score += 10;
$seo['score'] = $score;
echo json_encode($seo);
break;
case 'scan':
$scan = [
'pages' => (int)trim(shell_exec("find /var/www/html -maxdepth 2 -name '*.html' 2>/dev/null | wc -l")),
'apis' => (int)trim(shell_exec("find /var/www/html/api -name '*.php' 2>/dev/null | wc -l")),
'products' => (int)trim(shell_exec("ls /var/www/html/products/*.html 2>/dev/null | wc -l")),
'docker' => (int)trim(shell_exec("docker ps -q 2>/dev/null | wc -l")),
'disk' => trim(shell_exec("df -h / | tail -1 | awk '{print \$5}'")),
'nonreg' => trim(shell_exec("grep -o '[0-9]*/[0-9]*' /tmp/nonreg-result.txt 2>/dev/null | tail -1")),
'timestamp' => date('c')
];
// Dark Scout auto-scan: veille concurrentielle
$queries = ['email marketing pharma Maroc 2026', 'IA souveraine Afrique SaaS', 'API médecins Maghreb healthtech'];
$intel = [];
foreach ($queries as $q) {
$r = @file_get_contents("http://localhost:8888/search?q=" . urlencode($q) . "&format=json&categories=news&language=fr", false,
stream_context_create(['http'=>['timeout'=>10]]));
$d = @json_decode($r, true);
foreach (array_slice($d['results'] ?? [], 0, 3) as $res) {
$intel[] = ['title'=>$res['title']??'','url'=>$res['url']??'','snippet'=>substr($res['content']??'',0,200),'query'=>$q,'date'=>date('c')];
}
}
// SEO auto-audit
$seoR = @file_get_contents('https://127.0.0.1/api/growth-engine-api.php?action=seo_audit', false,
stream_context_create(['http'=>['timeout'=>15,'header'=>"Host: weval-consulting.com\n"],'ssl'=>['verify_peer'=>false]]));
$seo = @json_decode($seoR, true);
// WEVIA Master proposals
$ch = curl_init('https://127.0.0.1/api/wevia-master-api.php');
curl_setopt_array($ch, [CURLOPT_POST=>true,CURLOPT_POSTFIELDS=>json_encode([
'message'=>"Scan: {$scan['pages']} pages, {$scan['apis']} APIs, {$scan['products']} products, disk {$scan['disk']}. Propose 3 nouvelles opportunites de monetisation innovantes pas encore identifiees. Revenu estime et 2 actions concretes par opportunite.",
'session'=>'growth-autoscan-'.date('Ymd-H')
]),CURLOPT_HTTPHEADER=>['Content-Type: application/json','Host: weval-consulting.com'],
CURLOPT_RETURNTRANSFER=>true,CURLOPT_TIMEOUT=>45,CURLOPT_SSL_VERIFYPEER=>false]);
$proposals = @json_decode(curl_exec($ch), true);
curl_close($ch);
$state['last_scan'] = date('c');
$state['intel'] = array_merge($state['intel'] ?? [], $intel);
$state['intel'] = array_slice($state['intel'], -30); // keep last 30
$state['proposals'][] = ['date'=>date('c'),'scan'=>$scan,'seo'=>$seo,'proposal'=>$proposals['content']??''];
$state['proposals'] = array_slice($state['proposals'], -10);
file_put_contents($stateFile, json_encode($state, JSON_PRETTY_PRINT));
echo json_encode(['ok'=>true,'scan'=>$scan,'intel_count'=>count($intel),'seo_score'=>$seo['score']??0,'proposal'=>$proposals['content']??'']);
break;
case 'toggle_action':
$input = json_decode(file_get_contents('php://input'), true);
$id = $input['id'] ?? '';
if ($id) {
if (in_array($id, $state['actions_done'])) {
$state['actions_done'] = array_values(array_diff($state['actions_done'], [$id]));
} else {
$state['actions_done'][] = $id;
}
file_put_contents($stateFile, json_encode($state, JSON_PRETTY_PRINT));
}
echo json_encode(['ok'=>true,'done'=>count($state['actions_done'])]);
break;
case 'add_lead':
$input = json_decode(file_get_contents('php://input'), true);
$lead = [
'name' => $input['name'] ?? '',
'company' => $input['company'] ?? '',
'email' => $input['email'] ?? '',
'opportunity' => $input['opportunity'] ?? '',
'stage' => $input['stage'] ?? 'lead',
'value' => $input['value'] ?? 0,
'created' => date('c')
];
$state['leads'][] = $lead;
file_put_contents($stateFile, json_encode($state, JSON_PRETTY_PRINT));
echo json_encode(['ok'=>true,'lead'=>$lead,'total_leads'=>count($state['leads'])]);
break;
default:
echo json_encode([
'name' => 'WEVAL Growth Engine API v2',
'endpoints' => [
'GET ?action=status' => 'Dashboard KPIs + live metrics',
'GET ?action=crm_leads' => 'CRM leads from crm-api.php',
'GET ?action=ethica_stats' => 'Ethica HCP database stats',
'GET ?action=dark_scout&q=...' => 'Competitive intelligence via SearXNG',
'GET ?action=seo_audit&url=...' => 'SEO audit of any URL',
'GET ?action=scan' => 'Full scan: infra + dark scout + SEO + WEVIA proposals',
'POST ?action=toggle_action' => 'Toggle action done/undone',
'POST ?action=add_lead' => 'Add lead to pipeline'
],
'connected_services' => [
'crm' => 'crm-api.php (internal)',
'twenty' => 'Twenty CRM :3000',
'plausible' => 'Plausible Analytics :8000',
'searxng' => 'SearXNG :8888 (Dark Scout)',
'ethica' => 'ethica-stats.php',
'wevia_master' => 'wevia-master-api.php (proposals)',
'brain_engine' => 'Brain Engine (email optimization)'
]
]);
}