Trackily Docs

Catalogue des nodes

Tous les types de nodes que tu peux drag-and-drop dans le workflow builder. Pour chaque node : ce qu'il fait, ce qu'il config, et un exemple d'usage.

Les nodes sont organisés en 5 catégories, visibles dans la palette gauche du builder (public/cloaking-builder.html:262) :

  1. Trigger — point d'entrée du workflow (1 seul)
  2. Detection — évalue une condition, route vers "detected" ou "clean"
  3. Action — terminal : redirect, 404, allow, block, log
  4. Routing — splitte le trafic selon un attribut (device, geo, OS…)
  5. Destinations — termine vers une URL / landing / offer / produit

Le moteur d'évaluation est dans server.js:7540 (le runtime à chaque click) et dans server.js:6479 (le simulateur — même code).

Convention des sorties

  • Un node Detection a 2 sorties : output_1 = "Detected" (la condition est vraie), output_2 = "Clean" (la condition est fausse).
  • Un node Routing a N sorties : une par catégorie (mobile, desktop, tablet, smart TV pour route_device…), + une dernière "Other / Default" pour les valeurs qui ne matchent rien.
  • Un node Action terminal n'a pas de sortie — il termine l'évaluation.

Les outputs sont nommés output_1, output_2, etc. dans le JSON Drawflow. Le moteur les indexe à partir de 0 en interne.

1. Trigger

trigger_visitor — Visitor Arrives

Le point d'entrée. Il en faut exactement un par workflow, sinon l'évaluation est skip avec No trigger node found in workflow.

Field Type Notes
(aucune config) Toujours {}

Sortie : Next (la 1ère sortie, qui mène au node suivant).

Exemple d'usage : tous les workflows commencent par ce node. Il est seedé automatiquement quand tu cliques "+ New Workflow" dans l'UI.

2. Detection

Toutes les detection nodes suivent la même logique : si la condition est vraie → sortie 1 ("Detected"), sinon → sortie 2 ("Clean").

check_reviewer_ip — Reviewer IP

Détecte les IPs des reviewers Facebook, Google, TikTok, Bing, Snapchat, Pinterest (liste CIDR codée en dur — voir Filters).

Field Type Notes
(aucune config) Vérifie contre toutes les plateformes

Logic : isReviewerIP(ip) (voir server.js:1681). Si l'IP est dans un des CIDR ranges → detected = true.

Exemple : à mettre en TOUT PREMIER après le trigger. C'est gratuit (CIDR match) et bloque les reviewers avant tout le reste.

check_reverse_dns — Reverse DNS

Fait un reverse DNS lookup sur l'IP et vérifie si le hostname termine par un domaine de reviewer connu (*.facebook.com, *.googlebot.com, etc.).

Field Type Notes
patterns array of strings Optionnel. Override la liste par défaut. Format : suffixes de domaine.

Logic : dns.reverse(ip) puis test hostname.endsWith(pattern). Cache 1h via reverseDNSCache.

Coût : ~10–20ms pour le premier lookup, puis 0ms (cache).

Exemple : à mettre après check_reviewer_ip — capture les reviewers dont l'IP n'est pas dans la liste CIDR mais dont le hostname trahit l'origine.

check_vpn — VPN / Proxy / Tor

Détecte les connexions cachées via 4 mécanismes combinés.

Field Type Défaut Notes
check_vpn boolean true Match ISP contre la liste KNOWN_VPN_ASNS (nordvpn, expressvpn, surfshark…)
check_proxy boolean true Détecte headers proxy (X-Forwarded-For chain > 2, Via, etc.) + flag is_hosting de l'API GeoIP
check_tor boolean true Match ISP contient "tor ", "tor exit", "tor relay"

Logic : voir server.js:7592. detected = true si n'importe lequel des checks activés trigger.

Exemple : node central de la plupart des workflows. Combine avec check_datacenter pour couvrir les VPN qui passent en mode "résidentiel".

check_datacenter — Datacenter IP

Vérifie si l'ISP contient un mot-clé de datacenter connu (AWS, OVH, Hetzner, Linode, DigitalOcean, Vultr, Contabo, etc. — liste complète dans server.js:1760).

