Add README and MIT license
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -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.
|
||||||
204
README.md
Normal file
204
README.md
Normal file
@@ -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 <prompt-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
Schedule posts for the day (picks random times, waits, then posts):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node scheduler.js <prompt-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 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. `<key>` 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 `<placeholder>` 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 <link> on its own line.",
|
||||||
|
"links": {
|
||||||
|
"link": "https://example.com"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Multiple placeholders work too:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"prompt": "Mention <site> and end with <cta>.",
|
||||||
|
"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
|
||||||
Reference in New Issue
Block a user