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

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
- Va dans Campaigns → édite ta campagne
- Section Cloaking → dropdown "Cloaking Workflow"
- Sélectionne ton workflow (ex : "Meta Compliance — Strict")
- 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 :
- 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). - Avoir au moins un node action terminal (
action_safe_page,action_404,action_redirect,action_block,action_allow) sur chaque chemin possible. - 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
- Commence simple — un seul
check_vpn+action_safe_pagecouvre déjà 60% des cas - Ajoute une
check_reviewer_ipen tête quand tu pushes du trafic payant — gratuit et instantané - Mets
check_countryaprès les checks de bot — pas la peine de check le pays d'un bot - N'oublie pas
action_allowsur la branche "tout est OK" — sans ça, le visiteur reste bloqué dans le workflow - Teste avec le simulateur avant de mettre en prod
- Sauvegarde un workflow qui marche en exportant son JSON (bouton Export du builder)
- Garde une copie "safe" : un workflow
action_allowdirect 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 = trueET non supprimé (deleted_at IS NULL) - Tout le trafic est bloqué → tu as un node de détection mal configuré (typique :
check_countryen modewhitelistmais avec une liste vide → tout le monde est bloqué) - Le workflow ne s'exécute pas → la campagne n'a pas
cloaking_workflow_idset, 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
- Nodes — le catalogue complet des nodes disponibles
- Filters — les listes IP / DNS / ASN utilisées par les checks
- Cloaking — index — concept général
- Campaigns → cloaking — la vue côté campagne
- Vue d'ensemble — où le cloaking s'insère dans le chemin du click