Field Type Notes
(aucune config) Liste hard-codée

Logic : DATACENTER_KEYWORDS.some(k => isp.toLowerCase().includes(k)).

Exemple : derrière check_vpn. Un user résidentiel n'arrive jamais depuis "Amazon Web Services" — si l'ISP contient "aws", c'est presque sûr un bot ou un scraper.

check_bot_ua — Bot User-Agent

Détecte les User-Agents de bots connus (Googlebot, bingbot, curl, wget, Selenium, etc.).

Field Type Notes
(aucune config) Liste KNOWN_BOTS dans server.js

Logic : isBot(ua) — voir server.js:1627.

Exemple : à mettre EN PREMIER ou DEUXIÈME. C'est instantané et bloque déjà 30–50% du trafic bot.

check_fraud_score — Fraud Score

Compare le fraud score combiné (server + JS) à un threshold.

Field Type Défaut Notes
threshold integer (0-100) 50 Si fraudScore >= threshold → detected

Logic : detected = fraudScore >= config.threshold. Le score est calculé en amont par calculateFraudScore() (combine UA, IP, headers, geo, CF data, IPQS si configuré).

Exemple : node "fourre-tout" en fin de workflow — pour les visiteurs qui ont passé tous les autres checks mais ont accumulé pas mal de flags suspects.

check_js_fingerprint — JS Fingerprint

Détection basée sur des signaux client-side : canvas fingerprint, WebGL, AudioContext, WebDriver.

Field Type Notes
(config UI) Le check tourne dans /cloak.js côté navigateur, le résultat arrive via beacon

