-
-
Notifications
You must be signed in to change notification settings - Fork 1
Examples
Rumen Damyanov edited this page Jul 31, 2025
·
1 revision
Real-world examples and use cases for php-chatbot implementation.
- Basic Examples
- E-commerce Chatbot
- Customer Support
- Documentation Assistant
- Multi-language Support
- Advanced Integrations
- Performance Optimization
Real-world examples and use cases for php-chatbot implementation.
- Basic Examples
- E-commerce Chatbot
- Customer Support
- Documentation Assistant
- Multi-language Support
- Advanced Integrations
- Performance Optimization
<?php
require_once 'vendor/autoload.php';
use RumenX\PhpChatbot\PhpChatbot;
// Basic chatbot setup
$chatbot = new PhpChatbot([
'model' => 'openai',
'api_key' => $_ENV['OPENAI_API_KEY'],
'temperature' => 0.7,
]);
// Handle incoming message
if ($_POST['message']) {
$userMessage = $_POST['message'];
$response = $chatbot->sendMessage($userMessage);
header('Content-Type: application/json');
echo json_encode([
'reply' => $response['reply'],
'conversation_id' => $response['conversation_id'],
'timestamp' => time()
]);
}
?><?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use RumenX\PhpChatbot\PhpChatbot;
class ChatbotController extends Controller
{
private PhpChatbot $chatbot;
public function __construct()
{
$this->chatbot = new PhpChatbot([
'model' => config('chatbot.default_model'),
'api_key' => config('chatbot.api_keys.openai'),
'max_tokens' => 150,
'temperature' => 0.8,
]);
}
public function sendMessage(Request $request)
{
$request->validate([
'message' => 'required|string|max:2000',
'conversation_id' => 'nullable|string',
]);
try {
$response = $this->chatbot->sendMessage(
$request->message,
['conversation_id' => $request->conversation_id]
);
// Log conversation for analytics
$this->logConversation($request->message, $response);
return response()->json([
'success' => true,
'reply' => $response['reply'],
'conversation_id' => $response['conversation_id'],
]);
} catch (\Exception $e) {
\Log::error('Chatbot error: ' . $e->getMessage());
return response()->json([
'success' => false,
'error' => 'Sorry, I encountered an error. Please try again.',
], 500);
}
}
private function logConversation(string $message, array $response): void
{
\DB::table('chat_logs')->insert([
'user_message' => $message,
'bot_response' => $response['reply'],
'conversation_id' => $response['conversation_id'],
'model_used' => $this->chatbot->getCurrentModel(),
'created_at' => now(),
]);
}
}<?php
namespace App\Service;
use RumenX\PhpChatbot\PhpChatbot;
use Symfony\Component\HttpFoundation\JsonResponse;
use Psr\Log\LoggerInterface;
class ChatbotService
{
private PhpChatbot $chatbot;
private LoggerInterface $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
$this->chatbot = new PhpChatbot([
'model' => $_ENV['CHATBOT_MODEL'] ?? 'openai',
'api_key' => $_ENV['OPENAI_API_KEY'],
'system_prompt' => 'You are a helpful assistant for our Symfony application.',
]);
}
public function processMessage(string $message, ?string $conversationId = null): JsonResponse
{
$this->logger->info('Processing chatbot message', [
'message' => $message,
'conversation_id' => $conversationId,
]);
try {
$response = $this->chatbot->sendMessage($message, [
'conversation_id' => $conversationId,
]);
return new JsonResponse([
'status' => 'success',
'data' => $response,
]);
} catch (\Exception $e) {
$this->logger->error('Chatbot processing failed', [
'message' => $message,
'error' => $e->getMessage(),
]);
return new JsonResponse([
'status' => 'error',
'message' => 'Failed to process your message',
], 500);
}
}
}<?php
namespace App\Services;
use RumenX\PhpChatbot\PhpChatbot;
use App\Models\Product;
use App\Models\Category;
class EcommerceChatbot
{
private PhpChatbot $chatbot;
public function __construct()
{
$this->chatbot = new PhpChatbot([
'model' => 'openai',
'api_key' => config('services.openai.key'),
'system_prompt' => $this->getEcommercePrompt(),
'temperature' => 0.6,
]);
}
public function handleMessage(string $message, array $context = []): array
{
// Enhance message with product context
$enhancedMessage = $this->addProductContext($message, $context);
$response = $this->chatbot->sendMessage($enhancedMessage);
// Post-process response to add product links
$processedResponse = $this->addProductLinks($response['reply']);
return [
'reply' => $processedResponse,
'conversation_id' => $response['conversation_id'],
'suggested_products' => $this->extractProductSuggestions($response['reply']),
];
}
private function getEcommercePrompt(): string
{
return "You are a helpful e-commerce assistant for our online store.
Help customers find products, answer questions about items,
shipping, returns, and provide personalized recommendations.
Always be friendly and helpful. If you mention specific products,
use this format: [Product Name](product-id-123)";
}
private function addProductContext(string $message, array $context): string
{
$productContext = '';
// Add current category context
if (isset($context['category_id'])) {
$category = Category::find($context['category_id']);
$productContext .= "Current category: {$category->name}. ";
}
// Add recently viewed products
if (isset($context['recent_products'])) {
$recentProducts = Product::whereIn('id', $context['recent_products'])->get();
$productNames = $recentProducts->pluck('name')->implode(', ');
$productContext .= "Recently viewed: {$productNames}. ";
}
// Add cart context
if (isset($context['cart_items'])) {
$cartProducts = Product::whereIn('id', array_keys($context['cart_items']))->get();
$cartNames = $cartProducts->pluck('name')->implode(', ');
$productContext .= "Current cart: {$cartNames}. ";
}
return $productContext . "Customer message: " . $message;
}
private function addProductLinks(string $response): string
{
// Replace product mentions with actual links
return preg_replace_callback(
'/\[([^\]]+)\]\(product-id-(\d+)\)/',
function ($matches) {
$productName = $matches[1];
$productId = $matches[2];
$url = route('products.show', $productId);
return "<a href='{$url}' class='product-link'>{$productName}</a>";
},
$response
);
}
private function extractProductSuggestions(string $response): array
{
// Extract product IDs mentioned in response
preg_match_all('/product-id-(\d+)/', $response, $matches);
if (empty($matches[1])) {
return [];
}
return Product::whereIn('id', $matches[1])
->select('id', 'name', 'price', 'image_url')
->get()
->toArray();
}
}<?php
namespace App\Services;
class ShoppingCartChatbot extends EcommerceChatbot
{
public function handleCartOperation(string $message, int $userId): array
{
$intent = $this->detectIntent($message);
switch ($intent) {
case 'add_to_cart':
return $this->handleAddToCart($message, $userId);
case 'remove_from_cart':
return $this->handleRemoveFromCart($message, $userId);
case 'view_cart':
return $this->handleViewCart($userId);
case 'checkout':
return $this->handleCheckout($userId);
default:
return parent::handleMessage($message, ['user_id' => $userId]);
}
}
private function detectIntent(string $message): string
{
$message = strtolower($message);
if (preg_match('/add.*cart|want.*buy|purchase/', $message)) {
return 'add_to_cart';
}
if (preg_match('/remove.*cart|delete.*cart/', $message)) {
return 'remove_from_cart';
}
if (preg_match('/show.*cart|view.*cart|what.*cart/', $message)) {
return 'view_cart';
}
if (preg_match('/checkout|pay|order/', $message)) {
return 'checkout';
}
return 'general';
}
private function handleAddToCart(string $message, int $userId): array
{
// Extract product mentions
$products = $this->extractProductMentions($message);
if (empty($products)) {
return [
'reply' => "I'd be happy to help you add items to your cart! Could you tell me which product you're interested in?",
'type' => 'clarification'
];
}
$addedProducts = [];
foreach ($products as $productId) {
// Add to cart logic
Cart::updateOrCreate(
['user_id' => $userId, 'product_id' => $productId],
['quantity' => DB::raw('quantity + 1')]
);
$addedProducts[] = Product::find($productId);
}
$productNames = collect($addedProducts)->pluck('name')->implode(', ');
return [
'reply' => "Great! I've added {$productNames} to your cart. Would you like to continue shopping or proceed to checkout?",
'type' => 'success',
'cart_count' => Cart::where('user_id', $userId)->sum('quantity')
];
}
}<?php
namespace App\Services;
use RumenX\PhpChatbot\PhpChatbot;
use App\Models\Ticket;
use App\Models\User;
class SupportChatbot
{
private PhpChatbot $chatbot;
public function __construct()
{
$this->chatbot = new PhpChatbot([
'model' => 'anthropic',
'api_key' => config('services.anthropic.key'),
'system_prompt' => $this->getSupportPrompt(),
'temperature' => 0.3, // More consistent responses for support
]);
}
public function handleSupportQuery(string $message, ?User $user = null): array
{
$context = $this->buildUserContext($user);
$enhancedMessage = $context . "\n\nUser query: " . $message;
// Check if this needs human escalation
if ($this->shouldEscalateToHuman($message)) {
return $this->escalateToHuman($message, $user);
}
$response = $this->chatbot->sendMessage($enhancedMessage);
// Log support interaction
$this->logSupportInteraction($message, $response, $user);
return [
'reply' => $response['reply'],
'conversation_id' => $response['conversation_id'],
'escalated' => false,
'suggested_articles' => $this->findRelatedArticles($message),
];
}
private function getSupportPrompt(): string
{
return "You are a customer support assistant. Help users with:
- Order status and tracking
- Account issues and billing
- Product information and troubleshooting
- Return and refund policies
Always be empathetic and professional. If you cannot resolve
an issue, suggest escalating to a human agent. Use the knowledge
base information provided in the context.";
}
private function buildUserContext(?User $user): string
{
if (!$user) {
return "Anonymous user - no account information available.";
}
$context = "User: {$user->name} (ID: {$user->id})\n";
$context .= "Email: {$user->email}\n";
$context .= "Account created: {$user->created_at->format('Y-m-d')}\n";
// Recent orders
$recentOrders = $user->orders()->latest()->take(3)->get();
if ($recentOrders->count() > 0) {
$context .= "Recent orders:\n";
foreach ($recentOrders as $order) {
$context .= "- Order #{$order->id}: {$order->status} ({$order->created_at->format('M d')})\n";
}
}
// Open tickets
$openTickets = $user->tickets()->where('status', 'open')->count();
if ($openTickets > 0) {
$context .= "Open support tickets: {$openTickets}\n";
}
return $context;
}
private function shouldEscalateToHuman(string $message): bool
{
$escalationKeywords = [
'speak to human', 'talk to person', 'escalate', 'manager',
'unsatisfied', 'angry', 'frustrated', 'complaint',
'legal action', 'refund', 'cancel account'
];
$message = strtolower($message);
foreach ($escalationKeywords as $keyword) {
if (strpos($message, $keyword) !== false) {
return true;
}
}
return false;
}
private function escalateToHuman(string $message, ?User $user): array
{
// Create support ticket
$ticket = Ticket::create([
'user_id' => $user?->id,
'subject' => 'Escalated from chatbot',
'message' => $message,
'priority' => 'high',
'status' => 'open',
]);
// Notify support team
event(new TicketCreated($ticket));
return [
'reply' => "I understand you'd like to speak with a human agent. I've created ticket #{$ticket->id} and our support team will contact you within 2 hours. Is there anything else I can help you with in the meantime?",
'escalated' => true,
'ticket_id' => $ticket->id,
'estimated_response_time' => '2 hours',
];
}
private function findRelatedArticles(string $message): array
{
// Simple keyword matching for knowledge base articles
$articles = collect([
['title' => 'How to track your order', 'url' => '/help/tracking', 'keywords' => ['track', 'order', 'shipping']],
['title' => 'Return policy', 'url' => '/help/returns', 'keywords' => ['return', 'refund', 'exchange']],
['title' => 'Account settings', 'url' => '/help/account', 'keywords' => ['account', 'password', 'profile']],
]);
$message = strtolower($message);
$relevant = [];
foreach ($articles as $article) {
foreach ($article['keywords'] as $keyword) {
if (strpos($message, $keyword) !== false) {
$relevant[] = [
'title' => $article['title'],
'url' => $article['url']
];
break;
}
}
}
return array_slice($relevant, 0, 3); // Return top 3 matches
}
}<?php
namespace App\Services;
class MultiChannelSupportBot
{
private SupportChatbot $supportBot;
public function __construct(SupportChatbot $supportBot)
{
$this->supportBot = $supportBot;
}
public function handleMessage(string $message, string $channel, array $metadata = []): array
{
// Adapt response based on channel
$response = $this->supportBot->handleSupportQuery($message, $metadata['user'] ?? null);
// Format response for specific channels
switch ($channel) {
case 'slack':
return $this->formatForSlack($response);
case 'discord':
return $this->formatForDiscord($response);
case 'whatsapp':
return $this->formatForWhatsApp($response);
default:
return $response;
}
}
private function formatForSlack(array $response): array
{
$blocks = [
[
'type' => 'section',
'text' => [
'type' => 'mrkdwn',
'text' => $response['reply']
]
]
];
// Add suggested articles as attachments
if (!empty($response['suggested_articles'])) {
$blocks[] = [
'type' => 'section',
'text' => [
'type' => 'mrkdwn',
'text' => '*Helpful articles:*'
]
];
foreach ($response['suggested_articles'] as $article) {
$blocks[] = [
'type' => 'section',
'text' => [
'type' => 'mrkdwn',
'text' => "• <{$article['url']}|{$article['title']}>"
]
];
}
}
return [
'blocks' => $blocks,
'response_type' => 'in_channel'
];
}
private function formatForWhatsApp(array $response): array
{
$message = $response['reply'];
// Add quick reply buttons for WhatsApp
$quickReplies = [];
if ($response['escalated']) {
$quickReplies[] = 'Check ticket status';
} else {
$quickReplies = ['More help', 'Speak to human', 'End chat'];
}
return [
'text' => $message,
'quick_replies' => $quickReplies,
];
}
}<?php
namespace App\Services;
use RumenX\PhpChatbot\PhpChatbot;
class DocumentationChatbot
{
private PhpChatbot $chatbot;
private array $apiDocs;
public function __construct()
{
$this->chatbot = new PhpChatbot([
'model' => 'openai',
'api_key' => config('services.openai.key'),
'system_prompt' => $this->getDocumentationPrompt(),
'temperature' => 0.2, // Very consistent for documentation
]);
$this->loadApiDocumentation();
}
public function handleDocQuery(string $query): array
{
// Find relevant documentation sections
$relevantDocs = $this->findRelevantDocumentation($query);
// Enhance query with documentation context
$enhancedQuery = $this->buildDocumentationContext($relevantDocs) .
"\n\nUser question: " . $query;
$response = $this->chatbot->sendMessage($enhancedQuery);
return [
'reply' => $response['reply'],
'related_docs' => $relevantDocs,
'code_examples' => $this->extractCodeExamples($response['reply']),
];
}
private function getDocumentationPrompt(): string
{
return "You are a technical documentation assistant. Help developers understand:
- API endpoints and parameters
- Code examples and usage patterns
- Best practices and common pitfalls
- Integration guides and troubleshooting
Always provide accurate, practical answers with code examples when relevant.
If you reference API endpoints, include the full URL and required parameters.";
}
private function loadApiDocumentation(): void
{
// Load API documentation from various sources
$this->apiDocs = [
'endpoints' => $this->loadFromOpenAPI(),
'examples' => $this->loadCodeExamples(),
'guides' => $this->loadGuides(),
];
}
private function findRelevantDocumentation(string $query): array
{
$relevantDocs = [];
$queryLower = strtolower($query);
// Search endpoints
foreach ($this->apiDocs['endpoints'] as $endpoint) {
$searchText = strtolower($endpoint['path'] . ' ' . $endpoint['description']);
if ($this->calculateRelevance($queryLower, $searchText) > 0.3) {
$relevantDocs['endpoints'][] = $endpoint;
}
}
// Search examples
foreach ($this->apiDocs['examples'] as $example) {
$searchText = strtolower($example['title'] . ' ' . $example['description']);
if ($this->calculateRelevance($queryLower, $searchText) > 0.3) {
$relevantDocs['examples'][] = $example;
}
}
return $relevantDocs;
}
private function calculateRelevance(string $query, string $text): float
{
$queryWords = explode(' ', $query);
$textWords = explode(' ', $text);
$intersection = array_intersect($queryWords, $textWords);
$union = array_unique(array_merge($queryWords, $textWords));
return count($intersection) / count($union);
}
private function buildDocumentationContext(array $relevantDocs): string
{
$context = "Relevant documentation:\n\n";
// Add endpoint information
if (isset($relevantDocs['endpoints'])) {
$context .= "API Endpoints:\n";
foreach ($relevantDocs['endpoints'] as $endpoint) {
$context .= "- {$endpoint['method']} {$endpoint['path']}\n";
$context .= " Description: {$endpoint['description']}\n";
$context .= " Parameters: " . json_encode($endpoint['parameters']) . "\n\n";
}
}
// Add code examples
if (isset($relevantDocs['examples'])) {
$context .= "Code Examples:\n";
foreach ($relevantDocs['examples'] as $example) {
$context .= "- {$example['title']}\n";
$context .= " {$example['code']}\n\n";
}
}
return $context;
}
private function extractCodeExamples(string $response): array
{
// Extract code blocks from response
preg_match_all('/```(\w+)?\n(.*?)```/s', $response, $matches);
$examples = [];
for ($i = 0; $i < count($matches[0]); $i++) {
$examples[] = [
'language' => $matches[1][$i] ?: 'text',
'code' => trim($matches[2][$i]),
];
}
return $examples;
}
}<?php
namespace App\Services;
use RumenX\PhpChatbot\PhpChatbot;
use Illuminate\Support\Facades\Cache;
class MultiLanguageChatbot
{
private array $chatbots = [];
private string $defaultLanguage = 'en';
public function __construct()
{
$this->initializeChatbots();
}
public function handleMessage(string $message, string $language = null): array
{
$language = $language ?: $this->detectLanguage($message);
$chatbot = $this->getChatbotForLanguage($language);
// Translate message if needed
if ($language !== $this->defaultLanguage) {
$translatedMessage = $this->translateToEnglish($message, $language);
$response = $chatbot->sendMessage($translatedMessage);
$response['reply'] = $this->translateFromEnglish($response['reply'], $language);
} else {
$response = $chatbot->sendMessage($message);
}
return [
'reply' => $response['reply'],
'conversation_id' => $response['conversation_id'],
'detected_language' => $language,
'confidence' => $this->getLanguageConfidence($message, $language),
];
}
private function initializeChatbots(): void
{
$supportedLanguages = ['en', 'es', 'fr', 'de', 'ja', 'zh'];
foreach ($supportedLanguages as $lang) {
$this->chatbots[$lang] = new PhpChatbot([
'model' => 'openai',
'api_key' => config('services.openai.key'),
'system_prompt' => $this->getLanguageSpecificPrompt($lang),
'temperature' => 0.7,
]);
}
}
private function getLanguageSpecificPrompt(string $language): string
{
$prompts = [
'en' => 'You are a helpful assistant. Respond in English.',
'es' => 'Eres un asistente útil. Responde en español.',
'fr' => 'Vous êtes un assistant utile. Répondez en français.',
'de' => 'Sie sind ein hilfreicher Assistent. Antworten Sie auf Deutsch.',
'ja' => 'あなたは親切なアシスタントです。日本語で答えてください。',
'zh' => '你是一个有用的助手。请用中文回答。',
];
return $prompts[$language] ?? $prompts['en'];
}
private function detectLanguage(string $text): string
{
// Cache language detection results
return Cache::remember(
'lang_detect_' . md5($text),
3600,
function () use ($text) {
return $this->performLanguageDetection($text);
}
);
}
private function performLanguageDetection(string $text): string
{
// Simple language detection based on character patterns
// In production, use a proper language detection service
if (preg_match('/[ñáéíóúü]/i', $text)) {
return 'es'; // Spanish
}
if (preg_match('/[àâäçéèêëîïôöùûü]/i', $text)) {
return 'fr'; // French
}
if (preg_match('/[äöüß]/i', $text)) {
return 'de'; // German
}
if (preg_match('/[\x{4e00}-\x{9faf}]/u', $text)) {
return 'zh'; // Chinese
}
if (preg_match('/[\x{3040}-\x{309f}\x{30a0}-\x{30ff}]/u', $text)) {
return 'ja'; // Japanese
}
return 'en'; // Default to English
}
private function getChatbotForLanguage(string $language): PhpChatbot
{
return $this->chatbots[$language] ?? $this->chatbots[$this->defaultLanguage];
}
private function translateToEnglish(string $text, string $fromLanguage): string
{
// Use translation service (Google Translate, Azure, etc.)
return $this->translate($text, $fromLanguage, 'en');
}
private function translateFromEnglish(string $text, string $toLanguage): string
{
return $this->translate($text, 'en', $toLanguage);
}
private function translate(string $text, string $from, string $to): string
{
// Implementation would use actual translation service
// This is a placeholder
return Cache::remember(
"translate_{$from}_{$to}_" . md5($text),
3600,
function () use ($text, $from, $to) {
// Call translation API
return $text; // Placeholder
}
);
}
}<?php
namespace App\Services;
use RumenX\PhpChatbot\PhpChatbot;
use Illuminate\Support\Facades\Http;
class WebhookChatbot
{
private PhpChatbot $chatbot;
private array $webhooks;
public function __construct()
{
$this->chatbot = new PhpChatbot([
'model' => 'openai',
'api_key' => config('services.openai.key'),
'system_prompt' => $this->getWebhookPrompt(),
]);
$this->webhooks = config('chatbot.webhooks', []);
}
public function processMessage(string $message, array $context = []): array
{
// Pre-processing webhooks
$this->triggerWebhooks('pre_process', [
'message' => $message,
'context' => $context,
]);
// Process with AI
$response = $this->chatbot->sendMessage($message);
// Post-processing webhooks
$this->triggerWebhooks('post_process', [
'message' => $message,
'response' => $response,
'context' => $context,
]);
// Check for action triggers in response
$actions = $this->extractActions($response['reply']);
if (!empty($actions)) {
$response['actions'] = $this->executeActions($actions, $context);
}
return $response;
}
private function getWebhookPrompt(): string
{
return "You are an intelligent assistant that can trigger actions.
When appropriate, include action triggers in your response using this format:
[ACTION:action_name:parameter1,parameter2]
Available actions:
- [ACTION:send_email:recipient,subject] - Send an email
- [ACTION:create_ticket:priority,category] - Create support ticket
- [ACTION:schedule_callback:datetime,phone] - Schedule a callback
- [ACTION:update_user:field,value] - Update user information";
}
private function triggerWebhooks(string $event, array $data): void
{
if (!isset($this->webhooks[$event])) {
return;
}
foreach ($this->webhooks[$event] as $webhook) {
try {
Http::timeout(5)->post($webhook['url'], [
'event' => $event,
'data' => $data,
'timestamp' => now()->toISOString(),
]);
} catch (\Exception $e) {
\Log::warning("Webhook failed: {$webhook['url']}", [
'error' => $e->getMessage(),
]);
}
}
}
private function extractActions(string $response): array
{
preg_match_all('/\[ACTION:([^:]+):([^\]]*)\]/', $response, $matches);
$actions = [];
for ($i = 0; $i < count($matches[1]); $i++) {
$actions[] = [
'name' => $matches[1][$i],
'parameters' => explode(',', $matches[2][$i]),
];
}
return $actions;
}
private function executeActions(array $actions, array $context): array
{
$results = [];
foreach ($actions as $action) {
switch ($action['name']) {
case 'send_email':
$results[] = $this->sendEmail($action['parameters'], $context);
break;
case 'create_ticket':
$results[] = $this->createTicket($action['parameters'], $context);
break;
case 'schedule_callback':
$results[] = $this->scheduleCallback($action['parameters'], $context);
break;
default:
$results[] = ['error' => "Unknown action: {$action['name']}"];
}
}
return $results;
}
private function sendEmail(array $params, array $context): array
{
[$recipient, $subject] = $params;
try {
\Mail::to($recipient)->send(new \App\Mail\ChatbotTriggeredEmail([
'subject' => $subject,
'context' => $context,
]));
return ['status' => 'success', 'action' => 'email_sent'];
} catch (\Exception $e) {
return ['status' => 'error', 'message' => $e->getMessage()];
}
}
}<?php
namespace App\Services;
class DatabaseIntegratedChatbot
{
private PhpChatbot $chatbot;
public function __construct()
{
$this->chatbot = new PhpChatbot([
'model' => 'openai',
'api_key' => config('services.openai.key'),
'system_prompt' => $this->getDatabasePrompt(),
]);
}
public function queryWithDatabase(string $query, ?User $user = null): array
{
// Analyze query to determine what data might be needed
$dataContext = $this->buildDataContext($query, $user);
$enhancedQuery = $dataContext . "\n\nUser query: " . $query;
$response = $this->chatbot->sendMessage($enhancedQuery);
// Execute any database operations mentioned in response
$dbOperations = $this->extractDatabaseOperations($response['reply']);
$results = [];
foreach ($dbOperations as $operation) {
$results[] = $this->executeDatabaseOperation($operation, $user);
}
return [
'reply' => $this->replacePlaceholders($response['reply'], $results),
'conversation_id' => $response['conversation_id'],
'data_sources' => array_keys($dataContext ? json_decode($dataContext, true) : []),
];
}
private function buildDataContext(string $query, ?User $user): string
{
$context = [];
$queryLower = strtolower($query);
// User-related queries
if ($user && (strpos($queryLower, 'my ') !== false || strpos($queryLower, 'account') !== false)) {
$context['user'] = [
'id' => $user->id,
'name' => $user->name,
'email' => $user->email,
'created_at' => $user->created_at->format('Y-m-d'),
];
}
// Order-related queries
if (strpos($queryLower, 'order') !== false && $user) {
$context['recent_orders'] = $user->orders()
->latest()
->take(5)
->get(['id', 'status', 'total', 'created_at'])
->toArray();
}
// Product-related queries
if (preg_match('/product|item|stock/', $queryLower)) {
$context['featured_products'] = \App\Models\Product::where('featured', true)
->take(10)
->get(['id', 'name', 'price', 'stock'])
->toArray();
}
return json_encode($context);
}
private function getDatabasePrompt(): string
{
return "You are a data-aware assistant with access to user information.
When referencing data, use these placeholders:
- {{USER_DATA:field}} for user information
- {{ORDER_DATA:order_id:field}} for order information
- {{PRODUCT_DATA:product_id:field}} for product information
Example: 'Your order {{ORDER_DATA:123:status}} was placed on {{ORDER_DATA:123:created_at}}'";
}
private function extractDatabaseOperations(string $response): array
{
preg_match_all('/\{\{(\w+)_DATA:([^}]+)\}\}/', $response, $matches);
$operations = [];
for ($i = 0; $i < count($matches[1]); $i++) {
$operations[] = [
'type' => strtolower($matches[1][$i]),
'params' => explode(':', $matches[2][$i]),
];
}
return array_unique($operations, SORT_REGULAR);
}
private function executeDatabaseOperation(array $operation, ?User $user): array
{
switch ($operation['type']) {
case 'user':
return $user ? $user->toArray() : [];
case 'order':
$orderId = $operation['params'][0];
$order = $user?->orders()->find($orderId);
return $order ? $order->toArray() : [];
case 'product':
$productId = $operation['params'][0];
$product = \App\Models\Product::find($productId);
return $product ? $product->toArray() : [];
default:
return [];
}
}
}<?php
namespace App\Services;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Redis;
class OptimizedChatbot
{
private PhpChatbot $chatbot;
private string $cachePrefix = 'chatbot:';
public function __construct()
{
$this->chatbot = new PhpChatbot([
'model' => 'openai',
'api_key' => config('services.openai.key'),
]);
}
public function sendMessageWithCaching(string $message, array $options = []): array
{
// Create cache key based on message and relevant options
$cacheKey = $this->generateCacheKey($message, $options);
// Try to get cached response
if ($cached = $this->getCachedResponse($cacheKey)) {
return array_merge($cached, ['cached' => true]);
}
// Get fresh response
$response = $this->chatbot->sendMessage($message, $options);
// Cache the response
$this->cacheResponse($cacheKey, $response);
return array_merge($response, ['cached' => false]);
}
private function generateCacheKey(string $message, array $options): string
{
// Create deterministic cache key
$keyData = [
'message' => $message,
'model' => $options['model'] ?? 'default',
'temperature' => $options['temperature'] ?? 0.7,
// Don't include conversation_id in cache key for broader caching
];
return $this->cachePrefix . md5(json_encode($keyData));
}
private function getCachedResponse(string $cacheKey): ?array
{
return Cache::get($cacheKey);
}
private function cacheResponse(string $cacheKey, array $response): void
{
// Cache for 1 hour by default
$ttl = config('chatbot.cache.ttl', 3600);
// Don't cache conversation_id as it should be unique
$cacheable = $response;
unset($cacheable['conversation_id']);
Cache::put($cacheKey, $cacheable, $ttl);
}
public function preloadCommonResponses(): void
{
$commonQueries = [
'Hello',
'How are you?',
'What can you help me with?',
'Thank you',
'Goodbye',
];
foreach ($commonQueries as $query) {
$this->sendMessageWithCaching($query);
}
}
public function warmUpCache(array $queries): void
{
foreach ($queries as $query) {
try {
$this->sendMessageWithCaching($query);
usleep(100000); // 100ms delay to avoid rate limits
} catch (\Exception $e) {
\Log::warning("Failed to warm cache for query: {$query}");
}
}
}
}<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use RumenX\PhpChatbot\PhpChatbot;
class ProcessChatMessage implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct(
private string $message,
private string $userId,
private string $channelId,
private array $options = []
) {}
public function handle(): void
{
$chatbot = new PhpChatbot([
'model' => $this->options['model'] ?? 'openai',
'api_key' => config('services.openai.key'),
]);
try {
$response = $chatbot->sendMessage($this->message, $this->options);
// Send response back to user via WebSocket or other channel
$this->sendResponseToUser($response);
// Log the interaction
$this->logInteraction($response);
} catch (\Exception $e) {
\Log::error('Async chat processing failed', [
'message' => $this->message,
'user_id' => $this->userId,
'error' => $e->getMessage(),
]);
// Send error response to user
$this->sendErrorToUser($e->getMessage());
}
}
private function sendResponseToUser(array $response): void
{
// WebSocket implementation
broadcast(new ChatMessageProcessed([
'user_id' => $this->userId,
'channel_id' => $this->channelId,
'response' => $response,
]));
}
private function sendErrorToUser(string $error): void
{
broadcast(new ChatMessageFailed([
'user_id' => $this->userId,
'channel_id' => $this->channelId,
'error' => 'Sorry, I encountered an error processing your message.',
]));
}
}
// Usage
class ChatController extends Controller
{
public function sendMessage(Request $request)
{
// Queue the message for async processing
ProcessChatMessage::dispatch(
$request->message,
$request->user()->id,
$request->channel_id,
$request->options ?? []
);
return response()->json([
'status' => 'queued',
'message' => 'Your message is being processed...',
]);
}
}These examples demonstrate real-world implementations of php-chatbot across various use cases. Each example includes production-ready patterns, error handling, and optimization strategies that you can adapt for your specific requirements.
Next recommended reading: Best Practices for development and deployment guidelines.