{ "slug": "cloudflare-worker", "title": "Cloudflare Worker: classify at the edge", "language": "javascript", "suggested_filename": "worker.js", "description": "Fetches this index's regex list at the edge and tags every request with a category header, so your origin can log AI traffic without shipping a bot list to every app.", "url": "https://www.pathwren.workers.dev/snippet/cloudflare-worker.txt", "body": "// AI Crawler Index — Cloudflare Worker: tag every request with a crawler class.\n// curl -s https://www.pathwren.workers.dev/snippet/cloudflare-worker.txt\n// Pulls the regex list from this index once per hour and caches it at the edge,\n// so the bot list lives in one place instead of in every app.\nconst INDEX = \"https://www.pathwren.workers.dev/data/ua-regex.json\";\nlet cache = null, cachedAt = 0;\n\nasync function patterns() {\n if (cache && Date.now() - cachedAt < 3600_000) return cache;\n const r = await fetch(INDEX, { cf: { cacheTtl: 3600 } });\n const d = await r.json();\n cache = Object.entries(d.by_category).map(([k, v]) => [k, new RegExp(v, \"i\")]);\n cachedAt = Date.now();\n return cache;\n}\n\nexport default {\n async fetch(request) {\n const ua = request.headers.get(\"user-agent\") || \"\";\n let klass = \"human\";\n for (const [name, re] of await patterns()) if (re.test(ua)) { klass = name; break; }\n const req = new Request(request);\n req.headers.set(\"X-Crawler-Class\", klass);\n return fetch(req);\n }\n};\n" }