Skip to Content
Getting StartedBot Script

Getting Started with Bot Script

Automate BotBrowser without Playwright or Puppeteer using --bot-script and the Chrome Debugger API.


Prerequisites

  • BotBrowser binary installed on your system. See INSTALLATION.md for platform-specific setup.
  • A profile file (.enc for production, .json for local development). Download from GitHub Releases  or use the profiles in profiles/ .
  • A JavaScript file containing your automation logic.
  • No Node.js, Playwright, or Puppeteer installation required.

Quick Start

1. Create a bot script

Save the following as my-script.js:

console.log("Bot script loaded."); if (typeof chrome !== "undefined" && chrome.debugger) { console.log("chrome.debugger API is available."); // Find all browser targets chrome.debugger.getTargets(function (targets) { targets.forEach(function (target) { if (target.type === "page") { console.log("Found page:", target.url); } }); }); } else { console.log("ERROR: chrome.debugger API not available."); }

2. Launch BotBrowser with the script

# Windows chrome.exe --bot-profile="C:\path\to\profile.enc" --bot-script="C:\path\to\my-script.js" # macOS /Applications/Chromium.app/Contents/MacOS/Chromium \ --bot-profile="/path/to/profile.enc" \ --bot-script="/path/to/my-script.js" # Ubuntu chromium-browser \ --bot-profile="/path/to/profile.enc" \ --bot-script="/path/to/my-script.js"

That is it. BotBrowser loads the profile, opens a browser window, and executes your script in a privileged context.


How It Works

The --bot-script flag tells BotBrowser to execute a JavaScript file in a privileged, non-extension context immediately after startup. This context provides:

  1. Full chrome.debugger API access. You can attach to any browser target (page, iframe, service worker) and send Chrome DevTools Protocol (CDP) commands directly.

  2. No framework artifacts. Because no external framework is loaded, the page context remains clean. There are no Playwright bindings, no Puppeteer protocol hooks, and no framework-introduced artifacts in the page context.

  3. Early execution. The script runs before the first page navigation completes, allowing you to set up CDP listeners, intercept network requests, or configure protections before any page code executes.

  4. Standard browser APIs. You have access to console, setTimeout, setInterval, fetch, and other standard APIs alongside the chrome.* extension APIs.


Common Scenarios

Attaching to a page and sending CDP commands

chrome.debugger.getTargets(function (targets) { const pageTarget = targets.find((t) => t.type === "page"); if (!pageTarget) return; chrome.debugger.attach({ targetId: pageTarget.id }, "1.3", function () { if (chrome.runtime.lastError) { console.log("Attach failed:", chrome.runtime.lastError.message); return; } // Enable the Page domain chrome.debugger.sendCommand( { targetId: pageTarget.id }, "Page.enable", {}, function () { console.log("Page domain enabled."); } ); // Navigate to a URL chrome.debugger.sendCommand( { targetId: pageTarget.id }, "Page.navigate", { url: "https://example.com" }, function () { console.log("Navigation started."); } ); }); });

Interacting with iframe content

Bot scripts can monitor for embedded iframes and interact with them using CDP input events:

let activeTargets = new Set(); function startMonitoring() { chrome.debugger.getTargets(function (targets) { targets.forEach(function (target) { if (target.type === "iframe" && !activeTargets.has(target.id)) { activeTargets.add(target.id); interactWithFrame(target.id); } }); setTimeout(startMonitoring, 2000); }); } function interactWithFrame(targetId) { chrome.debugger.attach({ targetId: targetId }, "1.3", function () { if (chrome.runtime.lastError) { activeTargets.delete(targetId); return; } // Click within the iframe at a specific coordinate setTimeout(function () { chrome.debugger.sendCommand( { targetId: targetId }, "Input.dispatchMouseEvent", { type: "mousePressed", x: 30, y: 30, button: "left", clickCount: 1 } ); setTimeout(function () { chrome.debugger.sendCommand( { targetId: targetId }, "Input.dispatchMouseEvent", { type: "mouseReleased", x: 30, y: 30, button: "left", clickCount: 1 } ); activeTargets.delete(targetId); }, 100); }, 500); }); } startMonitoring();

Human-like mouse movement

async function moveMouse(targetId, fromX, fromY, toX, toY, steps) { for (let i = 0; i <= steps; i++) { const progress = i / steps; const x = fromX + (toX - fromX) * progress + Math.random() * 0.7; const y = fromY + (toY - fromY) * progress + Math.random() * 0.7; await new Promise((resolve) => { chrome.debugger.sendCommand( { targetId: targetId }, "Input.dispatchMouseEvent", { type: "mouseMoved", x: x, y: y, modifiers: 0, buttons: 0 }, resolve ); }); await new Promise((r) => setTimeout(r, 12 + Math.random() * 18)); } }

Typing with realistic cadence

async function typeText(targetId, text) { for (const ch of text) { await new Promise((resolve) => { chrome.debugger.sendCommand( { targetId: targetId }, "Input.insertText", { text: ch }, resolve ); }); await new Promise((r) => setTimeout(r, 35 + Math.random() * 45)); } }

Available APIs

Bot scripts run in a privileged isolated page context. The following APIs are available:

APIDescription
chrome.debugger.getTargets()List all browser targets (pages, iframes, workers)
chrome.debugger.attach()Attach the debugger to a target
chrome.debugger.detach()Detach from a target
chrome.debugger.sendCommand()Send any CDP command to an attached target
chrome.runtime.lastErrorCheck for errors after API calls
console.log()Log messages (visible in the terminal)
setTimeout() / setInterval()Standard timing functions

For the full list of CDP commands you can send via chrome.debugger.sendCommand(), see the Chrome DevTools Protocol documentation .


When to Use Bot Script vs Frameworks

ConsiderationBot ScriptPlaywright / Puppeteer
DependenciesNoneNode.js + npm packages
Page context cleanlinessNo framework artifacts at allRequires cleanup (Playwright bindings)
API styleCallback-based Chrome extension APIsPromise-based, high-level APIs
Page selectorsManual CDP queriesBuilt-in page.$(), page.click(), etc.
Multi-page workflowsManual target managementBuilt-in context and page management
Best forSimple interactions, lightweight single-page tasksComplex multi-page workflows, testing, data collection

Use bot script when:

  • You need the cleanest possible page context with zero framework artifacts.
  • Your task is a focused interaction (clicking a button, filling a form).
  • You want zero external dependencies.
  • You need the earliest possible intervention before page load.

Use Playwright or Puppeteer when:

  • You need high-level page interaction APIs (selectors, screenshots, PDF generation).
  • You are building complex multi-step workflows.
  • You need built-in waiting and retry mechanisms.
  • You are integrating with a test framework.

Troubleshooting / FAQ

ProblemSolution
”chrome.debugger API not available”Ensure you are using --bot-script, not loading the script another way.
Script does not executeUse an absolute path for --bot-script. Relative paths resolve from the binary’s directory.
chrome.runtime.lastError on attachAnother debugger may already be attached. Call chrome.debugger.detach() first, then retry.
Target not foundTargets appear asynchronously. Use setTimeout to poll chrome.debugger.getTargets() until the target appears.
No output visibleConsole output from bot scripts appears in the terminal where BotBrowser was launched.

Next Steps


Related documentation: Installation | Bot Script Examples  | Chrome Debugger API  | Chrome DevTools Protocol 


Legal Disclaimer & Terms of Use Responsible Use Guidelines . BotBrowser is for authorized fingerprint protection and privacy research only.