This bot watches Discord Minecraft moderation logs, extracts private-message log lines such as /cmi msg player text, sign text from sign-placement logs, and book pages from book-edit logs. It detects the language and replies underneath with an English translation or a staff-attention flag.
Default target:
- Server:
487398800353263616 - Message channel:
807177293943275530 - Signs channel:
1396738538229469184 - Books channel:
1397140960902647879
Example output:
(Polish) `postaw pochodnie` == `place torches`
:triangular_flag_on_post: (Dutch) `...` == `...`
discord.jsfor Discord.- LibreTranslate for translation. This can use your own free self-hosted instance, or a hosted endpoint if you have an API key.
- Local keyword heuristics for the
:triangular_flag_on_post:warning. This is useful as a moderation hint, not a perfect hate-speech classifier.
Public translation endpoints can be rate-limited, unavailable, or require an API key. The best no-credit-card path is self-hosting LibreTranslate on the same VPS or another always-on machine.
- Open the Discord Developer Portal: https://discord.com/developers/applications
- Create a new application.
- Go to Bot and create a bot.
- Copy the bot token.
- Enable Message Content Intent under the bot's privileged gateway intents.
- Invite the bot to your server with these permissions:
- View Channel
- Read Message History
- Send Messages
- Use External Emojis is optional
Invite URL pattern:
https://discord.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&permissions=68608&scope=bot
Replace YOUR_CLIENT_ID with the application/client ID from the Developer Portal.
For this bot application, the current invite URL is:
https://discord.com/oauth2/authorize?client_id=1499923232843894794&permissions=137439333440&scope=bot
After inviting it, the bot should appear as a member of the server. If it does not, make sure you selected server 487398800353263616 while logged in with a Discord account that has Manage Server permission.
From this folder:
npm install
cp .env.example .env
nano .envSet at least:
DISCORD_TOKEN=your-real-token
DISCORD_GUILD_ID=487398800353263616
LOG_CHANNEL_ID=807177293943275530
SIGN_CHANNEL_ID=1396738538229469184
BOOK_CHANNEL_ID=1397140960902647879Leave SOURCE_BOT_IDS blank at first. The bot will watch any bot/webhook message in the configured channels except itself. Once you know the MSG SPY bot's Discord user ID, set:
SOURCE_BOT_IDS=the-msg-spy-bot-user-idThat prevents the translator from reacting to other bots in the same channel.
LibreTranslate is free and open source. Run it in a second tmux session:
tmux new -s libretranslate
cd /Users/floris/Projects/Codex/1MBTranslateBot
npm run libretranslateDetach from tmux with Ctrl-b, then d.
On macOS/Homebrew Python, installing with python3 -m pip install --user libretranslate can fail with externally-managed-environment. The npm run libretranslate command avoids that by creating a local .venv-libretranslate/ virtual environment and installing LibreTranslate there.
The bot defaults to:
LIBRETRANSLATE_URL=http://127.0.0.1:5000
LIBRETRANSLATE_API_KEY=If you use hosted LibreTranslate instead, set the hosted URL and put the key in LIBRETRANSLATE_API_KEY.
Optional: LibreTranslate can provide alternative translations:
TRANSLATION_ALTERNATIVES=2
MAX_TRANSLATIONS_PER_MESSAGE=1
MAX_ORIGINAL_LENGTH=600
MAX_TRANSLATION_LENGTH=600TRANSLATION_ALTERNATIVES asks LibreTranslate for extra options. MAX_TRANSLATIONS_PER_MESSAGE controls how many the Discord bot prints. The default is 1 to keep moderation logs readable. The length limits are intentionally roomy enough for sign and book-page text.
Test in the foreground:
npm startOn startup, the bot checks Discord access and LibreTranslate access. If LibreTranslate is not running, it prints the exact tmux and npm run libretranslate commands to start it.
Run it in tmux:
tmux new -s translatebot
cd /Users/floris/Projects/Codex/1MBTranslateBot
npm startDetach from tmux with Ctrl-b, then d.
Reattach later:
tmux attach -t translatebotStop it while attached:
Ctrl-cThe bot has a small built-in profanity/risk list and checks both the original text and the translation. Add your own community-specific terms in .env:
FLAGGED_TERMS=term one,term two,term threeDisable flagging:
ENABLE_RISK_FLAG=false- English messages are skipped when language detection is confident enough, unless risk flagging catches profanity or staff-attention terms.
- Very short messages such as
cmokcan be hard for any free language detector. The bot still tries, but expect occasional misses. - The bot asks LibreTranslate for alternatives when supported. Natural alternatives like
kiss/mwahare still only a machine-translation hint.