A small, open-source Discord bot that lets people obfuscate code straight from Discord. Someone
runs /obfuscate, attaches a source file (or pastes a snippet), picks a strength, and the bot
forwards it to the Joker Obfuscator public API and hands back the
obfuscated file — as an ephemeral reply by default.
It is a thin, honest wrapper around the API: it forwards bytes and returns the response. It never executes, evals, or interprets anything a user uploads.
Obfuscation makes code hard to read and hard to trivially copy. It is not encryption and not a guarantee of secrecy — please don't market it as "unbreakable."
- Node.js 18.17+ (the bot uses the built-in
fetch/FormData/Blob). - A Discord application + bot (Developer Portal).
- A Joker API key — pay-per-use, spends credits from your account balance.
- Get a Joker API key. Create an account at jokerobfuscator.com,
add credits, then generate a key under
Account → API. It starts with
jkr_live_and is shown once — copy it somewhere safe. - Create the Discord bot. In the Developer Portal: create an application, add a Bot, and copy the Bot Token and the Application (Client) ID.
- Configure. Copy
.env.exampleto.envand fill in the values (see the table below).cp .env.example .env
- Install.
npm install
- Register the slash command.
(Set
npm run deploy-commands
ALLOWED_GUILDSfirst for instant registration while testing; global registration can take up to ~1 hour.) - Invite the bot to your server with the
applications.commandsscope (andbot). A minimal invite URL looks like:https://discord.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&scope=bot+applications.commands&permissions=0 - Run it.
npm start
- In Discord, run
/obfuscate, choose astrength, and attach a file (or pastecode+ pick alanguage).
All configuration is via environment variables (never hard-code secrets):
| Variable | Required | Default | Description |
|---|---|---|---|
DISCORD_TOKEN |
yes | — | Discord bot token. Keep secret. |
DISCORD_CLIENT_ID |
yes | — | Discord application (client) ID. Used to register the slash command. |
JOKER_API_KEY |
yes | — | Your Joker key (jkr_live_…). Spends your credits. Server-side only. |
JOKER_API_BASE |
no | https://jokerobfuscator.com |
API base URL. Change only for a self-hosted / white-label instance. |
ALLOWED_GUILDS |
no | (empty = global) | Comma-separated guild IDs. Registers commands per-guild and ignores others. |
COOLDOWN_SECONDS |
no | 15 |
Per-user cooldown between /obfuscate calls (anti-spam / anti-credit-drain). |
strength(required) —light(fastest, cheapest),medium(balanced),heavy(strongest).file(optional) — the source file to obfuscate (max 10 MB).code(optional) — paste code directly instead of uploading.language(required withcode) — the language of the pasted snippet.
Provide either a file or pasted code + language.
.lua .luau .js .py .jar .php .go .rb .kt — max 10 MB each. (Pasting code
supports the source languages, not .jar, which is a compiled archive.)
Each successful obfuscation spends credits from the account behind JOKER_API_KEY (heavier
strengths and larger/certain languages cost more). The bot shows the exact cost (from the API's
X-Credits-Cost header) in its reply. If the engine fails, the API refunds automatically.
Every request sends a unique Idempotency-Key, so if a call is retried the API replays the prior
result instead of charging twice.
| Symptom | Likely cause / fix |
|---|---|
Configuration error: … on start |
A required env var is missing/malformed. The message says which. |
| Bot replies "API key was rejected" | JOKER_API_KEY is wrong, revoked, or for a different instance. This is an operator problem — regenerate the key at Account → API. |
| Bot replies "out of credits" | Top up the account behind the key. |
| Bot replies "Rate limit reached" | The API allows ~60 requests/min per key. Wait and retry (the reply suggests how long). |
| Slash command doesn't appear | Run npm run deploy-commands; global commands can take up to ~1 hour. Use ALLOWED_GUILDS for instant updates. |
| "Could not reach the Joker API" | Network/DNS/TLS issue. Note: a TLS-inspecting corporate proxy can break the outbound HTTPS call. |
Offline unit tests (no network, no Discord login, no real key) stub the HTTP call and drive the command handler + error mapping:
npm testReal end-to-end obfuscation requires a live JOKER_API_KEY and network access to the API — that is
the one manual step the automated tests can't cover.
- No secrets in git.
.envandnode_modules/are git-ignored; only.env.example(placeholders) is committed. The bot never logs the API key or the Discord token, and error text is passed through a redactor as a backstop. - No code execution. User uploads are forwarded to the API and the response is returned. There
is no
eval, no shell, no interpreter — the bot only moves bytes. - Guardrails. File extension and size (10 MB) are validated before upload; a per-user cooldown limits spam and credit drain; only the invoking interaction's attachment is used.
- Minimal, pinned dependencies. Just
discord.jsanddotenv, at pinned versions, with nopostinstallscripts.
This project is not affiliated with, endorsed by, or sponsored by Discord, and is an independent example built on the Joker Obfuscator public API. Use it only on code you own or are authorized to modify, and in accordance with the Discord Terms of Service and the Joker Obfuscator terms. Obfuscation raises the effort to read/copy code; it does not make code secret or tamper-proof.
MIT.