Skip to content
ssrjkkPublic

About

Multi-bot orchestration platform for 8 platforms with BullMQ, script engine, webhooks and Prometheus. Self-hosted, MIT.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

129 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BotHive

CI node-22.19+ License: MIT

Multi-bot orchestration platform for Telegram, Twitch, YouTube, Twitter, Discord, Slack, Bluesky and crypto trading.

Site: https://ssrjkk.github.io/bothive/

by ssrjkk — run a fleet of social bots with shared infrastructure: one API, one queue layer, one dashboard, one script engine.

Live site: ssrjkk.github.io/bothive — screenshots, architecture and the dashboard preview.


Docs


Screenshots

The public site is the rack console below — captured from ssrjkk.github.io/bothive, 1440×900 and 390×844.

Desktop Mobile
BotHive landing page on desktop BotHive landing page on a 390px phone

The rest of the page, section by section:

Chaos & resilience Script sandbox
BotHive landing: circuit breaker, DLQ and chaos E2E unit BotHive landing: hardened Node vm script processor and Binance safety bay
Admin console Prometheus & API
BotHive landing: admin LCD console preview BotHive landing: Prometheus alert rules and API surface

The admin dashboard ships with light and dark themes.

Page Light Dark
Sign in BotHive sign in (light) BotHive sign in (dark)
Dashboard BotHive dashboard (light) BotHive dashboard (dark)
Bots Bots page (light) Bots page (dark)
Bot editor Bot editor (light) Bot editor (dark)
Accounts Accounts page (light) Accounts page (dark)
Users Users page (light) Users page (dark)
Scripts Scripts page (light) Scripts page (dark)
Queues Queues page with dead-letter queue (light) Queues page with dead-letter queue (dark)
Webhooks Webhooks page (light) Webhooks page (dark)
Events Events page with analytics (light) Events page with analytics (dark)
Logs Logs page (light) Logs page (dark)
Settings Settings page (light) Settings page (dark)

What it does

BotHive lets you register accounts and bots for eight platforms, start/stop them from one place, automate them with sandboxed scripts, react to events through webhooks, and observe everything on a single dashboard with Prometheus metrics.

  • 8 platform adapters — Telegram (long-polling or webhook), Twitch (IRC + Helix), YouTube (LiveChat), Twitter (v2 API), Discord, Slack, Bluesky, crypto/Binance (opt-in)
  • Crypto trading worker (opt-in, off by default) — a fifth adapter that runs Binance strategies against a generated EVM wallet. It is not started by docker compose up; see Crypto trading
  • Queue-driven control plane — every connect / disconnect / action is a BullMQ job, so control is reliable and restart-safe
  • Script engine — attach event-driven or interval scripts to any bot: 20 triggers (message, follow, subscribe, donation, comment, interval, raid, host, price, signal, trade, reaction, member_join, team_join, and the six Bluesky events) and 26 ctx/api actions — the full table with the payload of each trigger is in docs/scripts.md
  • Webhook sink — push events to your own endpoints with HMAC signatures and SSRF protection
  • RBAC — admin / viewer roles resolved from the database on every request (not from a stale JWT claim); admins can create/delete users and change roles in the dashboard
  • Secrets at rest — account tokens are encrypted with AES-256-GCM; encryption keys are validated at startup
  • Proxy pool — manage HTTP/SOCKS5 outbound proxies per-bot; the leader worker rotates healthy proxies with priority weighting, failure cooldown and health decay/boost, and POST /api/proxies/:id/test runs a reachability probe
  • Backup & restore — one-click JSON export/import with an atomic transaction and encrypted credential round-trips
  • Observability — /metrics for Prometheus, queue depth per platform, per-bot status and log stream, live worker health per platform, and a dark/light theme

Architecture

┌─────────────────────┐        ┌──────────────────────────────┐
│  Dashboard (nginx)  │        │  API (Fastify + Prisma)      │
│  React + antd       │──/api──▶  auth · bots · accounts ·    │
│                     │        │  scripts · webhooks · logs · │
└─────────────────────┘        │  stats · queues · backup     │
                               └───────┬──────────────┬───────┘
                                       │ enqueue      │ CRUD + config
                                       ▼              ▼
                              ┌───────────────┐  ┌──────────────┐
                              │  Redis        │  │ PostgreSQL   │
                              │  BullMQ queues│  │ (Prisma ORM) │
                              │  memory store │  └──────────────┘
                              └───────┬───────┘
                                      ▼ consume
        ┌───────────────┬─────────────┼───────────────┬───────────────┬───────────────┬───────────────┬───────────────┐
        ▼               ▼             ▼               ▼               ▼               ▼               ▼               ▼
  workers-telegram  workers-twitch  workers-youtube  workers-twitter  workers-discord  workers-slack  workers-bluesky  workers-crypto
  (one process per platform — a crash never takes down the others; crypto is opt-in)

