geminiKey = config('services.gemini.key', env('GEMINI_API_KEY')); $this->unsplashKey = config('services.unsplash.access_key', env('UNSPLASH_ACCESS_KEY')); } /** * Generate blog content using Gemini API */ public function generateContent(string $topic, ?string $context = null): array { $prompt = $this->buildPrompt($topic, $context); // Debug logging $keyStatus = empty($this->geminiKey) ? 'MISSING' : 'PRESENT (' . substr($this->geminiKey, 0, 5) . '...)'; Log::info("Gemini Service: Key status: $keyStatus"); try { $response = Http::withoutVerifying() ->retry(3, 10000, function ($exception, $request) { if ($exception instanceof \Illuminate\Http\Client\RequestException && $exception->response->status() === 429) { return false; } return true; }) ->withHeaders(['Content-Type' => 'application/json']) ->post("https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key={$this->geminiKey}", [ 'contents' => [ [ 'parts' => [ ['text' => $prompt] ] ] ], 'generationConfig' => [ 'temperature' => 0.7, 'topK' => 40, 'topP' => 0.95, 'maxOutputTokens' => 8192, 'responseMimeType' => 'application/json', ] ]); if ($response->failed()) { Log::error('Gemini API Error Status: ' . $response->status()); Log::error('Gemini API Error Body: ' . $response->body()); throw new \Exception('Gemini API request failed: ' . $response->body()); } $data = $response->json(); if (!isset($data['candidates'][0]['content']['parts'][0]['text'])) { Log::error('Gemini API Invalid Response: ' . json_encode($data)); throw new \Exception('Invalid response from Gemini API.'); } $jsonContent = $data['candidates'][0]['content']['parts'][0]['text']; // Clean markdown json blocks if present $jsonContent = str_replace(['```json', '```'], '', $jsonContent); return json_decode($jsonContent, true); } catch (\Exception $e) { Log::error('AI Blog Generation Exception: ' . $e->getMessage()); throw $e; } } /** * Build the prompt for Gemini */ private function buildPrompt(string $topic, ?string $context = null): string { $contextStr = $context ? "Additional Context: {$context}" : ""; return << and

tags for headings. * Use

for paragraphs. * Include a bulleted list (