Installation:
composer require deuchnord/no-ai-bundle
The bundle auto-registers via Symfony’s autoloader.
First Use Case:
Test with a known AI crawler User-Agent (e.g., GPTBot):
curl -v -H "User-Agent: GPTBot/1.1" http://your-site.test
Expected: 403 Forbidden response.
Where to Look First:
config/packages/deuchnord_no_ai.yaml (auto-generated).src/EventListener/AiCrawlerListener.php (customize logic if needed).tests/ for edge cases (e.g., whitelisted UAs).Request Interception:
The bundle hooks into Symfony’s kernel.request event via AiCrawlerListener. It checks the User-Agent header against a predefined list of AI crawlers (e.g., GPTBot, CCBot, AhrefsBot).
Blocking Logic:
403 Forbidden for matched UAs.AiCrawlerChecker service (see Gotchas).Integration Tips:
config/packages/deuchnord_no_ai.yaml:
deuchnord_no_ai:
whitelist:
- 'AmazonBot' # Allow Amazon crawlers
use Psr\Log\LoggerInterface;
public function __construct(private LoggerInterface $logger) {}
public function onKernelRequest(): void {
if ($this->isAiCrawler($request)) {
$this->logger->warning('Blocked AI crawler', ['ua' => $request->headers->get('User-Agent')]);
throw new AccessDeniedHttpException();
}
}
Performance:
User-Agent regex patterns (e.g., via Symfony\Component\HttpFoundation\RequestStack).False Positives:
AmazonBot) may be blocked if not whitelisted.whitelist config and test with real crawlers.Dynamic User-Agents:
AiCrawlerChecker service to add custom patterns:
services:
deuchnord_no_ai.ai_crawler_checker:
arguments:
$patterns: ['/CustomAIPattern/i']
Symfony Cache:
403 response isn’t cached by AI crawlers.Cache-Control: no-store headers in the listener.Testing:
User-Agent headers in PHPUnit:
$request = new Request([], [], ['HTTP_USER_AGENT' => 'GPTBot/1.1']);
$this->assertTrue($aiCrawlerChecker->isAiCrawler($request));
Enable Debug Mode:
Temporarily disable blocking in config/packages/deuchnord_no_ai.yaml:
deuchnord_no_ai:
enabled: false
Useful for diagnosing false blocks.
Check Headers:
Log the raw User-Agent to verify detection:
$this->logger->debug('User-Agent', ['ua' => $request->headers->get('User-Agent')]);
Custom Blocking Logic:
Override the AiCrawlerListener and inject your own logic (e.g., redirect to a CAPTCHA):
public function onKernelRequest(Request $request): void {
if ($this->isAiCrawler($request)) {
return new RedirectResponse('/captcha');
}
}
Add New Crawlers:
Extend the AiCrawlerChecker to include new patterns:
public function __construct(array $patterns = []) {
$this->patterns = array_merge($this->defaultPatterns, $patterns);
}
Event Dispatching: Trigger events when crawlers are blocked (e.g., for analytics):
$this->eventDispatcher->dispatch(new AiCrawlerBlockedEvent($request));
How can I help you explore Laravel packages today?