Monorepo layout

Package Role
packages/core Domain logic: CQRS commands, validation, credential cipher, rate limiters, webhook signing, script config safety, VM-friendly event bus
packages/api Fastify HTTP API, JWT auth + RBAC, BullMQ enqueuing, Prisma schema/migrations, Prometheus metrics
packages/workers BullMQ consumers + platform adapters (grammy, tmi.js, twurple, googleapis, twitter-api-v2), script engine, webhook dispatcher, and an opt-in crypto trading worker
packages/dashboard React + antd admin panel (lazy-loaded pages, admin-gated routes)

Quick start (Docker)

# 1. prepare secrets (copy the example and fill in ENCRYPTION_KEY / PASSWORD_PEPPER / JWT_SECRET)
cp .env.example .env

# 2. start the whole stack — postgres, redis, api, per-platform workers, dashboard, prometheus, grafana
docker compose up -d --build

One worker process runs per platform (workers-telegram, workers-twitch, …). Scale any of them independently: docker compose up -d --scale workers-telegram=3

Local development

npm install
docker compose up -d postgres redis     # just the infra

npm run dev                              # api + workers + dashboard (workspaces)

Run checks:

npm run check      # lint + build + typecheck + tests — one command
npm run build      # TypeScript across all workspaces
npm run lint
npm run typecheck  # typechecks sources AND tests (build skips __tests__)
npm run coverage   # vitest with coverage thresholds (enforced in CI)
npm test           # vitest

Configuration

Key environment variables (see .env.example for the full list with comments):

Variable Required Purpose
DATABASE_URL yes PostgreSQL connection string
REDIS_URL yes Redis for BullMQ queues, bot memory and pub/sub
REDIS_PASSWORD Redis auth password (also usable in the URL)
REDIS_SENTINELS host:port[,host:port,...] — switch all Redis connections to Sentinel (HA/failover); REDIS_URL is then ignored
REDIS_SENTINEL_NAME Sentinel master name (default mymaster when sentinels are set)
REDIS_TLS true enables TLS for cloud-managed Redis
REDIS_DB Numeric logical Redis DB index for all connections
ENCRYPTION_KEY yes 32-byte hex key for AES-256-GCM credential encryption
JWT_SECRET yes Session signing secret
PASSWORD_PEPPER yes Pepper mixed into scrypt password hashes
API_PORT / API_HOST API listen address
LOG_RETENTION_DAYS Automatic log cleanup window (default 30)
EVENT_RETENTION_DAYS Automatic event-store cleanup window (default 30)
DLQ_RETENTION_DAYS Automatic dead-letter job cleanup window (default 30)
WORKER_CONCURRENCY BullMQ jobs processed concurrently per worker (default 10)
INTERVAL_POLL_MS Interval-script polling frequency (default 30000)
ALLOW_PRIVATE_WEBHOOK_URLS no Never enable in production (SSRF)
WEBHOOK_DNS_CHECK Resolve webhook hostnames and block private IPs

Rotating ENCRYPTION_KEY makes previously stored credentials undecryptable — keep it stable.


Script engine

Scripts are attached to a bot and fire on platform events or a timer. They run inside a hardened Node vm sandbox: fetch is SSRF-guarded on every redirect hop, the host realm cannot leak functions, return values are sanitized, and infinite loops are killed by a timeout. A per-script maxExecutionMs (100–600 000 ms; unset = no global limit) caps the whole action chain against a wall-clock deadline — the chain aborts between steps once it's exceeded.

Triggers: message · follow · subscribe · donation · comment · interval · raid · host · price · signal · trade · reaction · member_join · team_join · like · repost · mention · quote · reply · notification

Actions exposed to scripts: sendMessage, sendPhoto, deleteMessage, say, timeout, tweet, reply, react, post, like, repost, follow, addReaction, updateMessage, openModal, log, fetch, remember(key, value, ttl), recall(key), forget(key).

