Trackily Docs

Workflows de cloaking

Un workflow = un graphe de nodes qui décide, pour chaque visiteur, s'il voit la money page, la safe page, ou un 404. Cette page t'explique comment en créer, l'éditer, le dupliquer et l'attacher à une campagne.

À quoi ça sert

Un workflow de cloaking est stocké dans la table cloaking_workflows :

CREATE TABLE cloaking_workflows (
  id           SERIAL PRIMARY KEY,
  name         TEXT NOT NULL DEFAULT 'Untitled',
  workflow_data JSONB DEFAULT '{}',
  is_active    BOOLEAN DEFAULT true,
  created_at   TIMESTAMPTZ DEFAULT NOW(),
  updated_at   TIMESTAMPTZ DEFAULT NOW(),
  deleted_at   TIMESTAMPTZ DEFAULT NULL
);

(voir database.js:535)

Le champ workflow_data stocke le graphe complet au format Drawflow :

{
  "drawflow": {
    "Home": {
      "data": {
        "1": { "id": 1, "name": "trigger_visitor", "data": {...},
               "inputs": {}, "outputs": { "output_1": { "connections": [{"node":"2","output":"input_1"}] } },
               "pos_x": 50, "pos_y": 250 },
        "2": { "id": 2, "name": "check_vpn", ... },
        ...
      }
    }
  }
}

Une campagne peut référencer un workflow via campaigns.cloaking_workflow_id (FK ON DELETE SET NULL — si tu supprimes le workflow, les campagnes survivent sans cloaking).

Le workflow seedé par défaut

Au premier boot, Trackily seede un workflow "VPN Blocker (Built-in)" :

trigger_visitor
   │
   ▼
