How can I fix the "exceeded quota" issue when using AI to generate articles in Laravel?

3 weeks ago 30
ARTICLE AD BOX

I am working on a blogging application in Laravel 8, which I named "Brave CMS".

I have recently added a "Write with AI" feature to the CMS.

In ArticleAIController.php I have:

class ArticleAIController extends Controller { public function generate(Request $request) { $request->validate([ 'prompt' => 'required|string|max:1000', ]); $prompt = $request->input('prompt'); $apiKey = config('services.openai.key'); if (!$apiKey) { Log::error('OpenAI API key missing!'); return response()->json(['error' => 'Server misconfiguration: missing API key'], 500); } $maxRetries = 2; $attempt = 0; do { $attempt++; try { // Chat completion request $response = Http::withHeaders([ 'Authorization' => 'Bearer ' . $apiKey, 'Content-Type' => 'application/json', ])->post('https://api.openai.com/v1/chat/completions', [ 'model' => 'gpt-3.5-turbo', 'messages' => [ [ 'role' => 'user', 'content' => $prompt ] ], 'max_tokens' => 500, 'temperature' => 0.7, ]); // Retry on rate limit if ($response->status() === 429 && $attempt <= $maxRetries) { sleep(1); continue; } // Handle unsuccessful response if (!$response->successful()) { $status = $response->status(); $body = $response->body(); Log::error("AI API failed (status $status): $body"); $json = json_decode($body, true); $msg = $json['error']['message'] ?? 'AI service failed. Check logs'; return response()->json(['error' => $msg], $status); } // Parse the response $data = $response->json(); if (!isset($data['choices'][0]['message']['content']) || empty($data['choices'][0]['message']['content'])) { Log::error('AI returned no usable text: ' . json_encode($data)); return response()->json(['error' => 'AI returned no usable text'], 500); } $text = trim($data['choices'][0]['message']['content']); // Return structured response return response()->json([ 'title' => $text, 'short_description' => $text, 'content' => $text, ]); } catch (\Exception $e) { Log::error('AI generation exception: ' . $e->getMessage()); if ($attempt <= $maxRetries) { sleep(1); continue; } return response()->json(['error' => 'AI service failed: ' . $e->getMessage()], 500); } } while ($attempt <= $maxRetries); } }

I have a modal with a textarea where the user can prompt the AI:

<div class="modal fade" id="aiWriterModal" tabindex="-1" data-bs-backdrop="static" data-bs-keyboard="false"> <div class="modal-dialog modal-md modal-dialog-centered"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title"> <i class="fa-solid fa-microchip me-1"></i> AI Article Generator </h5> <button type="button" class="btn-close btn-sm" data-bs-dismiss="modal"></button> </div> <div class="modal-body py-2"> <label for="aiPrompt" class="form-label"> Describe what the article should be about </label> <textarea id="aiPrompt" class="form-control" rows="4" placeholder="Example: Write an analytical article about the impact of horses on the development of civilization."></textarea> <div class="form-text mt-1"> The AI will generate a title, short description, and full content. You must pick a category and one or more tags (optional). </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">Cancel</button> <button type="button" class="btn btn-sm btn-success" id="generateArticleBtn">Generate Article</button> </div> </div> </div> </div>

The JavaScript part:

document.getElementById('generateArticleBtn').addEventListener('click', async function() { const prompt = document.getElementById('aiPrompt').value.trim(); if (!prompt) return alert('Please enter a prompt for the AI.'); const btn = this; const originalText = btn.innerHTML; btn.disabled = true; btn.innerHTML = `<span class="spinner-border spinner-border-sm"></span> Generating...`; try { const response = await fetch('{{ route('dashboard.articles.ai-generate') }}', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': '{{ csrf_token() }}', 'Accept': 'application/json' }, body: JSON.stringify({ prompt }) }); const text = await response.text(); let data; try { data = JSON.parse(text); } catch (err) { console.error('Non-JSON response:', text); throw new Error('AI returned invalid response.'); } if (data.error) { alert('AI generation failed: ' + data.error); } else { const titleField = document.getElementById('title'); const shortDescField = document.getElementById('short_description'); const contentField = CKEDITOR.instances.content; if (titleField) titleField.value = data.title || ''; if (shortDescField) shortDescField.value = data.short_description || ''; if (contentField) contentField.setData(data.content || ''); const modalEl = document.getElementById('aiWriterModal'); const modalInstance = bootstrap.Modal.getInstance(modalEl); modalInstance.hide(); } } catch (err) { console.error(err); alert('AI generation failed: ' + err.message); } finally { btn.disabled = false; btn.innerHTML = originalText; } });

The issue I am confronted with is the message below:

AI generation failed: You exceeded your current quota, please check your plan and billing details. For more information on this error, read the docs: https://platform.openai.com/docs/guides/error-codes/api-errors.

Questions:

Is there a way to get an unlimited quota for free, given that Brave CMS is free and open source? Is there a 100% free alternative to GTP I could use instead?
Read Entire Article