'SA not found'])); $action = $_GET['action'] ?? $_POST['action'] ?? ''; if (!$action) die(json_encode(['error'=>'no action','available'=>['drive-list','gmail-send','calendar-list','sheets-create','test']])); // JWT token génération for SA function getAccessToken($sa, $scopes) { $header = base64url(json_encode(['alg'=>'RS256','typ'=>'JWT'])); $now = time(); $claim = base64url(json_encode([ 'iss' => $sa['client_email'], 'scope' => implode(' ', $scopes), 'aud' => 'https://oauth2.googleapis.com/token', 'iat' => $now, 'exp' => $now + 3600, 'sub' => $sa['client_email'] ])); $sig_input = "$header.$claim"; openssl_sign($sig_input, $sig, $sa['private_key'], 'SHA256'); $jwt = "$sig_input." . base64url($sig); $ch = curl_init('https://oauth2.googleapis.com/token'); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => http_build_query([ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', 'assertion' => $jwt ]), CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10 ]); $resp = json_decode(curl_exec($ch), true); curl_close($ch); return $resp['access_token'] ?? null; } function base64url($data) { return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); } function apiCall($url, $token, $method = 'GET', $body = null) { $ch = curl_init($url); $headers = ['Authorization: Bearer ' . $token]; if ($body) { $headers[] = 'Content-Type: application/json'; curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body)); } curl_setopt_array($ch, [ CURLOPT_HTTPHEADER => $headers, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 15, CURLOPT_CUSTOMREQUEST => $method ]); $resp = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return ['code'=>$code, 'data'=>json_decode($resp, true) ?: $resp]; } switch ($action) { case 'test': $token = getAccessToken($SA, ['https://www.googleapis.com/auth/drive.readonly']); echo json_encode(['ok'=>!!$token, 'email'=>$SA['client_email'], 'project'=>$SA['project_id']]); break; case 'drive-list': $token = getAccessToken($SA, ['https://www.googleapis.com/auth/drive.readonly']); if (!$token) die(json_encode(['error'=>'no token'])); $r = apiCall('https://www.googleapis.com/drive/v3/files?pageSize=10', $token); echo json_encode($r); break; case 'gmail-send': $to = $_POST['to'] ?? ''; $subject = $_POST['subject'] ?? 'Test'; $body_text = $_POST['body'] ?? 'Test from WEVAL'; $token = getAccessToken($SA, ['https://www.googleapis.com/auth/gmail.send']); if (!$token) die(json_encode(['error'=>'no token'])); $raw = base64url("To: $to\r\nSubject: $subject\r\nContent-Type: text/html\r\n\r\n$body_text"); $r = apiCall('https://gmail.googleapis.com/gmail/v1/users/me/messages/send', $token, 'POST', ['raw'=>$raw]); echo json_encode($r); break; case 'calendar-list': $token = getAccessToken($SA, ['https://www.googleapis.com/auth/calendar.readonly']); if (!$token) die(json_encode(['error'=>'no token'])); $r = apiCall('https://www.googleapis.com/calendar/v3/calendars/primary/events?maxResults=5&orderBy=startTime&singleEvents=true', $token); echo json_encode($r); break; default: echo json_encode(['error'=>'unknown action','available'=>['test','drive-list','gmail-send','calendar-list']]); }