Install
openclaw skills install x-cdpAutomate X (Twitter) via Chromium CDP: post tweets, reply, quote-retweet, publish articles. Uses real browser sessions with existing login, no API keys neede...
openclaw skills install x-cdpRun the setup wizard. It checks everything and auto-fixes what it can:
node scripts/setup.js [--port 18802] [--profile ~/chromium-profiles/x-cdp]
The wizard does 4 things:
Install Chromium (recommended over Chrome for version stability):
# macOS
brew install --cask chromium
# Linux
sudo apt install chromium-browser
Install puppeteer-core:
cd /tmp && npm init -y && npm install puppeteer-core
Launch Chromium with CDP:
chromium --remote-debugging-port=18802 --user-data-dir=~/chromium-profiles/x-cdp --no-first-run
Log in to X: Open x.com in the Chromium window and log in once. The session persists in the profile directory.
Chrome auto-updates silently. One update can change DOM selectors and break all automation overnight. Chromium lets you pin a known-good version. That said, Chrome works fine too if you don't mind occasional breakage.
All scripts connect to a running Chromium instance via CDP (Chrome DevTools Protocol). This is not API-based. It drives the real browser UI, identical to a human clicking.
Each X account gets its own Chromium instance with a separate port and profile:
chromium-profiles/main: @your_main_accountchromium-profiles/second: @your_second_accountchromium-profiles/third: @your_third_accountLaunch multiple instances for multi-account use. All scripts accept --port to target a specific account.
NODE_PATH=/tmp/node_modules node scripts/post-tweet.js "Hello world" [--image /path/to/img.png] [--port 18802] [--dry-run]
NODE_PATH=/tmp/node_modules node scripts/reply-tweet.js <tweet_url> "Nice post!" [--image /path/to/img.png] [--port 18802] [--dry-run]
NODE_PATH=/tmp/node_modules node scripts/quote-tweet.js <tweet_url> "My thoughts" [--port 18802] [--dry-run]
NODE_PATH=/tmp/node_modules node scripts/post-article.js --title "Title" --body "Body text" [--body-file /path/to/content.md] [--cover /path/to/cover.jpg] [--port 18800] [--dry-run]
All scripts support --dry-run to fill content without sending. A screenshot is saved to /tmp/.
When the user asks to interact with X:
Before running any script, verify the environment:
curl -s http://localhost:<port>/json/versionnode scripts/setup.js --port <port> to launch and configureexecIf a script fails with "not found" errors, X may have changed its DOM. Check and update:
references/selectors.md for the latest selectorsscripts/lib/cdp-utils.js SELECTORS object