diff --git a/app/Services/Video/GeminiScriptService.php b/app/Services/Video/GeminiScriptService.php index e354fded..f2da6a40 100644 --- a/app/Services/Video/GeminiScriptService.php +++ b/app/Services/Video/GeminiScriptService.php @@ -2,18 +2,21 @@ namespace App\Services\Video; +use App\Models\System\AiConfig; +use App\Services\GoogleCloudService; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; class GeminiScriptService { - private string $apiKey; + private ?AiConfig $config = null; - private string $model = 'gemini-2.5-flash'; + private GoogleCloudService $googleCloud; - public function __construct() + public function __construct(GoogleCloudService $googleCloud) { - $this->apiKey = config('services.gemini.api_key', ''); + $this->googleCloud = $googleCloud; + $this->config = AiConfig::getActiveGemini(); } /** @@ -111,22 +114,19 @@ public function generateScenario(string $title, string $keyword = ''): array } /** - * Gemini API 호출 + * Gemini API 호출 (AiConfig 기반 - API Key / Vertex AI 자동 분기) */ private function callGemini(string $prompt): ?string { - if (empty($this->apiKey)) { - Log::error('GeminiScriptService: API 키가 설정되지 않았습니다.'); + if (! $this->config) { + Log::error('GeminiScriptService: 활성화된 Gemini 설정이 없습니다. (시스템 > AI 설정 확인)'); return null; } try { - $url = "https://generativelanguage.googleapis.com/v1beta/models/{$this->model}:generateContent"; - - $response = Http::withHeaders([ - 'x-goog-api-key' => $this->apiKey, - ])->timeout(60)->post($url, [ + $model = $this->config->model ?: 'gemini-2.5-flash'; + $body = [ 'contents' => [ [ 'parts' => [ @@ -139,12 +139,41 @@ private function callGemini(string $prompt): ?string 'maxOutputTokens' => 4096, 'responseMimeType' => 'application/json', ], - ]); + ]; + + if ($this->config->isVertexAi()) { + // Vertex AI 방식 (서비스 계정 OAuth) + $accessToken = $this->googleCloud->getAccessToken(); + if (! $accessToken) { + Log::error('GeminiScriptService: Vertex AI 액세스 토큰 획득 실패'); + + return null; + } + + $projectId = $this->config->getProjectId(); + $region = $this->config->getRegion(); + $url = "https://{$region}-aiplatform.googleapis.com/v1/projects/{$projectId}/locations/{$region}/publishers/google/models/{$model}:generateContent"; + + // Vertex AI에서는 role 필수 + $body['contents'][0]['role'] = 'user'; + + $response = Http::withToken($accessToken) + ->timeout(60) + ->post($url, $body); + } else { + // API Key 방식 + $apiKey = $this->config->api_key; + $baseUrl = $this->config->base_url ?? 'https://generativelanguage.googleapis.com/v1beta'; + $url = "{$baseUrl}/models/{$model}:generateContent?key={$apiKey}"; + + $response = Http::timeout(60)->post($url, $body); + } if (! $response->successful()) { Log::error('GeminiScriptService: API 호출 실패', [ 'status' => $response->status(), 'body' => $response->body(), + 'auth_type' => $this->config->isVertexAi() ? 'vertex_ai' : 'api_key', ]); return null;