← Back to Blog

How I Reverse-Engineered Discord to Control It With AI

📅 May 29, 2026 🏷 Hacky Reverse Engineering AI Agents ⏳ 8 min read
Limited 10% OFF Z.AI Coding Plan — GLM 5.1 is a powerhouse for code generation. Get the discount through Codex Launcher.
Free Xiaomi MiMo 2.5 Pro — Free API Access — Limited-time, no credit card. This is the model that built this project. Get it →

Discord has a "proper" way to do things. Create a bot application in the Developer Portal. Configure OAuth2. Set up intents. Invite the bot. Manage the token. It's clean, documented, and safe.

I didn't do any of that.

Instead, I launched Discord with a Chromium debug flag, connected to its renderer process via WebSocket, injected JavaScript to extract my user token from the live session, and used that token to hit the Discord REST API directly. Plus DOM manipulation for UI control and xdotool as a nuclear fallback.

The result: discord-thread-manager — an AI agent skill that manages Discord threads with zero setup.


The Setup Problem

I needed to scan for stale threads on my Discord server and bulk lock/archive them. The standard path:

  1. Go to Discord Developer Portal
  2. Create a new application
  3. Create a bot user, enable intents
  4. Generate an invite link with MANAGE_THREADS permission
  5. Invite the bot to my server
  6. Copy the bot token, store it in .env
  7. Write scripts using Authorization: Bot <token>

That's 30+ minutes of clicking through a web UI for something I wanted to do right now on my personal server.

I already have a Discord session running on my desktop. I'm already logged in. The token is right there in the renderer process. Why can't I just... grab it?

So I did.

How It Works

Discord Desktop (--remote-debugging-port=9222) │ ├── CDP WebSocket (Chrome DevTools Protocol) │ ├── JS Injection → Token Extraction (3 methods) │ ├── DOM Manipulation (click, type, read) │ │ │ └── Extracted User Token │ │ │ ▼ │ Discord REST API (api/v10) │ ├── Scan threads (active + archived) │ ├── Lock & archive stale threads │ └── Send messages │ └── xdotool fallback (when API fails) ├── Send keystrokes └── Click coordinates

Step 1: Launch with CDP

Discord Desktop is an Electron app — Chromium under the hood. Chromium supports --remote-debugging-port, which exposes the Chrome DevTools Protocol on localhost.

/usr/share/discord/Discord --remote-debugging-port=9222

Now http://127.0.0.1:9222/json returns debuggable targets, each with a WebSocket URL.

Step 2: Extract the Token

Connected via WebSocket, you can execute arbitrary JavaScript in Discord's renderer. Three extraction methods, tried in order:

Method 1 — localStorage (fastest):

localStorage.getItem('token')

Method 2 — Script tag parsing:

document.querySelector('script').textContent
  .match(/"token"\s*:\s*"([^"]{30,})"/)

Method 3 — Webpack module cache:

// Searches webpackChunkdiscord_app for getToken() exports

Step 3: Use the Token

With the extracted user token, the controller becomes a standard Discord REST API client. Same endpoints, same pagination, same rate limits — just using Authorization: <token> instead of Authorization: Bot <token>.

The Proper Way vs. The Hacky Way

Proper (Bot API)Hacky (CDP)
SetupCreate bot, OAuth, inviteJust launch Discord
TokenBot token from dev portalExtracted from live session
Auth headerBot <token><token>
UI ControlAPI onlyAPI + CDP DOM + xdotool
TOS RiskNoneUser tokens = gray area
Setup time~30 minutes~0 minutes

What It Actually Does

The project is an AI agent skill — a self-contained set of instructions and scripts that an AI coding tool can follow. Three-phase workflow: scan → report → act.

Scan

Discovers all threads in a channel — active, public archived, private archived — with full pagination. Analyzes each for inactivity, message count, locked/archived state, and auto-categorizes by issue type.

python scripts/scan_threads.py --channel-id 123456789 --min-inactive-days 30

Report

Generates markdown with age breakdowns (30-60, 60-90, 90-180, 180+ days), issue categories (billing, bugs, API errors, performance), and full thread details.

python scripts/generate_report.py --input stale_threads.json --categorize

Act

Bulk locks and archives stale threads. Always dry-runs first. Requires explicit user confirmation. Locks before archiving (order matters for Discord's API).

# Always dry-run first
python scripts/lock_archive_threads.py --input stale_threads.json --dry-run

# After explicit confirmation
python scripts/lock_archive_threads.py --input stale_threads.json --confirm

Bonus: CDP DOM Manipulation

Because we have a full CDP connection, the controller can do things the API can't:

# Click a button in Discord's UI
ctrl.cdp.click_element('[aria-label="Thread Menu"]')

# Type into a contenteditable
ctrl.cdp.type_in_element('[contenteditable="true"]', "Closing this")

# Read visible text
title = ctrl.cdp.get_element_text('.channel-name')

And when everything else fails:

ctrl.xdo.activate_discord()
ctrl.xdo.send_keys("Hello!")
ctrl.xdo.send_key("Return")

Built With: Codex CLI + Custom Models

This entire project was built and tested using Codex CLI with custom AI models. Not GPT-4. Not Claude. Two alternative models:

The Codex Launcher lets you swap OpenAI models for these alternatives. Same Codex CLI experience, powered by models that cost nothing (or significantly less).

AI Tool Compatibility

The skill format (SKILL.md) is standard. The repo includes setup guides for five AI coding tools:

Codex CLI
✓ Tested & Working
Claude Code
? Not tested
OpenCode
? Not tested
ZCode
? Not tested
Antigravity
? Not tested

We only tested with Codex. The others should work since they all read SKILL.md the same way, but we haven't verified. PRs welcome.

Pros

Cons

The Verdict

For personal server management on Ubuntu Linux, this approach is ridiculously convenient. You skip 30 minutes of bot setup and go straight to managing threads. The CDP bridge is elegant — extracting the token via JS injection, then using it for REST API calls, with DOM manipulation as a bonus.

Is it "proper"? No. Will Discord eventually break it? Maybe. Was it a fun engineering challenge powered by free AI models? Absolutely.

If you're managing your own server and don't want the overhead of bot infrastructure, give it a try. Just don't use it for spam or abuse.

The Repo

github.com/roman-ryzenadvanced/discord-thread-manager

MIT licensed. The core is scripts/discord_controller.py — ~500 lines of Python handling CDP connection, token extraction, REST API calls, and xdotool fallback. The rest is analysis helpers and CLI wrappers.

Everything built with Codex Launcher + free mimo 2.5 pro API on Ubuntu.


Built with Codex CLI + xiaomi mimo 2.5 pro (free API) on Ubuntu Linux.

Codex Launcher · Free Mimo 2.5 Pro API · z.ai 10% OFF