Files
WMS/Modules/ChatGPT/Services/OpenAiFileService.php
2026-09-21 10:14:57 +01:00

120 lines
3.1 KiB
PHP
Executable File

<?php
namespace Modules\ChatGPT\Services;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Facades\Http;
use Modules\ChatGPT\Exceptions\OpenAiFileException;
class OpenAiFileService
{
private const BASE_URL = 'https://api.openai.com/v1';
public function __construct(private readonly string $apiKey) {}
/**
* List all OpenAI API files visible to the configured API key.
*
* @return array<int, array<string, mixed>>
*/
public function listFiles(): array
{
$files = [];
$after = null;
do {
$query = ['limit' => 100];
if (is_string($after) && $after !== '') {
$query['after'] = $after;
}
$response = $this->client()
->get(self::BASE_URL . '/files', $query);
if ($response->failed()) {
throw new OpenAiFileException('OpenAI file list request failed: ' . $response->body());
}
$payload = $response->json();
$batch = $payload['data'] ?? [];
foreach ($batch as $file) {
if (is_array($file)) {
$files[] = $file;
}
}
$hasMore = (bool) ($payload['has_more'] ?? false);
$after = $payload['last_id'] ?? null;
} while ($hasMore && is_string($after) && $after !== '');
return $files;
}
/**
* Delete one OpenAI API file by ID.
*
* @return array<string, mixed>
*/
public function deleteFile(string $fileId): array
{
$response = $this->client()
->delete(self::BASE_URL . '/files/' . rawurlencode($fileId));
if ($response->failed()) {
throw new OpenAiFileException("OpenAI file delete request failed for {$fileId}: " . $response->body());
}
return $response->json() ?? [];
}
/**
* Delete every OpenAI API file visible to the configured API key.
*
* @return array{listed:int, deleted:int, failed:int, failures:array<int, array{file_id:string, error:string}>}
*/
public function deleteAllFiles(): array
{
$files = $this->listFiles();
$deleted = 0;
$failures = [];
foreach ($files as $file) {
$fileId = (string) ($file['id'] ?? '');
if ($fileId === '') {
continue;
}
try {
$this->deleteFile($fileId);
$deleted++;
} catch (OpenAiFileException $exception) {
$failures[] = [
'file_id' => $fileId,
'error' => $exception->getMessage(),
];
}
}
return [
'listed' => count($files),
'deleted' => $deleted,
'failed' => count($failures),
'failures' => $failures,
];
}
/**
* Build the authenticated OpenAI HTTP client.
*/
private function client(): PendingRequest
{
return Http::withToken($this->apiKey)
->acceptJson()
->timeout(60)
->retry(2, 500);
}
}