check_vpn  ─── Detected ───► action_safe_page (https://example.com/blog)
   │
   Clean
   ▼
check_datacenter  ─── Detected ───► action_safe_page (idem)
   │
   Residential
   ▼
action_allow

(voir database.js:3961)

C'est un bon point de départ — il bloque les VPN/Tor/proxy + les IP de datacenter (AWS, OVH, Hetzner, Linode, etc.). Tu peux le cloner, l'éditer, ou en créer un from scratch.

Le seed est idempotent par nom : si tu renommes ou supprimes "VPN Blocker (Built-in)", il ne sera pas recréé au redémarrage. Le seed check juste s'il existe une row avec ce nom exact.

Lister les workflows

Note : la liste cloaking est accessible via le menu latéral "Cloaking". Tu peux aussi gérer les toggles globaux dans Settings → Cloaking (voir Filters) ou ouvrir le builder visuel directement via /cloaking-builder.

La liste affiche :

  • Nom + statut (active / inactive)
  • Nombre de campagnes qui l'utilisent
  • Date de dernière modification
  • Boutons : Éditer (ouvre le builder), Dupliquer, Pause, Delete

Créer un nouveau workflow

Via l'UI

  1. Sidebar → Cloaking → bouton + New Workflow
  2. Donne un nom (ex : "Meta Compliance — Strict")
  3. Tu arrives sur /cloaking-builder?id=<new_id>
  4. Drag-and-drop les nodes depuis la palette gauche
  5. Connecte-les avec les flèches (clique + drag depuis un point de sortie vers un point d'entrée)
  6. Click un node pour le configurer dans le panneau de droite
  7. Save en haut à droite — le graphe est sérialisé en JSON et stocké dans workflow_data

Builder visuel

Via MCP

{
  "name": "create_cloaking_workflow",
  "arguments": {
    "name": "Meta Compliance — Strict",
    "workflow_data": {
      "drawflow": {
        "Home": {
          "data": {
            "1": { "id": 1, "name": "trigger_visitor", "data": { "type": "trigger_visitor", "config": {} }, "inputs": {}, "outputs": { "output_1": { "connections": [{"node":"2","output":"input_1"}] } }, "pos_x": 50, "pos_y": 250 },
            "2": { "id": 2, "name": "check_vpn", "data": { "type": "check_vpn", "config": { "check_vpn": true, "check_proxy": true, "check_tor": true } }, "inputs": { "input_1": { "connections": [{"node":"1","input":"output_1"}] } }, "outputs": { "output_1": { "connections": [{"node":"3","output":"input_1"}] }, "output_2": { "connections": [{"node":"4","output":"input_1"}] } }, "pos_x": 300, "pos_y": 200 },
            "3": { "id": 3, "name": "action_safe_page", "data": { "type": "action_safe_page", "config": { "url": "https://en.wikipedia.org/wiki/McAfee" } }, "inputs": { "input_1": { "connections": [{"node":"2","input":"output_1"}] } }, "outputs": {}, "pos_x": 600, "pos_y": 100 },
            "4": { "id": 4, "name": "action_allow", "data": { "type": "action_allow", "config": {} }, "inputs": { "input_1": { "connections": [{"node":"2","input":"output_2"}] } }, "outputs": {}, "pos_x": 600, "pos_y": 300 }
          }
        }
      }
    }
  }
}

Construire le JSON Drawflow à la main est pénible. Pour les usages MCP, mieux vaut dupliquer un workflow existant (duplicate_cloaking_workflow) puis l'éditer.

Éditer un workflow existant

Le builder reload automatiquement le graphe sérialisé. Tu peux :

  • Déplacer un node en le draguant
  • Reconnecter une flèche en la draguant vers un autre node
  • Supprimer un node : clique dessus → touche Suppr ou bouton "Delete node" du panneau properties
  • Zoomer : boutons + / − / ⊙ en bas à droite, ou Ctrl+molette
  • Pan : drag sur le fond du canvas
  • Import / Export JSON : boutons header pour partager des workflows entre instances

Toute modif n'est pas auto-sauvée — tu dois cliquer Save explicitement. Un indicateur "unsaved changes" s'affiche en haut.

Attacher un workflow à une campagne

C'est l'étape essentielle — un workflow sans campagne ne fait rien.

Via l'UI

  1. Va dans Campaigns → édite ta campagne
  2. Section Cloaking → dropdown "Cloaking Workflow"
  3. Sélectionne ton workflow (ex : "Meta Compliance — Strict")
  4. Save

Via MCP

{
  "name": "assign_cloaking_workflow_to_campaign",
  "arguments": {
    "campaign_id": 42,
    "workflow_id": 7
  }
}

Une fois attaché, chaque visite sur /c/<slug-de-la-campagne> exécute le workflow avant le routing normal.

Dupliquer un workflow

Cas d'usage : tu veux une variante stricte et une variante soft, ou tu veux tester des changements sans casser la version qui tourne en prod.

Via l'UI

Liste cloaking → ligne du workflow → bouton Duplicate. Le nouveau workflow s'appelle "Mon Workflow (copy)" et reprend toute la conf.

Via MCP

{
  "name": "duplicate_cloaking_workflow",
  "arguments": {
    "id": 7,
    "new_name": "Meta Compliance — Strict (v2)"
  }
}

Pause / Resume

Un workflow is_active = false n'est jamais évalué, même si une campagne le référence. Utile pour désactiver un workflow temporairement sans le supprimer ni le détacher des campagnes.

Via MCP

{
  "name": "update_cloaking_workflow",
  "arguments": {
    "id": 7,
    "is_active": false
  }
}

Supprimer un workflow

Soft delete via deleted_at (voir migration v19). Les campagnes qui le référencent passent à cloaking_workflow_id = NULL automatiquement (FK ON DELETE SET NULL).

Via MCP

{
  "name": "delete_cloaking_workflow",
  "arguments": { "id": 7 }
}

Tu peux le restaurer depuis l'onglet Archive.

Tester un workflow sans envoyer du trafic

Trackily fournit un simulateur qui exécute le workflow contre un faux visiteur — utile pour vérifier que ta logique fait ce que tu veux avant de mettre le workflow en prod.

L'endpoint admin /admin/api/campaigns/:id/simulate prend :

{
  "ip": "203.0.113.1",       // ou "auto" pour 8.8.8.8
  "ua": "Mozilla/5.0 ...",
  "language": "en-US,en;q=0.9",
  "referrer": "https://facebook.com/ad",
  "num_clicks": 1
}

Le retour contient un steps[] qui te raconte tout :

Processing campaign 42: Meta US Push
GeoIP: US | New York | ISP: Comcast
UA: Windows Chrome Desktop
Fraud score: 12/100 | Flags: no_cookies
Loading cloaking workflow #7
Workflow: "Meta Compliance — Strict"
→ Trigger: Visitor Arrives
→ Check VPN/Proxy/Tor: 🟢 Clean [ISP: Comcast]
→ Check Datacenter: 🟢 Residential
✅ ACTION: Allow (real page)
Found 1 flow(s)
…

C'est le même moteur que /c/:slug, sans rien INSERT en DB. Voir server.js:6479.

Tester depuis l'UI

Sur la fiche d'une campagne, tu as un bouton "Simulate visit" qui appelle ce endpoint et affiche le steps[] formaté. Idéal pour débugger un workflow qui ne fait pas ce que tu veux.

Structure d'un graphe valide

Pour que le moteur puisse l'évaluer, un workflow DOIT :

  1. Avoir exactement un node trigger_visitor (le point d'entrée). S'il en manque ou s'il y en a plusieurs, l'évaluation est skip (No trigger node found in workflow).
  2. Avoir au moins un node action terminal (action_safe_page, action_404, action_redirect, action_block, action_allow) sur chaque chemin possible.
  3. Ne pas avoir de cycle (le moteur a une limite hard de 20 steps par évaluation pour éviter une boucle infinie — voir server.js:7567).

Si un node de détection a une sortie non connectée, le visiteur qui prend ce chemin tombe dans un cul-de-sac → l'évaluation termine sans action → le code continue vers le flow normal (équivalent à action_allow).

Best practices

  1. Commence simple — un seul check_vpn + action_safe_page couvre déjà 60% des cas
  2. Ajoute une check_reviewer_ip en tête quand tu pushes du trafic payant — gratuit et instantané
  3. Mets check_country après les checks de bot — pas la peine de check le pays d'un bot
  4. N'oublie pas action_allow sur la branche "tout est OK" — sans ça, le visiteur reste bloqué dans le workflow
  5. Teste avec le simulateur avant de mettre en prod
  6. Sauvegarde un workflow qui marche en exportant son JSON (bouton Export du builder)
  7. Garde une copie "safe" : un workflow action_allow direct sans check, à attacher en cas de fausse alerte de blocage massif

Erreurs courantes

  • "Workflow non trouvé" dans les logs → vérifie que le workflow est is_active = true ET non supprimé (deleted_at IS NULL)
  • Tout le trafic est bloqué → tu as un node de détection mal configuré (typique : check_country en mode whitelist mais avec une liste vide → tout le monde est bloqué)
  • Le workflow ne s'exécute pas → la campagne n'a pas cloaking_workflow_id set, OU le workflow est en pause
  • Le graphe ne se sauve pas → un node a un nom invalide (ex : tu as fait un copier-coller depuis un workflow plus ancien). Recrée le node depuis la palette.

Voir aussi