{
 "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"
}