Part of the Sentinel project.
Add a user ID. From that moment, the selfbot records everything it can observe:
- ๐ข Online / offline presence โ real-time, event-driven, including which device (desktop / mobile / web)
- ๐ฎ Games & activities โ what they play, for how long, with rich metadata
- ๐ต Spotify listening โ tracks, albums, artists, timestamps
- ๐ฅ๏ธ Custom status changes โ every status text and emoji set or cleared
- ๐๏ธ Voice channel movements โ joins, leaves, moves, mute/deafen state, co-participants
- ๐ฌ Messages โ sent, edited, deleted (content preserved before deletion)
- ๐ป Ghost typing โ started typing but never sent
- ๐ผ๏ธ Profile changes โ username, display name, avatar, bio, connected accounts (Twitter, Steam, etc.)
- ๐ Platform switches โ detects when a target moves from desktop to mobile mid-session
- ๐ฅ๏ธ Self-commands โ manage tracking from any Discord channel with instant trace deletion
AI-powered intelligence (optional):
- ๐ท๏ธ Message categorization โ every message auto-tagged (gaming, music, venting, humor, etc.)
- ๐ AI social graph โ relationship classification with confidence scores (close friend, romantic interest, group buddyโฆ)
- ๐ฐ Daily intelligence briefs โ morning summary with anomalies and behavioral changes
- ๐ Historical message backfill โ fills in the past automatically when you start tracking someone
- ๐ Smarter alerts โ digest mode, fatigue prevention, instant Discord webhooks
All data lives in a local SQLite database. Optional Supabase sync gives a cloud mirror for backup or cross-device access.
Sentinel uses Discord's op 14 (GUILD_SUBSCRIBE) gateway opcode with a members array to subscribe to real-time presence events for specific users. When a tracked target changes status โ online, idle, DND, or offline โ Discord pushes the change immediately as a PRESENCE_UPDATE event. No polling delay.
Key properties:
- Offline detection is instant โ no waiting for a poll cycle
- Subscriptions refresh automatically โ re-sent on every reconnect, session resume, and every 4 minutes in case of silent expiry
- New targets subscribe within 5 seconds of being added via the API or self-command
- Platform switches tracked independently โ moving from desktop to mobile without a status change is its own event
Requires at least one mutual Discord server between the selfbot account and the target.
โ Technical deep-dive: docs/presence-tracking.md
Type commands in any Discord channel (including your own private servers). The triggering message is deleted immediately before anyone else sees it. Feedback appears as a temporary message that self-deletes after a few seconds โ no permanent trace in the channel.
| Command | Description |
|---|---|
$add <@user> |
Add a tracking target |
$remove <@user> |
Remove a target (deletes all history) |
$pause <@user> |
Suspend tracking without deleting history |
$resume <@user> |
Re-activate a paused target |
$label <@user> <text> |
Set a display label for a target |
$note <@user> <text> |
Append a timestamped note to a target |
$status <@user> |
Current presence, platform & activities |
$seen <@user> |
When the target was last online |
$uptime <@user> |
Today's total active time with progress bar |
$streak <@user> |
How long in current status uninterrupted |
$history <@user> [n] |
Last N presence transitions with timestamps |
$pattern <@user> |
30-day hourly activity heatmap (โโโโโ
โโโ) |
$list |
All active targets with live status |
$ping |
REST & gateway heartbeat latency check |
$stats |
System stats (targets, events, DB size, uptime) |
$reload |
Reload alert rules & runtime config live |
$help |
Full command reference |
All commands accept <@mention> or a raw Discord user ID snowflake.
โ Full reference: docs/commands.md
Uses an LLM to examine the texture of interactions โ sentiment, reply speed, topic clustering, initiation balance, voice co-presence times โ and classifies relationships:
close friend, romantic interest, group friend, conflict relationship, server contact, and more.
Each classification includes a confidence score and a relationship timeline showing how the connection has evolved over weeks.
Messages are automatically tagged with categories like gaming, music, venting, humor, planning, questions, etc. Works by batching recent messages through a lightweight LLM call, configurable batch size.
Every morning at your configured time, Sentinel generates a plain-text summary per active target:
- Presence duration and devices used
- Games and music played
- Message counts (including deleted / ghost typing)
- Voice channel activity
- Profile changes
- Anomaly flags
When you add a target, Sentinel walks backwards through every shared channel to fill in past messages. Configurable depth (max days, max messages per channel). The API exposes live progress per channel.
- 14 alert types โ comes online, goes offline, starts activity, joins voice, sends message, ghost types, profile change, unusual hour, new game, keyword mention, and more
- Digest mode โ batch alerts into a single notification every N minutes
- Fatigue detection โ auto-suppress rules that fire too often (configurable threshold)
- Composite conditions โ combine multiple conditions in one rule
- Discord webhooks โ normal alerts and critical system errors routed to separate channels
Sentinel logging multiple targets' messages across servers:
Sentinel running AI Social Relation/Graph Analysis:
View more: github.com/Privex-chat/sentinel
git clone https://github.com/Privex-chat/sentinel-selfbot.git
cd sentinel-selfbot
npm install
cp .env.example .env
# Edit .env โ set DISCORD_TOKEN, API_AUTH_TOKEN, and optionally AI provider
npm run build && npm startThen connect the plugin or web panel to http://localhost:48923.
Full setup guide: docs/selfbot.md
Click to expand the full .env reference
# โโ Core (requires restart to change) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
DISCORD_TOKEN=your_account_token_here
API_PORT=48923
API_AUTH_TOKEN=generate_a_random_string_here
DB_PATH=./data/sentinel.db
LOG_LEVEL=info
# RANDOM_JITTER=true โ adds ยฑ20% jitter to polling intervals so requests
# don't fire on a predictable schedule. Also randomises the browser/OS
# fingerprint sent in the Discord gateway IDENTIFY and REST headers.
# Recommended for Railway / cloud deployments.
RANDOM_JITTER=false
# โโ Database mode (requires restart) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# local โ SQLite only. Default.
# local+cloud โ SQLite live DB + async Supabase mirror.
# cloud โ Hydrates SQLite from Supabase on boot. For Railway / Fly.io.
DB_MODE=local
SUPABASE_URL=https://your-project-ref.supabase.co
SUPABASE_SERVICE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
SUPABASE_SYNC_INTERVAL_MS=300000 # cloud recommended: 30000
# โโ All settings below are hot-reloadable via PATCH /api/config โโโโโโโโโโโโโโโ
PROFILE_POLL_INTERVAL_MS=300000
STATUS_POLL_INTERVAL_MS=120000
DAILY_SUMMARY_INTERVAL_MS=3600000
# โโ AI Provider โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# Providers: none (default) | gemini | ollama | openai | anthropic
# Gemini recommended โ free tier: 15 RPM / 1M tokens per day
# Get a free key: https://aistudio.google.com
AI_PROVIDER=none
AI_MODEL=gemini-2.5-flash
AI_API_KEY=
AI_BASE_URL=http://localhost:11434/v1
AI_ANALYSIS_INTERVAL_MS=86400000
AI_CATEGORIZATION_BATCH_SIZE=50
# โโ Backfill โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
BACKFILL_ENABLED=true
BACKFILL_MAX_DAYS=90
BACKFILL_MAX_MESSAGES_PER_CHANNEL=5000
# โโ Alerts โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
ALERT_WEBHOOK_URL=
CRITICAL_WEBHOOK_URL= # system errors only (token invalidation, auth failures)
ALERT_DIGEST_MODE=false
ALERT_DIGEST_INTERVAL_MS=900000
ALERT_FATIGUE_THRESHOLD=20
# โโ Daily Briefs โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
BRIEF_GENERATION_TIME=07:00 # UTC โ requires AI_PROVIDER != noneOPSEC tip: Set RANDOM_JITTER=true to make your polling patterns and gateway fingerprint less predictable.
| Platform | Notes |
|---|---|
| Local / VPS | npm start or PM2 (pm2 start npm -- start) |
| Docker | Dockerfile included |
| Railway | One-click deploy โ |
| Fly.io | fly.toml included. Use DB_MODE=cloud with Supabase |
For cloud deployments: set DB_MODE=cloud, SUPABASE_SYNC_INTERVAL_MS=30000, and RANDOM_JITTER=true.
| Guide | Description |
|---|---|
| docs/selfbot.md | Full setup and configuration guide |
| docs/commands.md | Self-command system reference |
| docs/api.md | REST & SSE API reference |
| docs/presence-tracking.md | How real-time presence tracking works |
- sentinel-plugin โ Vencord plugin UI
- sentinel-web โ Browser dashboard
- sentinel-proxy โ Windows proxy for remote selfbot
