Return

All tests / src/constants aiCrawlers.ts

100% Statements 2/2
100% Branches 0/0
100% Functions 0/0
100% Lines 1/1

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48                                                                  30x                            
/**
 * What a crawler fetches pages for, as its operator documents it.
 * - `training`: collects content to train models.
 * - `search`: builds the index behind an AI search product.
 * - `user-fetch`: fetches one page because a person asked the assistant to (not a crawl).
 * - `ads`: validates ad landing pages.
 * - `dataset`: builds an open web corpus that others train on.
 */
export type AiCrawlerPurpose = 'training' | 'search' | 'user-fetch' | 'ads' | 'dataset';
 
export type AiCrawler = {
    /** Substring matched case-insensitively against the request's User-Agent. */
    token: string;
    operator: string;
    purpose: AiCrawlerPurpose;
};
 
/**
 * AI crawlers recognised by the middleware, from each operator's own documentation (read
 * 2026-09-18): developers.openai.com/api/docs/bots, support.claude.com/en/articles/8896518,
 * docs.perplexity.ai/guides/bots, commoncrawl.org/ccbot and
 * developers.facebook.com/docs/sharing/webmasters/web-crawlers.
 *
 * Deliberately absent, although public/robots.txt names them:
 * - `Google-Extended` and `Applebot-Extended` are robots.txt tokens only. Google and Apple fetch with
 *   their ordinary crawlers and never send these strings as a User-Agent, so matching on them would
 *   count nothing.
 * - `anthropic-ai` no longer appears in Anthropic's crawler list; its current bots are the three
 *   `Claude*` entries below.
 * Bytespider is not listed either: ByteDance publishes no documentation to take a purpose from.
 *
 * No token is a substring of another, so the order of the list does not change the result.
 */
export const AI_CRAWLERS: readonly AiCrawler[] = [
    { token: 'GPTBot', operator: 'OpenAI', purpose: 'training' },
    { token: 'OAI-SearchBot', operator: 'OpenAI', purpose: 'search' },
    { token: 'ChatGPT-User', operator: 'OpenAI', purpose: 'user-fetch' },
    { token: 'OAI-AdsBot', operator: 'OpenAI', purpose: 'ads' },
    { token: 'ClaudeBot', operator: 'Anthropic', purpose: 'training' },
    { token: 'Claude-SearchBot', operator: 'Anthropic', purpose: 'search' },
    { token: 'Claude-User', operator: 'Anthropic', purpose: 'user-fetch' },
    { token: 'PerplexityBot', operator: 'Perplexity', purpose: 'search' },
    { token: 'Perplexity-User', operator: 'Perplexity', purpose: 'user-fetch' },
    { token: 'meta-externalagent', operator: 'Meta', purpose: 'training' },
    { token: 'meta-externalfetcher', operator: 'Meta', purpose: 'user-fetch' },
    { token: 'CCBot', operator: 'Common Crawl', purpose: 'dataset' },
];