Download the PHP package hamaka/silverstripe-matomo-ai-tracking without Composer
On this page you can find all versions of the php package hamaka/silverstripe-matomo-ai-tracking. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download hamaka/silverstripe-matomo-ai-tracking
More information about hamaka/silverstripe-matomo-ai-tracking
Files in hamaka/silverstripe-matomo-ai-tracking
Package silverstripe-matomo-ai-tracking
Short Description Track AI chatbot requests (ChatGPT-User, Claude-User, Perplexity-User, ...) in Matomo AI Insights via server-side middleware.
License BSD-3-Clause
Homepage https://github.com/hamaka/silverstripe-matomo-ai-tracking
Informations about the package silverstripe-matomo-ai-tracking
Silverstripe Matomo AI tracking
Tracks requests from AI chatbots (ChatGPT-User, Claude-User, Perplexity-User, …) in Matomo AI Insights using server-side middleware.
AI assistants fetch your pages on behalf of their users, but they don't execute JavaScript, so the regular
Matomo tracking code never sees them. This module detects these requests in PHP and sends them to the Matomo
HTTP Tracking API in "bot only" mode (recMode=1). They show up under AI Insights without affecting your
visitor statistics.
Requirements
- Silverstripe 5 or 6
- PHP 8.1+
- Matomo 5.7 or newer, with the BotTracking plugin (AI Insights) enabled. The plugin does not exist in 5.6 and older.
- A full-page cache, if any, must run as Director middleware. See Full-page caches.
Installation
Flush afterwards: ?flush=1 in the browser, or on the command line vendor/bin/sake dev/build flush=1 (Silverstripe 5)
or vendor/bin/sake flush (Silverstripe 6). No database build is needed: the module adds no tables.
Configuration
Tracking is off by default. Enable it per environment in .env:
The site URL is taken from the request itself. Behind a proxy or load balancer that terminates TLS, make sure
Silverstripe recognises the request as https (SS_TRUSTED_PROXY_IPS), or set MATOMO_AI_TRACKING_SITE_URL.
No token is needed: hits are always sent in real time.
Tip: only enable it on live (or point test environments to a separate Matomo site ID), otherwise test hits end up in your production statistics.
Optional YAML configuration
Excluded paths and downloads are single regexes. Setting one in YAML replaces the default, so copy the
default from src/AiBotDetector.php and extend it. For example, to also exclude /api/:
User agents: user_agent_patterns is a list. Silverstripe merges lists from YAML with the default instead of
replacing them, so a YAML list can only add patterns. Adding one rarely helps: Matomo only counts the AI chatbots
its BotTracking plugin knows and silently drops the rest. To track fewer bots, replace the list in _config.php:
Tracker settings:
How it works
MatomoAiTrackingMiddlewareis registered as the outermost Director middleware (Before: '*').- Only user agents that Matomo counts as AI chatbots are sent. Crawlers such as GPTBot and ClaudeBot are ignored by Matomo in bot mode, so they are skipped here as well.
- Status code, response size and server response time (
pf_srv) are sent along. A request that ends in an uncaught exception is tracked as a 500. - The call to Matomo happens in a shutdown function, after the response has been sent. Under PHP-FPM the connection
to the bot is closed first (
fastcgi_finish_request()). Under mod_php the connection stays open until the call is done (max.timeout_seconds). - A
warningis logged and the hit is dropped when Matomo is unreachable, returns an error, or rejects the hit as invalid (for example a wrong site ID: Matomo still answers "success" then, with aninvalidcount). The response to the bot is never affected.
Full-page caches
The middleware only sees requests that reach Silverstripe's Director:
- Tracked: full-page caches that run as Director middleware after this one (such as an in-house
DynamicCacheMiddleware), because this middleware is registered first. - Not tracked: caches that answer before Director, such as static publishing
(
silverstripe/staticpublishqueue), caches inindex.phpor.htaccess, a reverse proxy (Varnish) or a CDN. The originaltractorcow/silverstripe-dynamiccachebelongs here too: it hooks in before the framework and was never released for Silverstripe 5/6.
For those setups, bots that get a cached page never reach PHP. Track them at the proxy/CDN level or exclude AI chatbot user agents from the cache.
Limitation: files served directly by the webserver
Existing files in assets/ (PDFs, documents) are served by Apache/nginx without starting PHP, so this middleware
never sees them. If you want to know which documents AI assistants read, route only AI chatbot requests for
those files through Silverstripe. Regular visitors are unaffected.
Apache: add this before the "Non existant files passed to requesthandler" block in public/assets/.htaccess.
That file is generated, so put the rule in your project's override of the template
templates/SilverStripe/Assets/Flysystem/PublicAssetAdapter_HTAccess.ss (mind the capitals on case-sensitive file
systems), then regenerate it with a flush.
The rule uses [.] instead of \. on purpose: backslashes in that template are escaped (the existing rules use
\\. and \\\\), so a pasted \. may not end up in .htaccess as written. Always check the generated
public/assets/.htaccess.
nginx: use an equivalent location block with an if ($http_user_agent ~* ...) rewrite to index.php.
Check that Silverstripe then actually serves the file (status 200) on your setup. Keep the list of bots in sync
with user_agent_patterns.
Running the tests
The tests/ folder is not part of the Packagist download (see .gitattributes). Install the module from source
in a Silverstripe project to run them:
If the tests fail with "getItemPath returned null", the class manifest is stale. Silverstripe picks up a flush
argument from the command line. With PHPUnit 9 (Silverstripe 5) use:
PHPUnit 10+ (Silverstripe 6) treats extra arguments as test paths, so this trick doesn't work there; see the Silverstripe 6 testing docs for how to flush before a test run.
License
BSD-3-Clause, see LICENSE.md.