Automate X Posts with Playwright and Node.js
This repository ships a single script, tweet.js, that opens X (Twitter) in Playwright, logs in automatically (or with your help), and publishes a post. It can run headless for fully automated flows or visible for the first manual login. Auth state is persisted to twitter-auth.json so you do not have to sign in on every run.
Why it is useful
- Automates posting to X without using the public API or access tokens.
- Works with chromium (default) or webkit; can run headless or with a visible browser.
- Handles 2FA: reads a one-time code from env or generates TOTP from a secret.
- Saves and reuses session state to avoid repeated logins.
- Supports a manual-login mode to survive captchas or unusual prompts.
Quick start
1) Install dependencies and Playwright browsers:
git clone https://github.com/127/ixer
git clone https://github.com/127/ixer
npm install && npx playwright install
2) Configure environment:
cp .env.example .env
Fill .env with:
TWITTER_USERNAME=your_login
TWITTER_PASSWORD=your_password
TWITTER_2FA_SECRET=your_totp_secret (optional for 2FA)
or a single-use code: TWITTER_2FA_CODE=123456
Running the script
Automatic login with credentials from .env:
TWEET_TEXT="Post via Playwright" npm run tweet
First run with manual login (if you expect captchas or verification):
MANUAL_LOGIN=true HEADLESS=false npm run tweet
log in in the opened browser, then press Enter in the terminal
Subsequent headless run using the saved session:
HEADLESS=true TWEET_TEXT="New post" npm run tweet
Key environment variables
TWEET_TEXT — post text (default: "Привет, X!"). BROWSER — chromium (default) or webkit. HEADLESS — true|false; ignored when MANUAL_LOGIN=true (window stays visible). MANUAL_LOGIN — true|false; enables manual sign-in before posting. TWITTER_2FA_SECRET or TWITTER_2FA_CODE — allows automatic 2FA.
Session handling
After a successful login, Playwright stores cookies and tokens in twitter-auth.json. Keep this file alongside tweet.js to reuse the session. Delete it if you need to force a fresh login or rotate accounts.
Tips and safeguards
- Prefer MANUAL_LOGIN=true for the very first run to confirm the UI path and handle any security prompts.
- Do not commit .env or twitter-auth.json; they contain credentials and session data.
- If X changes its UI, rerun with HEADLESS=false to watch the flow and adjust selectors if needed.