Crypto actions (only execute when a crypto worker is running — see Crypto trading): getPrice(symbol), getCandles(symbol, interval?, limit?), getBalance(asset), getWallet(), marketBuy(symbol, amountUsdt), marketSell(symbol, quantity). Order placement respects the bot's maxOrderValueUsdt and maxDailyOrderValueUsdt caps; see docs/scripts.md.

Safety checks run at save time too — the API rejects scripts with catastrophic regex filters, sandbox-escaping custom code, or disallowed webhook URLs (also enforced on backup import).


Webhooks

Bots can push events to your endpoints. Webhooks support per-bot or global (botId: null) targets, event filtering, HMAC signing (X-BotHive-Signature) and delivery telemetry (status, error, last delivered, delivery count). Private/loopback URLs are blocked by default to prevent SSRF, and an optional DNS check blocks hostnames that resolve to private ranges.

Crypto trading (opt-in)

A fifth worker adapter trades on Binance using per-bot strategies. It is off by default — docker compose up starts only the four social-platform workers. Enable it explicitly:

docker compose --profile crypto up -d workers-crypto

Bots on the crypto platform are created like any other, and the API generates a dedicated EVM wallet for each one (private key encrypted at rest; only the address is returned).

Safety defaults

  • tradeMode defaults to dry, so no live order is placed until a bot explicitly sets live.
  • maxOrderValueUsdt caps a single order (default 100 USDT; override the default with CRYPTO_MAX_ORDER_USDT).
  • maxDailyOrderValueUsdt caps rolling daily BUY spend — the default of 0 disables the cap entirely, so set it before going live.

Without the worker running, crypto bots and their scripts do nothing. Nothing surfaces an error, because no consumer is reading those jobs — the bot simply never acts. Trading alerts in prometheus/rules/bothive.yml only evaluate while the worker is up.

Resilience

Workers stay polite when platforms are unhappy, instead of hammering them:

  • Per-bot circuit breaker (packages/core/src/resilience/circuit-breaker.ts): after 5 consecutive connect failures the connection circuit opens and reconnects stop; one probe is let through per 60s cooldown, and a single successful connect closes it again. Reconcile/auto-start also skips bots whose circuit is open.
  • Adaptive backoff (packages/core/src/resilience/adaptive-backoff.ts): reconnect delays are exponential with jitter (no more fixed [5s, 15s, 30s, 60s, 120s] table) and scale with the bot's recent failure rate, capped at 5 minutes — so a fleet never reconnects in lock-step and a failing bot backs off hard.
  • Health score (packages/core/src/resilience/health-score.ts): every connect and action outcome feeds a 1-hour sliding window that yields a 0-100 score per bot. Workers publish these to Redis and the API's /metrics exposes them as bothive_bot_health_score{bot_id="...",status="..."}, plus bothive_bot_uptime_seconds, bothive_bot_actions_total{result="success|failure"}, bothive_bot_reconnect_attempts_total and bothive_bot_script_executions_total.
  • Per-bot rate limits: set rateLimitPerMinute in a bot's config to enforce a separate outbound budget for that bot (in addition to the global per-window limit). Limits are enforced via Redis, so they hold across a scaled fleet.
  • Rate limit budgeting (packages/core/src/rate-limit/budget.ts): per-action-type budgets give every endpoint its own window/cap, so a tweet burst can never starve sendMessage (and vice versa). Configure via RATE_LIMIT_BUDGETS (JSON env) or a bot's config.rateLimitBudgets, with default + per-action overrides.
  • Idempotency keys: every event carries an eventId derived from the platform's natural id (message id, update id, tweet id) when one exists. Workers claim it in a Redis dedup window before fan-out, so provider webhook redelivery or a worker failover replay can never double-fire scripts/webhooks/analytics.
  • Versioned contracts (packages/core/src/contracts/): every emitted event is stamped with its contract version (v), and webhook envelopes carry the envelope version. The event store persists it, replay re-runs under the original version, and an unsupported (newer) contract is rejected instead of mis-parsed when a platform API changes.
  • Dead-letter queues: jobs that exhaust their retry budget are moved into per-platform DLQs (<queue>-dlq, including webhook deliveries) with the payload and failure reason preserved. Admins can inspect and replay them via GET /api/queues/dead-letter / POST /api/queues/dead-letter/:platform/:id/replay / POST /api/queues/dead-letter/replay-all.
  • Event store & replay: every platform event is persisted (batched, idempotent by eventId) and browsable via GET /api/events. POST /api/events/:id/replay re-runs a stored event through the platform worker — scripts, webhooks and AI exactly as on the original emission — so a lost delivery or a script bug can be replayed after the fact.
  • Proxy pool (packages/core/src/proxy/proxy-pool.ts): the leader worker reloads proxies from the DB every reconcile cycle and injects a healthy one (proxy/proxyType) into each connect. Selection is weighted by priority with round-robin rotation, a failed proxy enters a 30s cooldown, and every connect outcome feeds its health score (bothive_proxy_health_score{proxy_id,type,priority}).

