x-integration
Flagged{"isSafe":false,"isSuspicious":true,"riskLevel":"medium","findings":[{"category":"data_exfiltration","severity":"medium","description":"Remote copying of Playwright profiles to a remote server via rsync could leak session data (cookies/tokens) if the destination is not trusted or properly secured.","evidence":"rsync -az data/playwright-profiles/x/ server:path/to/pynchy/data/playwright-profiles/x/"}],"summary":"The skill content describes browser automation with persistent Playwright sessions and remote profile synchronization. Potential safety issues include risk of data exfiltration through rsync of session profiles to a remote server, and exposure of a VNC-based remote desktop URL for login (which could allow remote access if not properly secured). Mitigations are recommended for securing remote access and limiting exposure of sensitive profile data."}
npx machina-cli add skill crypdick/pynchy/x-integration --openclawX (Twitter) Integration
Automates X/Twitter actions via Playwright browser automation with a persistent Chromium profile.
System requirements
Requires a system Chrome/Chromium binary — CHROME_PATH must be set in .env (e.g. CHROME_PATH=/usr/bin/google-chrome-stable). Playwright's bundled Chromium is not used because X fingerprints it as a bot.
All X tools run in headed mode (not headless) because X actively detects and blocks headless browsers. On headless servers, this requires Xvfb (apt install xvfb).
For interactive login via setup_x_session, you also need VNC (apt install x11vnc novnc).
How it works
Playwright drives the system Chrome binary (via CHROME_PATH) using persistent browser contexts. After one manual login (human handles CAPTCHA / 2FA), subsequent actions run automatically using the saved session. All tools use headed mode with anti-detection flags to avoid X's bot fingerprinting.
First-time setup (requires human)
Before any X actions can be performed, a human must log in once:
setup_x_session()
This opens a visible Chromium window at the X login page. The human completes the login flow. The session is saved for future automated use.
On a headless server (no X display), the tool automatically starts Xvfb + noVNC on port 6080. Before calling setup_x_session, tell the human to open http://<server>:6080/vnc.html?autoconnect=true in their browser.
Hardware security keys (YubiKey, FIDO2): noVNC cannot forward WebAuthn challenges — the key must be physically connected to the machine running the browser. If X login requires a hardware key, run setup_x_session on a local machine with the key attached, then rsync the profile to the server:
rsync -az data/playwright-profiles/x/ server:path/to/pynchy/data/playwright-profiles/x/
Tools
setup_x_session(timeout_seconds=120)
Launch a headed browser for manual X login. Saves the session to a persistent profile for future use.
timeout_seconds— how long to wait for login completion (default: 120s)
x_post(content)
Post a tweet. Content must be 1–280 characters.
x_like(tweet_url)
Like a tweet. Accepts a full URL (https://x.com/user/status/123) or a bare tweet ID.
x_reply(tweet_url, content)
Reply to a tweet. Content must be 1–280 characters.
x_retweet(tweet_url)
Retweet without comment.
x_quote(tweet_url, comment)
Quote tweet with a comment. Comment must be 1–280 characters.
Error handling
- "X login expired" — The saved browser session has expired. A human needs to run
setup_x_sessionagain. - "Tweet not found" — The tweet URL is invalid or the tweet was deleted.
- "Post/Submit button disabled" — Content may be empty or exceed the character limit.
- "Login not completed within Xs" — The human didn't finish the manual login in time. Try again with a longer
timeout_seconds. - "CHROME_PATH is required" — Set
CHROME_PATHin.envto the system Chrome/Chromium binary path. - "No display available and Xvfb not installed" — X tools need headed mode. Install Xvfb on the server.
- Selector errors — X may have changed its UI. Check if the data-testid selectors in the plugin still match X's React components.
Source
git clone https://github.com/crypdick/pynchy/blob/main/src/pynchy/agent/skills/x-integration/SKILL.mdView on GitHub Overview
X integration automates common Twitter actions—posting tweets, liking, replying, retweeting, and quoting—through a persistent Playwright-driven Chrome session. Actions run in headed mode to evade bot detection, with an initial manual login that saves a reusable session.
How This Skill Works
Playwright drives the system Chrome (via CHROME_PATH) using a persistent browser context. After a one-time manual login (setup_x_session) completes, subsequent actions run automatically using the saved session, with headed mode and anti-detection flags to minimize bot fingerprinting. If running on a headless server, Xvfb/noVNC support is provided to keep the browser visible for interaction.
When to Use It
- You want to post a new tweet automatically from your app or script.
- You need to like a specific tweet by URL or ID.
- You want to reply to a tweet with a custom message.
- You want to retweet without adding a comment.
- You want to quote a tweet with your own remark.
Quick Start
- Step 1: setup_x_session(timeout_seconds=120) to login visually and save the session.
- Step 2: Use x_post(), x_like(), x_reply(), x_retweet(), or x_quote() with proper parameters to perform actions.
- Step 3: If running on a headless server, ensure Xvfb/noVNC is installed and handle potential login expiry by re-running setup_x_session.
Best Practices
- Set CHROME_PATH in your environment to your system Chrome/Chromium before first use.
- Run setup_x_session(timeout_seconds=120) in a headed browser to perform the initial login and save the session.
- Use full tweet URLs (or tweet IDs) when calling x_like, x_reply, x_retweet, or x_quote to ensure accuracy.
- Keep content within 1–280 characters for posts, replies, and quotes to avoid 'Post/Submit button disabled' errors.
- Monitor for common errors like 'X login expired' or 'Tweet not found' and re-run setup_x_session if needed.
Example Use Cases
- x_post("Automating with X-integration—hello world via Playwright!")
- x_like("https://x.com/user/status/1234567890123456789")
- x_reply("https://x.com/user/status/1234567890123456789", "Nice analysis on this topic!")
- x_retweet("https://x.com/user/status/1234567890123456789")
- x_quote("https://x.com/user/status/1234567890123456789", "Thoughts worth sharing: this aligns with our approach.")