diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5958c71 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Matt Jackson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..cf7215b --- /dev/null +++ b/README.md @@ -0,0 +1,204 @@ +# xBot + +AI-powered Twitter/X bot that generates and posts tweets on configurable schedules using stealth browser automation. + +## How it works + +1. **Scheduler** runs via cron, picks random times within a configured window +2. **Bot** logs into X via [Kernel.sh](https://onkernel.com) stealth browsers (residential proxies + CAPTCHA solving) +3. **Claude** (Anthropic API) generates tweets based on your prompts +4. **Links** are inserted after generation — URLs never touch the AI +5. **History** is tracked per-prompt and fed back to avoid repetition + +## Setup + +### Prerequisites + +- Node.js 18+ +- [Kernel.sh](https://onkernel.com) API key +- [Anthropic](https://console.anthropic.com) API key +- An X/Twitter account + +### Install + +```bash +git clone https://github.com/MattJackson/xBot.git +cd xBot +npm install +``` + +### Configure + +1. Copy the example files: + +```bash +cp .env.example .env +cp prompts.example.json prompts.json +``` + +2. Edit `.env` with your credentials: + +``` +MYACCOUNT_USER=your_twitter_handle +MYACCOUNT_PW=your_password +MYACCOUNT_EMAIL=your_email@example.com +MYACCOUNT_PHONE=1234567890 + +KERNEL=sk_your_kernel_key +ANTHROPIC=sk-ant-your_anthropic_key +``` + +Credentials are prefixed by account name (uppercase). To add another account, add another set: + +``` +ANOTHERACCOUNT_USER=... +ANOTHERACCOUNT_PW=... +ANOTHERACCOUNT_EMAIL=... +ANOTHERACCOUNT_PHONE=... +``` + +3. Edit `prompts.json` with your prompts (see [Prompt Configuration](#prompt-configuration) below). + +### Run + +Post a single tweet: + +```bash +node bot.js +``` + +Schedule posts for the day (picks random times, waits, then posts): + +```bash +node scheduler.js +``` + +### Cron + +Add a cron job for each prompt. The scheduler handles random timing within the window — cron just needs to trigger it once daily before the window opens. + +```bash +crontab -e +``` + +``` +# Runs daily — scheduler picks random time(s) between 8am-8pm PST +0 16 * * * cd /path/to/xBot && /usr/bin/node scheduler.js my-prompt >> bot.log 2>&1 +``` + +The cron time should be in UTC. `0 16 * * *` = midnight PST (8 hours ahead), ensuring the scheduler starts before the 8am PST window. + +## Prompt Configuration + +`prompts.json` is an array of prompt objects: + +```json +[ + { + "name": "my-prompt", + "account": "myaccount", + "prompt": "Your prompt text here. Generate 1 tweet. Just the tweet.", + "links": { + "link": "https://example.com" + }, + "schedule": { + "type": "daily", + "window": [8, 20], + "postsPerDay": [1, 3], + "minGapHours": 4 + } + } +] +``` + +### Fields + +| Field | Required | Description | +|-------|----------|-------------| +| `name` | Yes | Unique identifier. Used as CLI argument and for history files. | +| `account` | Yes | Maps to env var prefix. `"myaccount"` looks up `MYACCOUNT_USER`, etc. | +| `prompt` | Yes | The prompt sent to Claude. Include generation instructions here. | +| `links` | No | Key-value map. `` placeholders in the generated tweet are replaced with the URL. URLs never reach the AI. | +| `schedule` | Yes | Scheduling configuration (see below). | + +### Schedule types + +**Daily** — posts every day, 1 or more times: + +```json +{ + "type": "daily", + "window": [8, 20], + "postsPerDay": [1, 3], + "minGapHours": 4 +} +``` + +- `window`: `[startHour, endHour]` in PST. Posts only happen within this range. +- `postsPerDay`: `[min, max]`. A random count is picked each day. Defaults to `[1, 1]`. +- `minGapHours`: Minimum hours between posts on the same day. Defaults to `4`. + +**Random** — posts on random days with a minimum gap: + +```json +{ + "type": "random", + "window": [8, 20], + "minDays": 2 +} +``` + +- `minDays`: Minimum days between posts. After the gap is met, there's a 50% chance each day — so actual spacing varies naturally (2, 3, 4+ days). + +### Link placeholders + +Use `` in your prompt instructions. The AI generates the tweet with the placeholder, then the bot replaces it with the real URL: + +```json +{ + "prompt": "Write a tweet. End with on its own line.", + "links": { + "link": "https://example.com" + } +} +``` + +Multiple placeholders work too: + +```json +{ + "prompt": "Mention and end with .", + "links": { + "site": "https://mysite.com", + "cta": "https://mysite.com/signup" + } +} +``` + +## Multi-account + +Each prompt specifies which account to post from. You can run multiple accounts from the same instance: + +```json +[ + { "name": "account1-daily", "account": "firstaccount", "prompt": "...", "schedule": { ... } }, + { "name": "account2-promo", "account": "secondaccount", "prompt": "...", "schedule": { ... } } +] +``` + +Just add the corresponding credentials to `.env` for each account. + +## Files + +| File | Tracked | Description | +|------|---------|-------------| +| `bot.js` | Yes | Main bot — login, generate, post | +| `scheduler.js` | Yes | Picks random times, runs bot.js | +| `prompts.json` | No | Your prompt config (create from example) | +| `.env` | No | Your credentials | +| `history-*.json` | No | Per-prompt tweet history | +| `bot.log` | No | Cron output log | + +## License + +MIT