Database performance

  • Indexes (packages/api/prisma/migrations/): hot query paths are indexed — accounts by platform, bots by (platform, status) and by accountId, scripts by (botId, trigger) and enabled, webhooks by botId, logs by (botId, createdAt), (botId, level) and createdAt, event records by (botId, createdAt), (platform, type) and createdAt (unique on eventId).
  • Bounded pagination: list endpoints cap results via parsePage (100 per page, 1000 max for most endpoints, skip capped at 100 000; the log stream caps at 500 and the CSV export at 50 000) so deep paging can't grind the DB.
  • Filterable bot list: GET /api/bots accepts ?platform=, ?status= and ?q= (name substring, case-insensitive) — all index-friendly and validated.
  • Connection pooling: each service's Prisma pool is bounded via DATABASE_URL?...&connection_limit=10 (see docker-compose.yml and .env.example) so a scaled worker fleet cannot exhaust Postgres connections.

Observability & alerting

  • Prometheus metrics (GET /metrics): HTTP counters/histograms (rate, latency, response size per route), queue depths per platform/state (bothive_queue_jobs, bothive_worker_queue_depth), dead-letter backlog per queue (bothive_queue_dlq_jobs), event-store size and replay counter (bothive_event_store_total, bothive_event_replays_total), per-bot health/uptime/action/reconnect/script-execution metrics, worker liveness and concurrency (bothive_worker_up, bothive_worker_concurrency_current), proxy health scores, Prisma row counts and Node runtime gauges. Protected by METRICS_TOKEN, JWT, or METRICS_OPEN=true.
  • Readiness (GET /health/ready) probes both Postgres and Redis (503 when either is unavailable) — it is safe to use as a load-balancer/K8s readiness probe.
  • Alerting (prometheus/rules/bothive.yml): 22 rules — API unreachable/high error rate/slow p95, all-workers-down, workers down, queue backlog/high-wait/stuck failed jobs, dead-letter backlog, event-replay spikes, unhealthy bots/proxies, script failure spikes, worker heap growth/reconnect thrashing/sandbox worker leaks, crypto high error rate/no fills/volume spike, plus SLO burn-rate/latency pages.

Warning: Alertmanager notifies nobody by default. Out of the box every rule except severity="page" goes to a null receiver, and pages land in the bundled webhook-receiver, which just appends to data/webhook-capture.jsonl. The rules are evaluated and visible in the Prometheus/Alertmanager UI, but no human is paged until you point bothive-webhook at a real endpoint (PagerDuty/Slack/email) — see the header of alertmanager.yml. Check curl -s localhost:9093/api/v2/alerts after a deploy to confirm alerting works end to end.


Security model

  • Credentials are encrypted at rest (AES-256-GCM) and never returned by the API — including webhook HMAC secrets (enc:-prefixed, legacy plaintext keeps working on read) and crypto wallet private keys (bot responses only ever expose the wallet address; a config save that omits the key preserves the stored one instead of destroying it).
  • Sessions use httpOnly cookies + short-lived JWTs; roles are re-read from the database per request (fail-closed: unknown role ⇒ viewer). WebSocket log streams re-check the user too.
  • Login is rate-limited; passwords are hashed with scrypt plus a pepper.
  • RBAC: only admin can manage scripts, queues, webhooks, settings, backups and bulk operations; viewer gets read-only access.
  • The API and dashboard emit security headers on every response, including HSTS; auth responses that carry the token in the body set Cache-Control: no-store.
  • Webhook delivery and script fetch are SSRF-hardened; bulk operation errors are masked instead of echoing raw exceptions.

API surface (abridged)

