> For the complete documentation index, see [llms.txt](https://docs.airops.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.airops.com/docs/fr/insights/onsite/traffic/cloudflare-worker-agent-analytics.md).

# Cloudflare Worker

Ce guide vous explique comment configurer un Cloudflare Worker pour diffuser les journaux de requêtes dans AirOps pour Agent Analytics.

Ce guide vous accompagne dans la configuration de Cloudflare pour diffuser vers AirOps via **Workers**. Une fois connecté, AirOps analyse automatiquement votre trafic, classe les visites des bots IA (ChatGPT, Claude, Perplexity, Google, et plus encore) et met en avant des insights dans votre tableau de bord Agent Analytics.

{% hint style="info" %}
**Logpush ou Worker ?** Si vous êtes sur un forfait Cloudflare Enterprise, nous recommandons [Cloudflare Logpush](/docs/fr/insights/onsite/traffic/cloudflare-logpush-agent-analytics.md) à la place. C’est l’option la plus simple et elle ne nécessite aucun code. Utilisez Workers lorsque Logpush n’est pas disponible, par exemple sur les forfaits non Enterprise.
{% endhint %}

***

## Prérequis

* Un **AirOps** compte actif avec Agent Analytics activé
* Un **compte** Cloudflare hébergeant votre site web, qui est soit au niveau Enterprise, soit doté de l’option complémentaire Workers Paid
* Une machine de développement avec Node.js installé
* Votre **clé API du Workspace**, disponible dans `Paramètres → Workspace`
* Votre **ID du Brand Kit**, disponible dans l’URL en naviguant vers `Contexte → Brand Kits`. L’URL a la forme `https://app.airops.com/<YOUR_WORKSPACE_SLUG>/data/brand_kits/<YOUR_BRAND_KIT_ID>`

***

## Regroupement via Workers

L’intégration de regroupement est l’ **approche recommandée** pour la plupart des sites web. Elle utilise une Cloudflare Queue pour tamponner les événements de journalisation par requête et les envoyer à AirOps par lots, ce qui vous maintient bien en dessous de la limite de débit d’AirOps, même en cas de fort trafic.

### Étape 1 : initialiser le Worker Cloudflare

Pour ce processus, nous utiliserons la version `2.68.2` de l’interface CLI de Cloudflare. D’autres versions mineures peuvent fonctionner, mais il peut y avoir des différences dans les invites de la CLI.

{% hint style="info" %}
Selon votre environnement de développement, vous devrez peut-être installer manuellement les paquets node suivants : `node-addon-api`, `node-gyp`, et `sharp`.
{% endhint %}

```bash
npm create cloudflare@2.68.2
```

Définissez le répertoire sur `airops-log-collector`.

<figure><img src="https://344527547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX2n5yPRPynbnWuO4SH0M%2Fuploads%2Fgit-blob-d3a82ed25616b153b6eb6c41dda860f1162cc66f%2Fcloudflare-workers-01-directory.png?alt=media" alt=""><figcaption></figcaption></figure>

Définissez l’exemple de départ sur `exemple Hello World`.

<figure><img src="https://344527547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX2n5yPRPynbnWuO4SH0M%2Fuploads%2Fgit-blob-6a28ae22cd704f476ba29a5fa1df7a42b9a99b03%2Fcloudflare-workers-02-project-example.png?alt=media" alt=""><figcaption></figcaption></figure>

Définissez le modèle sur `Worker consommateur et producteur de file d’attente`.

<figure><img src="https://344527547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX2n5yPRPynbnWuO4SH0M%2Fuploads%2Fgit-blob-d40a4b5afebeebd3322857bbad322cec2f01addb%2Fcloudflare-workers-03-batch-template.png?alt=media" alt=""><figcaption></figcaption></figure>

Définissez la langue sur `TypeScript`.

<figure><img src="https://344527547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX2n5yPRPynbnWuO4SH0M%2Fuploads%2Fgit-blob-06e645b730047ef5c67a980815390d43a54effba%2Fcloudflare-workers-04-language.png?alt=media" alt=""><figcaption></figcaption></figure>

Choisissez **Oui** pour utiliser git pour le contrôle de version.

<figure><img src="https://344527547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX2n5yPRPynbnWuO4SH0M%2Fuploads%2Fgit-blob-9bbaf28aa13bf1c613af4e0628740b1d2a86fe94%2Fcloudflare-workers-05-git.png?alt=media" alt=""><figcaption></figcaption></figure>

Choisissez **Non** pour déployer votre application (nous le ferons plus tard).

<figure><img src="https://344527547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX2n5yPRPynbnWuO4SH0M%2Fuploads%2Fgit-blob-bdb363dcdf8ddde3f76b8bcc194361f9b46905d1%2Fcloudflare-workers-06-deploy.png?alt=media" alt=""><figcaption></figcaption></figure>

### Étape 2 : configurer la route du Worker Cloudflare

Modifiez le `wrangler.json` et configurez votre `pattern`, `zone_name`, les liaisons de file d’attente et `AIROPS_API_URL`.

{% hint style="info" %}
La `pattern` doit être votre domaine réel ou l’URL du site cible, tandis que le `zone_name` doit être le domaine canonique. Par exemple, si votre site cible est `https://blog.example.com`, le `pattern` doit être `blog.example.com` et votre `zone_name` doit être `example.com`.
{% endhint %}

```json
{
  "$schema": "node_modules/wrangler/config-schema.json",
  "name": "airops-log-collector",
  "main": "src/index.ts",
  "compatibility_date": "2026-05-18",
  "observability": {
    "enabled": true
  },
  "queues": {
    "consumers": [
      {
        "queue": "airops-log-collector-queue",
        "max_batch_size": 1000,
        "max_batch_timeout": 60
      }
    ],
    "producers": [
      {
        "binding": "AIROPS_LOG_COLLECTOR_QUEUE",
        "queue": "airops-log-collector-queue"
      }
    ]
  },
  "upload_source_maps": true,
  "compatibility_flags": [
    "nodejs_compat"
  ],
  "route": {
    "pattern": "example.com/*",
    "zone_name": "example.com"
  },
  "vars": {
    "AIROPS_API_URL": "https://ingest.airops.com/api/v1/cloudflare-worker/<YOUR_BRAND_KIT_ID>/ingest"
  }
}
```

### Étape 3 : configurer le code du Worker Cloudflare

Remplacez le contenu du `src/index.ts` fichier par le code suivant.

```typescript
export interface Env {
  AIROPS_API_URL: string;
  AIROPS_API_KEY: string;
  AIROPS_LOG_COLLECTOR_QUEUE: Queue;
}

export default {
  // Le producteur de file d’attente est invoqué à chaque visite de page et enregistre les métadonnées de la requête dans la file d’attente
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
    // Enregistrer l’heure de début de la requête
    const startTime = Date.now();

    // Effectuer la requête
    const response = await fetch(request);

    // Cloner la réponse afin qu’elle puisse être réutilisée
    const responseClone = response.clone();

    ctx.waitUntil(handleRequest(startTime, request, responseClone, env));
    return response;
  },

  // Le consommateur de file d’attente lit les messages de la file et envoie périodiquement des lots à AirOps
  async queue(batch: MessageBatch<string>, env: Env): Promise<void> {
    const body = batch.messages.map(m => m.body).join('\n');

    await fetch(env.AIROPS_API_URL, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': env.AIROPS_API_KEY,
      },
      body,
    }).catch(error => console.error('Failed to send logs:', error))
  }
} satisfies ExportedHandler<Env, string>;

async function handleRequest(startTime: number, request: Request, response: Response, env: Env) {
  const logData = {
    request_start_time: startTime,
    request_end_time: Date.now(),
    status_code: response.status,
    response_bytes: response.bytes.length,
    method: request.method,
    url: request.url,
    user_agent: request.headers.get('user-agent'),
    referer: request.headers.get('referer'),
  };

  await env.AIROPS_LOG_COLLECTOR_QUEUE.send(JSON.stringify(logData));
}
```

### Étape 4 : configurer la clé API AirOps

{% hint style="info" %}
Votre `AIROPS_API_KEY` doit être défini à la même valeur que votre clé API du Workspace, disponible dans `Paramètres → Workspace`.
{% endhint %}

```bash
# Connectez-vous à Cloudflare
npx wrangler login

# Configurez la clé API
npx wrangler secret put AIROPS_API_KEY
```

### Étape 5 : créer la Queue Cloudflare

```bash
npx wrangler queues create airops-log-collector-queue
```

### Étape 6 : déployer le Worker Cloudflare

```bash
# Déployer le Worker Cloudflare
npx wrangler deploy
```

### Étape 7 : vérifier la connexion

Après le déploiement du Worker Cloudflare, les données devraient commencer à circuler dans un délai de **2 à 5 minutes**.

1. Générez du trafic sur votre site web.
2. Dans votre **tableau de bord AirOps**, accédez à **Agent Analytics**. Les données de trafic devraient apparaître sous peu.

***

## Workers alternatif

L’approche d’intégration alternative envoie un événement à AirOps à chaque visite de page. Elle convient mieux aux sites web avec moins de visites de page afin d’éviter de dépasser les limites de débit et n’est donc pas recommandée pour la plupart des sites.

### Étape 1 : initialiser le Worker Cloudflare

Pour ce processus, nous utiliserons la version `2.68.2` de l’interface CLI de Cloudflare. D’autres versions mineures peuvent fonctionner, mais il peut y avoir des différences dans les invites de la CLI.

{% hint style="info" %}
Selon votre environnement de développement, vous devrez peut-être installer manuellement les paquets node suivants : `node-addon-api`, `node-gyp`, et `sharp`.
{% endhint %}

```bash
npm create cloudflare@2.68.2
```

Définissez le répertoire sur `airops-log-collector`.

<figure><img src="https://344527547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX2n5yPRPynbnWuO4SH0M%2Fuploads%2Fgit-blob-d3a82ed25616b153b6eb6c41dda860f1162cc66f%2Fcloudflare-workers-01-directory.png?alt=media" alt=""><figcaption></figcaption></figure>

Définissez l’exemple de départ sur `exemple Hello World`.

<figure><img src="https://344527547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX2n5yPRPynbnWuO4SH0M%2Fuploads%2Fgit-blob-6a28ae22cd704f476ba29a5fa1df7a42b9a99b03%2Fcloudflare-workers-02-project-example.png?alt=media" alt=""><figcaption></figcaption></figure>

Définissez le modèle sur `Worker uniquement`.

<figure><img src="https://344527547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX2n5yPRPynbnWuO4SH0M%2Fuploads%2Fgit-blob-47978f6b8874aeb95c2b8401bcc062ab98c15ee9%2Fcloudflare-workers-03-alternate-template.png?alt=media" alt=""><figcaption></figcaption></figure>

Définissez la langue sur `TypeScript`.

<figure><img src="https://344527547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX2n5yPRPynbnWuO4SH0M%2Fuploads%2Fgit-blob-06e645b730047ef5c67a980815390d43a54effba%2Fcloudflare-workers-04-language.png?alt=media" alt=""><figcaption></figcaption></figure>

Choisissez **Oui** pour utiliser git pour le contrôle de version.

<figure><img src="https://344527547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX2n5yPRPynbnWuO4SH0M%2Fuploads%2Fgit-blob-9bbaf28aa13bf1c613af4e0628740b1d2a86fe94%2Fcloudflare-workers-05-git.png?alt=media" alt=""><figcaption></figcaption></figure>

Choisissez **Non** pour déployer votre application (nous le ferons plus tard).

<figure><img src="https://344527547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX2n5yPRPynbnWuO4SH0M%2Fuploads%2Fgit-blob-bdb363dcdf8ddde3f76b8bcc194361f9b46905d1%2Fcloudflare-workers-06-deploy.png?alt=media" alt=""><figcaption></figcaption></figure>

### Étape 2 : configurer la route du Worker Cloudflare

Modifiez le `wrangler.json` et configurez votre `pattern`, `zone_name`, et `AIROPS_API_URL`.

{% hint style="info" %}
La `pattern` doit être votre domaine réel ou l’URL du site cible, tandis que le `zone_name` doit être le domaine canonique. Par exemple, si votre site cible est `https://blog.example.com`, le `pattern` doit être `blog.example.com` et votre `zone_name` doit être `example.com`.
{% endhint %}

```json
{
  "$schema": "node_modules/wrangler/config-schema.json",
  "name": "airops-log-collector",
  "main": "src/index.ts",
  "compatibility_date": "2026-05-18",
  "observability": {
    "enabled": true
  },
  "upload_source_maps": true,
  "compatibility_flags": [
    "nodejs_compat"
  ],
  "route": {
    "pattern": "example.com/*",
    "zone_name": "example.com"
  },
  "vars": {
    "AIROPS_API_URL": "https://ingest.airops.com/api/v1/cloudflare-worker/<YOUR_BRAND_KIT_ID>/ingest"
  }
}
```

### Étape 3 : configurer le code du Worker Cloudflare

Remplacez le contenu du `src/index.ts` fichier par le code suivant.

```typescript
export interface Env {
  AIROPS_API_URL: string;
  AIROPS_API_KEY: string;
}

export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
    // Enregistrer l’heure de début de la requête
    const startTime = Date.now();

    // Effectuer la requête
    const response = await fetch(request);

    // Cloner la réponse afin qu’elle puisse être réutilisée
    const responseClone = response.clone();

    ctx.waitUntil(handleRequest(startTime, request, responseClone, env));
    return response;
  }
} satisfies ExportedHandler<Env>;

async function handleRequest(startTime: number, request: Request, response: Response, env: Env) {
	const logData = {
		request_start_time: startTime,
		request_end_time: Date.now(),
		status_code: response.status,
		response_bytes: response.bytes.length,
		method: request.method,
		url: request.url,
		user_agent: request.headers.get('user-agent'),
		referer: request.headers.get('referer'),
    }

  await fetch(env.AIROPS_API_URL, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': env.AIROPS_API_KEY
    },
    body: JSON.stringify(logData)
  }).catch(error => console.error('Failed to send logs:', error))
}
```

### Étape 4 : configurer la clé API AirOps

{% hint style="info" %}
Votre `AIROPS_API_KEY` doit être défini à la même valeur que votre clé API du Workspace, disponible dans `Paramètres → Workspace`.
{% endhint %}

```bash
# Connectez-vous à Cloudflare
npx wrangler login

# Configurez la clé API
npx wrangler secret put AIROPS_API_KEY
```

### Étape 5 : déployer le Worker Cloudflare

```bash
# Déployer le Worker Cloudflare
npx wrangler deploy
```

### Étape 6 : vérifier la connexion

Après le déploiement du Worker Cloudflare, les données devraient commencer à circuler dans un délai de **2 à 5 minutes**.

1. Générez du trafic sur votre site web.
2. Dans votre **tableau de bord AirOps**, accédez à **Agent Analytics**. Les données de trafic devraient apparaître sous peu.

***

## Limites de débit

L’ingesteur AirOps applique une limite de débit de **5 requêtes par minute et par clé API**. Le Worker en temps réel envoie une requête par visite de page, donc cette option convient mieux aux sites à faible trafic. Pour les sites à fort trafic, regroupez les requêtes ou utilisez une option d’ingestion tamponnée.

***

## Ce qu’AirOps suit

Une fois connecté, AirOps :

* **ingère toutes les requêtes Cloudflare**: vues de page, ressources et appels API
* **classe le trafic des bots IA**: identifie les visites provenant de ChatGPT, Claude, Google, Perplexity, Meta, Apple, Bing, Bytedance, Common Crawl et autres
* **catégorise le comportement de crawl**: distingue les robots d’entraînement IA, les récupérations pour la recherche IA, l’indexation IA et la navigation IA initiée par l’utilisateur
* **affiche des analyses**: répartitions du trafic, ratios bots/humains et tendances de crawl dans votre tableau de bord


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.airops.com/docs/fr/insights/onsite/traffic/cloudflare-worker-agent-analytics.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