Logic server-side : detected = false (le check ne peut pas s'évaluer server-side — voir server.js:7610). Il faut combiner avec un node delay_check ou le résultat arrive via un beacon JS qui re-trigger le workflow.

Exemple : pour les workflows avancés qui veulent attraper des bots Puppeteer/Playwright/Selenium qui passent tous les checks IP/UA. Combine avec delay_check qui wait 500ms le temps que le JS fingerprint remonte.

check_behavior — Behavioral Check

Détecte les patterns inhumains : pas de mouvement souris, pas de scroll, time-on-page < 1s.

Field Type Notes
(config UI) Idem check_js_fingerprint — résultat client-side

Logic server-side : detected = false (s'évalue côté client uniquement).

Exemple : utile pour les bots headless ultra-furtifs. Souvent overkill pour la plupart des cas.

check_country — Country

Compare le pays géolocalisé (GeoIP ou CF country) contre une liste.

Field Type Défaut Notes
countries string (CSV) "" Codes ISO-2 séparés par virgule. Ex : US,CA,GB,AU
mode string "whitelist" whitelist = detected si PAS dans la liste. blacklist = detected si dans la liste.

Logic : voir server.js:7614. Attention au sens — whitelist route les visiteurs hors liste vers la sortie "Detected" (i.e. typiquement vers safe page).

Exemple whitelist : seul le trafic US/CA est autorisé sur ta money page → countries="US,CA", mode="whitelist", sortie "Detected" → safe page, sortie "Clean" → continue.

Exemple blacklist : bloquer le trafic indien et russe → countries="IN,RU", mode="blacklist", sortie "Detected" → safe page.

check_referrer — Referrer

Vérifie si le referrer HTTP contient un des patterns donnés.

Field Type Défaut Notes
patterns string (CSV) "" Patterns de domaine, ex : facebook.com,fb.com,m.facebook.com

Logic : detected = patterns.some(p => referer.toLowerCase().includes(p)). Case-insensitive.

Exemple : valider que le trafic Meta vient bien de Facebook → patterns="facebook.com,fb.com", sortie "Detected" → continue, sortie "Clean" → safe page (visiteur arrivé sans referrer Meta = suspect).

check_time — Time Rules

Vérifie si l'heure UTC actuelle est dans une plage donnée. Utile pour cloak pendant les heures de bureau des reviewers (Mon-Fri 8am-6pm UTC couvre US + EU).

Field Type Défaut Notes
hours_from integer (0-23) 0 Heure UTC de début
hours_to integer (0-23) 23 Heure UTC de fin

Logic : detected = utcHour >= hours_from && utcHour <= hours_to.

Exemple "agressive black hat" : hours_from=8, hours_to=18 → safe page pendant les heures de boulot des reviewers, money page le reste du temps.

check_device — Device Type

Match le device type du visiteur contre une liste.

Field Type Défaut Notes
devices string (CSV) "Mobile,Desktop" Valeurs possibles : Mobile, Desktop, Tablet, Smart TV

Logic : detected = devices.includes(uaParsed.device_type).

Exemple : ton offer est mobile-only → devices="Mobile", sortie "Detected" → continue, sortie "Clean" → safe page (desktop = pas le bon trafic).

3. Actions terminales

Ces nodes terminent l'évaluation et déclenchent une réponse HTTP. Pas de sortie.

action_safe_page — Show Safe Page

Redirect 302 vers une URL "safe" (typiquement un blog ou un article).

Field Type Notes
url string URL de destination. Si vide → https://google.com par défaut.

Logic : res.redirect(config.url || 'https://google.com').

Exemple : url = "https://en.wikipedia.org/wiki/Antivirus_software" pour un workflow McAfee.

action_404 — Return 404

Réponse HTTP 404 brute.

Field Type Notes
(aucune) Body = "Page Not Found"

Logic : res.status(404).send('Page Not Found').

Exemple : pour faire croire à un reviewer que la page n'existe pas (plus discret qu'un redirect).

action_redirect — Redirect URL

Comme action_safe_page mais sémantiquement différent : utilisé pour rediriger un visiteur "blanc" vers une page custom (pas forcément une safe page).

Field Type Notes
url string Destination

Exemple : geo-redirect en sortie d'un route_country → users IN/PK/BD vers ton offer indienne.

action_block — Block & Blacklist

Réponse HTTP 403 + ajoute l'IP à la blacklist permanente.

Field Type Défaut Notes
blacklist boolean false Si true, append à ip_blacklist avec reason "Cloaking workflow block"

Logic : res.status(403).send('Forbidden') + db.addToBlacklist() si blacklist=true.

Exemple : bot ultra-confirmé (fraud_score ≥ 95 + datacenter + headless) → block + blacklist pour ne plus jamais le voir.

action_allow — Allow (Real Page)

Termine le workflow et continue vers le flow normal de la campagne (landing → offer).

Field Type Notes
(aucune)

Logic : break de la boucle workflow, le code continue vers le flow engine.

Exemple : node final sur le chemin "le visiteur est OK". Indispensable — sans ça, le workflow tombe dans un cul-de-sac.

action_log — Log Event

Log un event de fraud sans bloquer. Le visiteur continue.

Field Type Défaut Notes
event_name string "cloak_log" Nom de l'event dans fraud_events.event_type

Logic : db.createFraudEvent({ event_type: config.event_name, … }) puis continue vers la sortie 1.

Exemple : "je veux savoir combien d'iPhone iOS 14 arrivent sur ma campagne, sans rien bloquer" → check_device → si match → action_log event="ios14_visitor" → continue.

4. Routing nodes

Routes le visiteur sur une sortie parmi N selon un attribut. Pas une condition binaire.

route_device — Route by Device

Sorties Order
1 Mobile
2 Desktop
3 Tablet
4 Smart TV
N Other (catch-all)

Logic : voir server.js:7631. Mapping mobile=0, desktop=1, tablet=2, smart tv=3. Si le device ne match rien → dernière sortie.

Exemple : montrer une landing optimisée Mobile vs Desktop.

route_country — Route by Country

Field Type Notes
group_a string CSV Pays du groupe A. Ex : US,CA,AU,GB (Tier 1)
group_b string CSV Pays du groupe B. Ex : DE,FR,ES,IT,NL (Tier 2)
group_c string CSV Pays du groupe C. Ex : IN,PK,BD (Tier 3)
... Tu peux ajouter autant de groupes que tu as de sorties

Sorties : une par groupe + une "Other" (catch-all en dernière position).

Logic : pour chaque groupe group_a..z dans l'ordre, premier qui contient le pays gagne. Sinon → dernière sortie. Voir server.js:7639.

Exemple : 3 sorties → Tier 1 (offer high payout) | Tier 2 (offer medium) | Other (safe page).

route_os — Route by OS

Sorties Order
1 Windows
2 Mac
3 Android
4 iOS
N Other

Mapping fixe (voir server.js:7654) : windows=0, mac/macos=1, android=2, ios/iphone/ipad=3.

route_browser — Route by Browser

Sorties Order
1 Chrome
2 Safari
3 Firefox
4 Edge
5 Opera
6 IE
N Other

route_language — Route by Language

Field Type Notes
languages string CSV Ex : en,fr,de — codes ISO-2

Sorties : 1 par langue dans l'ordre du CSV + "Other".

Logic : lang = navigator language[0] → premier match dans languages[] gagne. Voir server.js:7669.

route_ab_split — A/B/C Split

Random weighted split.

Field Type Notes
weight_a integer Poids relatif sortie 1
weight_b integer Poids relatif sortie 2
weight_c, weight_d, ... integer Pour 3+ sorties

Sorties : N sorties (autant que tu connectes), labellisées A / B / C / D…

Logic : rand = Math.random() * total_weight, premier cumulative >= rand gagne. Voir server.js:7677.

Exemple : tester 3 safe pages différentes pour voir laquelle "rassure" le plus → 33/33/34.

route_source — Route by Source

Route selon la valeur de sub2 (typiquement l'ID adset/placement).

Sorties : config-driven, une par valeur de sub2 listée.

Exemple : routing adset par adset pour un test isolé.

5. Destinations

Termine le workflow vers une cible spécifique (override le flow normal de la campagne).

dest_url — Redirect to URL

Field Type Notes
url string URL de destination

Logic : res.redirect(config.url). Override le flow engine.

dest_landing — Show Landing Page

Termine en laissant le flow normal de la campagne servir la landing. Équivalent à action_allow.

dest_offer — Go to Offer

Termine et laisse le flow normal envoyer vers l'offer.

dest_product — Go to Product

Pour le commerce natif — termine vers une product page.

Combinaisons recommandées

Cloak basique anti-bot (3 nodes)

trigger_visitor → check_bot_ua → [Detected] → action_safe_page
                                → [Clean] → action_allow

Cloak Meta compliance (5 nodes)

trigger_visitor
  → check_reviewer_ip → [Detected] → action_safe_page
                      → [Clean]
  → check_reverse_dns → [Detected] → action_safe_page
                      → [Clean]
  → check_vpn → [Detected] → action_safe_page
              → [Clean] → action_allow

Cloak agressif (9 nodes)

trigger_visitor
  → check_reviewer_ip → safe
  → check_reverse_dns → safe
  → check_bot_ua → safe
  → check_vpn → safe
  → check_datacenter → safe
  → check_country (whitelist US/CA/GB/AU) → safe
  → check_fraud_score (threshold 40) → safe
  → action_allow

Cloak + routing geo (combiné)

trigger_visitor
  → check_vpn → [Detected] → action_safe_page
              → [Clean]
  → route_country
       Tier 1 (US,CA,AU) → dest_url=https://my-offer.com/tier1
       Tier 2 (EU)       → dest_url=https://my-offer.com/tier2
       Other             → action_safe_page

Erreurs courantes

  • Le workflow ne fait rien : il manque le node trigger_visitor ou il y en a plusieurs
  • Tout le trafic est cloaké : tu as inversé une sortie (sortie 1 = Detected, sortie 2 = Clean — pas l'inverse)
  • Le check_js_fingerprint ne détecte rien : c'est normal en server-only, il faut le combiner avec un delay_check ou activer le beacon JS
  • check_country whitelist bloque tout : mode="whitelist" + countries="" (vide) → personne ne match → tout le monde est routé vers "Detected" → safe page. Vérifie que ta liste de pays est remplie.
  • Cul-de-sac : un node de détection a une sortie non connectée → le visiteur tombe dans le vide → le code continue vers le flow normal (équivalent allow silencieux)

Voir aussi