GET   /health, /health/ready, /metrics · GET /api/health/workers · /api/docs (Swagger UI) · /ws/logs (live log stream)
POST  /api/auth/register, /api/auth/login, /api/auth/logout
GET   /api/auth/me · PATCH /api/auth/password
GET/POST /api/auth/users · PATCH /api/auth/users/:id/role · DELETE /api/auth/users/:id
GET   /api/bots · POST /api/bots · GET/PATCH/DELETE /api/bots/:id
POST  /api/bots/:id/start · /stop · /restart · /action · GET/DELETE /api/bots/:id/memory[/:key]
GET   /api/accounts · POST /api/accounts · GET/PATCH/DELETE /api/accounts/:id
GET   /api/scripts/patterns · POST /api/scripts/generate · CRUD /api/scripts
POST  /api/scripts/:id/test · /clone
GET   /api/webhooks · CRUD /api/webhooks · POST /api/webhooks/:id/test
GET   /api/queues · /api/queues/failed · /api/queues/dead-letter
POST  /api/queues/dead-letter/:platform/:id/replay · /api/queues/dead-letter/replay-all
GET   /api/events · /api/events/:id · POST /api/events/:id/replay · DELETE /api/events/:id
GET   /api/logs · /api/logs/export · /api/stats
GET/POST /api/proxies · GET/PATCH/DELETE /api/proxies/:id · POST /api/proxies/:id/test
GET   /api/backup/export · POST /api/backup/import · POST /api/bulk/bots · /api/bulk/scripts

Testing

Vitest across all workspaces — 700+ tests covering domain rules, RBAC, sandbox isolation, webhook SSRF guards, backup round-trips, leader election, circuit breakers, rate limiting, proxy rotation/health, Redis connection options, API behaviour, and unit-level worker chaos (crash/requeue with a mocked queue). npm test is the source of truth for the exact count; it is not mirrored here because it changes with every PR.

Coverage thresholds (statements/lines 50%, branches/functions 45%) are enforced in CI — see vitest.config.ts. They are a floor rather than a target.

.env.example is kept in step with the code by packages/core/src/__tests__/env-docs.test.ts, which fails if the source reads a process.env.* variable the example file never mentions.

npm test

Beyond unit tests, .github/workflows/chaos.yml runs compose-level chaos / E2E against the real Docker stack (chaos/): Postgres and Redis outages, worker hang detection (SIGSTOP) and worker crash recovery (SIGKILL), asserting /health/ready flips to 503 and the bothive_worker_up metric reflects the fault, then recovering to 200 / 1.


CI/CD & releases

  • CI (.github/workflows/ci.yml) runs on every push/PR: ESLint, full build, typecheck of sources and tests, the whole test suite with coverage on Node 22 and 26, docker compose validation, and a Docker build of every image target (api / workers / dashboard). On main the images are pushed to Docker Hub as :latest and :<sha>; PRs build them locally so a broken Dockerfile is caught before merge.

  • Chaos / E2E (.github/workflows/chaos.yml) starts the real compose stack and faults it — Postgres/Redis outages, worker hang and crash — then checks recovery via /health/ready and worker metrics.

  • Releases (.github/workflows/release.yml) — push a semver tag and the images are published as :latest, :<tag> and :<sha>, plus a draft GitHub release with a changelog:

    git tag v1.2.3 && git push origin v1.2.3
  • Dependabot (.github/dependabot.yml) keeps npm, Docker and GitHub Actions dependencies up to date weekly.

Secrets required for image publishing: DOCKERHUB_USERNAME, DOCKERHUB_TOKEN (configured in the repo settings).

Known limitations

These are deliberate open items rather than bugs — listed so nobody assumes the capability is live.

  • Crypto trading is opt-in and off by default. The worker exists and is tested, but docker compose up does not start it (see Crypto trading). Nothing surfaces an error for a crypto bot whose worker is stopped — the jobs are simply never consumed.
  • Encryption key rotation with versioning. ENCRYPTION_KEYS supports multiple key versions (e.g., v1:old-key,v2:new-key), allowing in-place rotation via POST /api/backup/rotate-encryption. Legacy ENCRYPTION_KEY (single key) is still supported for backward compatibility. See docs/security.md for the rotation procedure.

Author

Sitnikov Sergey Alekseevich Full-stack Engineer · Saint Petersburg
GitHub · Telegram · [email protected]


License

MIT — see LICENSE. Contributions are welcome: read CONTRIBUTING and the Code of Conduct first.

Installation

git clone https://github.com/ssrjkk/bothive.git
cd bothive
npm install

Usage

npm start

SSRJKK — GitHub · Telegram · Projects hub · Bot catalogue

About

Multi-bot orchestration platform for 8 platforms with BullMQ, script engine, webhooks and Prometheus. Self-hosted, MIT.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages