Artificial Intelligence is reshaping the way websites interact with users. If you’re building with Laravel, you can easily integrate ChatGPT (OpenAI) and Gemini (Google AI) into your application to provide a smart chatbot. In this guide, we’ll build a Laravel AI Chatbot step by step.
You’ll learn how to:
✅ Setup API integration with OpenAI and Gemini
✅ Create a chatbot service & controller in Laravel
✅ Build a Tailwind CSS chat UI
✅ Add the chatbot as a floating widget on your homepage
Step 1: Install Laravel & Dependencies
Make sure you have a Laravel project ready. Then install GuzzleHTTP to handle API requests:
composer require guzzlehttp/guzzle
Step 2: Add API Keys
In your .env file, add:
OPENAI_API_KEY=your_openai_api_key_here
GEMINI_API_KEY=your_gemini_api_key_here
Step 3: Create a Service for Chat APIs
Create app/Services/ChatAIService.php
<?php
namespace App\Services;
use GuzzleHttp\Client;
class ChatAIService
{
protected $client;
public function __construct()
{
$this->client = new Client();
}
// ChatGPT
public function chatWithOpenAI($message)
{
$response = $this->client->post('https://api.openai.com/v1/chat/completions', [
'headers' => [
'Authorization' => 'Bearer ' . env('OPENAI_API_KEY'),
'Content-Type' => 'application/json',
],
'json' => [
'model' => 'gpt-4o-mini',
'messages' => [
['role' => 'system', 'content' => 'You are a helpful assistant.'],
['role' => 'user', 'content' => $message],
],
'max_tokens' => 300,
],
]);
$data = json_decode($response->getBody(), true);
return $data['choices'][0]['message']['content'] ?? 'No response';
}
// Gemini
public function chatWithGemini($message)
{
$response = $this->client->post("https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=" . env('GEMINI_API_KEY'), [
'headers' => [
'Content-Type' => 'application/json',
],
'json' => [
'contents' => [
['parts' => [['text' => $message]]],
],
],
]);
$data = json_decode($response->getBody(), true);
return $data['candidates'][0]['content']['parts'][0]['text'] ?? 'No response';
}
}
Step 4: Create Controller
Make app/Http/Controllers/ChatController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Services\ChatAIService;
class ChatController extends Controller
{
protected $chatService;
public function __construct(ChatAIService $chatService)
{
$this->chatService = $chatService;
}
public function askOpenAI(Request $request)
{
$message = $request->input('message');
$reply = $this->chatService->chatWithOpenAI($message);
return response()->json(['reply' => $reply]);
}
public function askGemini(Request $request)
{
$message = $request->input('message');
$reply = $this->chatService->chatWithGemini($message);
return response()->json(['reply' => $reply]);
}
}
Step 5: Define Routes
Add in routes/web.php:
use App\Http\Controllers\ChatController;
Route::post('/chat/openai', [ChatController::class, 'askOpenAI']);
Route::post('/chat/gemini', [ChatController::class, 'askGemini']);
Step 6: Create Tailwind Chat Widget
Create a widget view:
resources/views/components/chat-widget.blade.php
<div id="chat-widget" class="fixed bottom-5 right-5 w-80 bg-white shadow-lg rounded-2xl overflow-hidden flex flex-col hidden">
<!-- Header -->
<div class="bg-indigo-600 text-white px-4 py-2 flex justify-between items-center">
<span class="font-semibold">🤖 AI Chatbot</span>
<button onclick="toggleChat()" class="text-white">✖</button>
</div>
<!-- Chat Messages -->
<div id="chat-box" class="flex-1 overflow-y-auto p-3 space-y-3 h-64">
<!-- Messages will appear here -->
</div>
<!-- Input Area -->
<div class="border-t p-2 flex items-center space-x-2">
<input id="message" type="text" placeholder="Type..."
class="flex-1 px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-400">
<button onclick="sendMessage()"
class="bg-indigo-600 text-white px-3 py-2 rounded-lg hover:bg-indigo-700 transition text-sm">
GPT
</button>
<button onclick="sendMessageGemini()"
class="bg-green-600 text-white px-3 py-2 rounded-lg hover:bg-green-700 transition text-sm">
Gem
</button>
</div>
</div>
<!-- Floating Button -->
<button id="chat-toggle-btn" onclick="toggleChat()"
class="fixed bottom-5 right-5 bg-indigo-600 text-white p-4 rounded-full shadow-lg hover:bg-indigo-700">
💬
</button>
<script>
function toggleChat() {
let widget = document.getElementById("chat-widget");
let btn = document.getElementById("chat-toggle-btn");
widget.classList.toggle("hidden");
btn.classList.toggle("hidden");
}
function addMessage(sender, text, type = "user") {
const chatBox = document.getElementById("chat-box");
const msgDiv = document.createElement("div");
if (type === "user") {
msgDiv.className = "flex justify-end";
msgDiv.innerHTML = `<div class="bg-indigo-100 text-gray-800 px-3 py-2 rounded-lg max-w-xs">${text}</div>`;
} else {
msgDiv.className = "flex justify-start";
msgDiv.innerHTML = `<div class="bg-gray-200 text-gray-800 px-3 py-2 rounded-lg max-w-xs"><b>${sender}:</b> ${text}</div>`;
}
chatBox.appendChild(msgDiv);
chatBox.scrollTop = chatBox.scrollHeight;
}
async function sendMessage() {
let message = document.getElementById('message').value;
if (!message.trim()) return;
addMessage("You", message, "user");
document.getElementById('message').value = "";
let res = await fetch('/chat/openai', {
method: 'POST',
headers: {
"Content-Type": "application/json",
"X-CSRF-TOKEN": document.querySelector('meta[name="csrf-token"]').getAttribute('content')
},
body: JSON.stringify({ message })
});
let data = await res.json();
addMessage("OpenAI", data.reply, "bot");
}
async function sendMessageGemini() {
let message = document.getElementById('message').value;
if (!message.trim()) return;
addMessage("You", message, "user");
document.getElementById('message').value = "";
let res = await fetch('/chat/gemini', {
method: 'POST',
headers: {
"Content-Type": "application/json",
"X-CSRF-TOKEN": document.querySelector('meta[name="csrf-token"]').getAttribute('content')
},
body: JSON.stringify({ message })
});
let data = await res.json();
addMessage("Gemini", data.reply, "bot");
}
</script>Step 7: Include Widget on Homepage
In resources/views/home.blade.php (or welcome.blade.php):
@extends('layouts.app')
@section('content')
<div class="container mx-auto p-6">
<h1 class="text-3xl font-bold mb-6">Welcome to My Site</h1>
<p class="mb-4">This is the homepage content...</p>
</div>
{{-- Chatbot Widget --}}
@include('components.chat-widget')
@endsection
Here’s a full Tailwind-styled chatbot interface (with scrolling chat bubbles, input box, and buttons):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>AI Chatbot</title>
<meta name="csrf-token" content="{{ csrf_token() }}">
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-100 flex items-center justify-center min-h-screen">
<div class="w-full max-w-lg bg-white rounded-2xl shadow-lg flex flex-col h-[600px]">
<!-- Header -->
<div class="bg-indigo-600 text-white text-center py-3 rounded-t-2xl font-semibold">
🤖 Laravel AI Chatbot
</div>
<!-- Chat Messages -->
<div id="chat-box" class="flex-1 overflow-y-auto p-4 space-y-4">
<!-- Messages will appear here -->
</div>
<!-- Input Area -->
<div class="border-t p-3 flex items-center space-x-2">
<input id="message" type="text" placeholder="Type a message..."
class="flex-1 px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-400">
<button onclick="sendMessage()"
class="bg-indigo-600 text-white px-4 py-2 rounded-lg hover:bg-indigo-700 transition">
ChatGPT
</button>
<button onclick="sendMessageGemini()"
class="bg-green-600 text-white px-4 py-2 rounded-lg hover:bg-green-700 transition">
Gemini
</button>
</div>
</div>
<script>
function addMessage(sender, text, type = "user") {
const chatBox = document.getElementById("chat-box");
const msgDiv = document.createElement("div");
if (type === "user") {
msgDiv.className = "flex justify-end";
msgDiv.innerHTML = `<div class="bg-indigo-100 text-gray-800 px-4 py-2 rounded-lg max-w-xs">${text}</div>`;
} else {
msgDiv.className = "flex justify-start";
msgDiv.innerHTML = `<div class="bg-gray-200 text-gray-800 px-4 py-2 rounded-lg max-w-xs"><b>${sender}:</b> ${text}</div>`;
}
chatBox.appendChild(msgDiv);
chatBox.scrollTop = chatBox.scrollHeight;
}
async function sendMessage() {
let message = document.getElementById('message').value;
if (!message.trim()) return;
addMessage("You", message, "user");
document.getElementById('message').value = "";
let res = await fetch('/chat/openai', {
method: 'POST',
headers: {
"Content-Type": "application/json",
"X-CSRF-TOKEN": document.querySelector('meta[name="csrf-token"]').getAttribute('content')
},
body: JSON.stringify({ message })
});
let data = await res.json();
addMessage("OpenAI", data.reply, "bot");
}
async function sendMessageGemini() {
let message = document.getElementById('message').value;
if (!message.trim()) return;
addMessage("You", message, "user");
document.getElementById('message').value = "";
let res = await fetch('/chat/gemini', {
method: 'POST',
headers: {
"Content-Type": "application/json",
"X-CSRF-TOKEN": document.querySelector('meta[name="csrf-token"]').getAttribute('content')
},
body: JSON.stringify({ message })
});
let data = await res.json();
addMessage("Gemini", data.reply, "bot");
}
</script>
</body>
</html>
Final Result 🎉
You now have a Laravel AI Chatbot powered by ChatGPT and Gemini.
It appears as a floating widget on your homepage.
Users can chat in real-time with AI responses styled using Tailwind CSS.