vipx/bot-detect
Detect and identify web crawlers (Google, Bing, Yahoo, etc.) from user agent and IP. Loads bot metadata from YAML, returns matched bot details, and includes optional caching and configurable cache naming/dumping for better performance.
Install via Composer:
composer require vipx/bot-detect
Register the service provider in config/app.php:
'providers' => [
// ...
Vipx\BotDetect\BotDetectServiceProvider::class,
],
Publish the config (optional):
php artisan vendor:publish --provider="Vipx\BotDetect\BotDetectServiceProvider"
Create a middleware (app/Http/Middleware/DetectBots.php):
<?php
namespace App\Http\Middleware;
use Closure;
use Vipx\BotDetect\Facades\BotDetect;
class DetectBots
{
public function handle($request, Closure $next)
{
$bot = BotDetect::detect($request->userAgent(), $request->ip());
if ($bot) {
// Log bot activity or block request
return response('Bot detected', 403);
}
return $next($request);
}
}
Register the middleware in app/Http/Kernel.php:
protected $middleware = [
// ...
\App\Http\Middleware\DetectBots::class,
];
Leverage Laravel's service container for dependency injection:
use Vipx\BotDetect\BotDetector;
class SomeService
{
protected $botDetector;
public function __construct(BotDetector $botDetector)
{
$this->botDetector = $botDetector;
}
public function checkRequest($request)
{
$bot = $this->botDetector->detect(
$request->userAgent(),
$request->ip()
);
// Handle bot detection logic
}
}
Use the provided facade for cleaner code:
use Vipx\BotDetect\Facades\BotDetect;
class Controller
{
public function index()
{
$bot = BotDetect::detect(
request()->userAgent(),
request()->ip()
);
if ($bot) {
return response()->json(['message' => 'Bot detected']);
}
// Normal request handling
}
}
Configure caching in config/bot-detect.php:
'cache' => [
'enabled' => env('BOT_DETECT_CACHE_ENABLED', true),
'driver' => env('BOT_DETECT_CACHE_DRIVER', 'file'),
'path' => storage_path('framework/cache/bot-detect'),
],
Extend the bot list by publishing and modifying the YAML files:
php artisan vendor:publish --tag="bot-detect-config"
Edit config/bot-detect/extended.yml to add custom bots.
Listen for bot detection events:
use Vipx\BotDetect\Events\BotDetected;
class BotDetectionListener
{
public function handle(BotDetected $event)
{
// Log bot activity
\Log::info('Bot detected: '.$event->bot->name);
// Block specific bots
if ($event->bot->name === 'Googlebot') {
abort(403, 'Googlebot access denied');
}
}
}
Register the listener in EventServiceProvider:
protected $listen = [
\Vipx\BotDetect\Events\BotDetected::class => [
\App\Listeners\BotDetectionListener::class,
],
];
'cache' => ['enabled' => false]) if you experience issues with large bot lists.Enable Debug Mode:
$bot = BotDetect::detect($agent, $ip, ['debug' => true]);
This will log detection attempts to storage/logs/bot-detect.log.
Check Cache Issues:
storage/framework/cache/bot-detect).php artisan cache:clear
Update Bot Metadata:
Custom Metadata Loaders: The package supports YAML out-of-the-box. For other formats (XML, JSON), extend the MetadataLoader interface:
class JsonFileLoader implements MetadataLoaderInterface
{
// Implement load() method
}
Register it in the service provider.
Case Sensitivity: Bot detection is case-insensitive by default. Override in config:
'case_sensitive' => false,
Partial Matches: The detector uses regex patterns. For strict matching, adjust the match_strategy:
'match_strategy' => 'exact', // 'regex' (default), 'exact', or 'contains'
Custom Bot Actions:
event(new BotDetected($bot, $request))
->listen(function ($event) {
// Custom logic for specific bots
if ($event->bot->name === 'Bingbot') {
// Special handling
}
});
Dynamic Bot Lists: Fetch updated bot lists from an external API and merge with the existing YAML:
$externalBots = json_decode(file_get_contents('https://api.example.com/bots'), true);
$mergedBots = array_merge($existingBots, $externalBots);
Rate Limiting for Bots: Combine with Laravel's rate limiting:
$bot = BotDetect::detect($request->userAgent(), $request->ip());
if ($bot) {
$key = 'bot:'.$bot->name.':'.$request->ip();
if (Cache::has($key)) {
abort(429, 'Too many requests');
}
Cache::put($key, true, now()->addMinutes(1));
}
How can I help you explore Laravel packages today?