Use a real browser session's cookie header to verify login and perform browser actions on X/Twitter via headless Playwright. Currently supports posting tweets.
Execute browser actions on X using your real browser login state, without the official X API.
Users only need to provide a single cookie header string.
After installing into OpenClaw, the skill lives at:
~/.openclaw/workspace/skills/x-twitter-browser/
Commands below assume you run from the skill root directory:
cd ~/.openclaw/workspace/skills/x-twitter-browser
cookie header stringThis skill has two layers:
Persists the user-provided cookie locally (outside the skill directory so it survives skill updates):
scripts/save_cookie_header.py~/.x-twitter-browser/config.jsonPerforms actions using the verified browser session. Currently implemented:
scripts/post_tweet.pyscripts/reply_post.pyscripts/repost_post.pyNote: First-time setup can take several minutes (Chromium is ~150MB). Each step may take 1–5 minutes depending on your network. If a package or browser is already installed, that step will finish quickly.
OpenClaw: When running setup.sh via OpenClaw, it executes in the background and the user cannot see the echo output. Forward each progress message (e.g. "Installing playwright...", "✓ Playwright package installed.", "Installing Chromium...") to the user as it appears so they know the setup is progressing.
First-time setup (recommended):
./scripts/setup.sh
Paste the full browser Cookie request header, e.g.:
guest_id=...; auth_token=...; ct0=...; twid=...; ...
Important cookies:
auth_tokenct0twidkdtatt_twitter_sessCookie and other config are stored in ~/.x-twitter-browser/config.json (outside the skill directory, so they survive ClawHub skill updates). Do not commit or share this file.
{
"cookie_header": "guest_id=...; auth_token=...; ..."
}
Future parameters may be added to the same config file.
If the user pastes a cookie header, save it to ~/.x-twitter-browser/config.json:
python3 scripts/save_cookie_header.py \
--cookie-header 'guest_id=...; auth_token=...; ct0=...; twid=...'
Or save the cookie to a file first, then import:
cat > /tmp/cookie.txt <<'EOF'
guest_id=...; auth_token=...; ct0=...; twid=...; ...
EOF
python3 scripts/save_cookie_header.py \
--cookie-file /tmp/cookie.txt
Before any browser action, run:
python3 scripts/post_tweet.py \
--verify-only
Success looks like:
Session looks valid: https://x.com/home
If verification fails, the cookie may be expired. Ask the user to provide a fresh cookie.
After verification succeeds:
python3 scripts/post_tweet.py \
--text "hello"
python3 scripts/reply_post.py \
--tweet "https://x.com/username/status/123456789" \
--text "My reply"
Plain repost (no comment):
python3 scripts/repost_post.py \
--tweet "https://x.com/username/status/123456789"
Quote tweet (repost with your comment):
python3 scripts/repost_post.py \
--tweet "https://x.com/username/status/123456789" \
--text "My comment"
For both reply and repost, --tweet accepts a full URL or just the tweet ID.
--verify-only success means the session is likely usable--verify-only before any write operation~/.x-twitter-browser/config.jsonscripts/*.py directlyImported session is not authenticatedAsk the user to provide a fresh, complete cookie header.
ZIP package — ready to use