Note: This project was fully coded using GitHub Copilot.
Lightweight, friendly Paper plugin that sends Minecraft server notifications to Telegram — join/leave, optional alerts, and a low TPS monitor. Clear setup, sane defaults, admin commands with tab completion, and no fuss.
Quick links: Releases · Actions/Artifacts · Issues
- Install: drop the shaded JAR into
plugins/, start once, editplugins/TelegramPlugin/config.yml, then/hmdqr tg reload. - Key commands:
/hmdqr tg reload— reloads config/runtime and posts a Telegram confirmation/hmdqr tg list— show feature toggles/hmdqr tg enable monitor— enable low TPS monitor (alias forenable_low_tps)/hmdqr tg disable enable_quit— disable quit messages/hmdqr tg toggle enable_join on|off— toggle a feature
- Permissions:
hmdqr.admin(ops) → includes all Telegram subcommands - Config path:
plugins/TelegramPlugin/config.yml - Required config:
telegram.token,telegram.chat_id
- Download the latest shaded JAR from Releases (Assets → file ending with -shaded.jar).
- Copy it to your server's
plugins/folder. - Start the server once to generate
plugins/TelegramPlugin/config.yml. - Edit
config.ymland settelegram.tokenandtelegram.chat_id. - Restart the server.
- Sends join/leave messages to a Telegram chat
- Optional alerts: kick, ban (login disallow), death, teleport, low TPS (cooldown + threshold)
- Asynchronous HTTP (non-blocking) with URL-encoding and timeouts
- Config validated at startup; disables plugin if token/chat ID are missing
- Fully customizable messages with placeholders and parse modes (none/Markdown/MarkdownV2/HTML)
- Admin commands under a root namespace:
/hmdqr telegram …(aliastg) with tab completion - Live toggles for features (enable/disable without restart)
- Reload command also posts a Telegram confirmation including who reloaded
- Java 17+
- Maven 3.8+
- Paper 1.20.6 (recommended)
Using a different Paper version? Update both:
plugin.yml→api-versionpom.xml→io.papermc.paper:paper-apiversion
PaperMC docs: https://docs.papermc.io/
- Stable: get the latest release from GitHub Releases → https://github.com/hmdqr/TelegramPlugin/releases (Assets → shaded JAR)
- Nightly: every push to main builds a JAR; download from GitHub Actions → https://github.com/hmdqr/TelegramPlugin/actions (Artifacts)
Then:
- Place the JAR into
plugins/. - Start once to generate
plugins/TelegramPlugin/config.yml. - Set
telegram.tokenandtelegram.chat_id. - Restart.
Tip: After editing config, you can use /hmdqr telegram reload instead of a full restart.
The configuration file is written to plugins/TelegramPlugin/config.yml on first run.
YAML excerpt:
# Internal config version for upgrades
config_version: 2
telegram:
token: "YOUR_TELEGRAM_BOT_TOKEN"
chat_id: "YOUR_CHAT_ID"
messages:
# Enable/disable notifications
enable_join: true
enable_quit: true
enable_kick: false
enable_ban: false
enable_death: false
enable_teleport: false
enable_low_tps: false
# Text formatting: none | Markdown | MarkdownV2 | HTML
parse_mode: none
# Templates (placeholders: {player}, {uuid}, {world}, {online}, {max})
join: "[+] {player} joined the server."
quit: "[-] {player} left the server."
# Extra placeholders by event:
# Kick: {reason}
kick: "[ALERT] {player} was kicked: {reason}"
# Ban: {reason}
ban: "[ALERT] {player} is banned: {reason}"
# Death: {cause}, {x}, {y}, {z}
death: "\u2620 {player} died to {cause} at {x},{y},{z} in {world}"
# Teleport: {from_x},{from_y},{from_z},{from_world}, {to_x},{to_y},{to_z},{to_world}
teleport: "\u21A6 {player} teleported {from_world}({from_x},{from_y},{from_z}) \u2192 {to_world}({to_x},{to_y},{to_z})"
# Low TPS monitoring
low_tps_check_seconds: 15
low_tps_threshold: 16.0
low_tps_cooldown_seconds: 300
# Placeholders: {tps1m}, {tps5m}, {tps15m}
low_tps: "\u26A0 TPS low: {tps1m} (5m: {tps5m}, 15m: {tps15m})"- telegram.token (string): required, from @BotFather.
- telegram.chat_id (string/int): required. Groups often use a negative ID like -1001234567890.
- messages.enable_join|quit|kick|ban|death|teleport|low_tps (bool): toggles per event.
- messages.parse_mode: none | Markdown | MarkdownV2 | HTML.
- messages.join|quit|kick|ban|death|teleport|low_tps: templates with placeholders.
- messages.low_tps_check_seconds (int): check interval seconds.
- messages.low_tps_threshold (double): alert when 1m TPS below this.
- messages.low_tps_cooldown_seconds (int): minimum seconds between alerts.
- config_version: used internally to merge new defaults on upgrade.
Root prefix to namespace your plugins: /hmdqr
/hmdqr telegram reload- Reloads config and runtime safely. Sends a Telegram message like: "✅ TelegramPlugin configuration reloaded by ."
/hmdqr telegram list- Lists current feature toggles.
/hmdqr telegram toggle <feature> <on|off>- Toggles a feature and saves config.
/hmdqr telegram enable <feature>and/hmdqr telegram disable <feature>- Convenience verbs for toggling.
Short alias for the namespace: replace telegram with tg, e.g. /hmdqr tg reload.
Features (feature keys):
enable_join,enable_quit,enable_kick,enable_ban,enable_death,enable_teleport,enable_low_tps- Friendly alias:
monitor→enable_low_tps
Tab completion is available for subcommands, features, and on/off.
Quick summary:
- Reload:
/hmdqr tg reload - List:
/hmdqr tg list - Enable:
/hmdqr tg enable <feature|monitor> - Disable:
/hmdqr tg disable <feature|monitor> - Toggle:
/hmdqr tg toggle <feature> <on|off>
hmdqr.admin(default: op)- Allows using
/hmdqrand includes all Telegram command permissions.
- Allows using
hmdqr.telegram(default: op)- Base node; includes:
hmdqr.telegram.reloadhmdqr.telegram.togglehmdqr.telegram.list
- Base node; includes:
- Common: {player}, {uuid}, {world}, {online}, {max}
- Kick: {reason}
- Ban: {reason}
- Death: {cause}, {x}, {y}, {z}
- Teleport: {from_x},{from_y},{from_z},{from_world}, {to_x},{to_y},{to_z},{to_world}
- MarkdownV2 and HTML require proper escaping. If a message fails with HTTP 400, first suspect unescaped characters.
- If in doubt, use
parse_mode: nonefor plain text.
- MarkdownV2 (remember to escape special characters):
messages: parse_mode: MarkdownV2 join: "[+] *{player}* joined \\({online}\\/{max}\\)" quit: "[-] *{player}* left"
- HTML:
messages: parse_mode: HTML join: "[+] <i>{player}</i> joined (<code>{online}/{max}</code>)" quit: "[-] <i>{player}</i> left"
- Create a bot via Telegram’s @BotFather and obtain the HTTP API token.
- Send a message to the bot (or add the bot to a group).
- Retrieve the chat ID:
- Visit
https://api.telegram.org/bot<YOUR_TOKEN>/getUpdatesand readmessage.chat.idin the JSON - Group/supergroup IDs are often negative (e.g.,
-1001234567890)
Useful docs
- Bot API sendMessage: https://core.telegram.org/bots/api#sendmessage
- MarkdownV2 rules: https://core.telegram.org/bots/api#markdownv2-style
- HTML style: https://core.telegram.org/bots/api#html-style
- The plugin writes default
config.ymlon first run and merges new defaults on upgrade (copyDefaults = true). - A hidden
config_versionmay be used to track defaults; new keys are added while your existing values are preserved. - If we ever remove/rename keys, you may need to adjust your config manually.
Run in the project root (where pom.xml resides).
Linux/macOS:
mvn -q -DskipTests packageWindows (Command Prompt):
mvn -q -DskipTests packageArtifacts appear in target/.
Notes
- CI builds use Temurin JDK 21, but the plugin targets Java 17 bytecode (maven-compiler release=17). Running on Java 17+ is supported.
Windows
scripts\build.bat— Build the shaded JAR locally (skip tests)scripts\release_simple.bat— Build and upload the shaded JAR directly to a GitHub Release namedv<version>python scripts\release_wizard.py— Interactive wizard: optional version bump → commit/push → tag/push → optional build + upload to Release
CI (GitHub Actions)
- Pushing a tag matching
v*builds and uploads the JAR automatically (see.github/workflows/release.yml).
- Single target chat_id (per plugin instance)
- No proxy configuration
- Only text messages are sent (no photos/files)
- Telegram rate limits apply; the plugin does not queue during downtime
- Treat your bot token as a secret; do not commit
config.ymlwith a real token - Limit who can access your server files and console
Tip: If you prefer not to install Maven globally, add the Maven Wrapper (mvnw, mvnw.cmd) — happy to include it.
- Plugin disables on startup: placeholders in
config.ymlnot replaced, or token/chat ID missing - No messages received:
- Check server console for messages like: Telegram sendMessage failed: HTTP {status_code}
- Ensure the bot is present and allowed to post in the chat/group
- Use the correct (possibly negative) group chat ID
- Confirm outbound connectivity to
api.telegram.org - If using MarkdownV2/HTML, ensure your message text escapes special characters per Telegram rules
Common Telegram API errors
- 400 Bad Request: often due to unescaped characters with
parse_modeset - 403 Forbidden: bot not a participant in the target chat, or blocked
- Default: Paper 1.20.6, Java 17+
- For other versions, align
api-versionand Paper API dependency
PRs and issues are welcome — whether it’s a typo fix, a feature request, or a bug report.
When filing bugs, include:
- Server version (Paper build) and Java version
- Plugin version
- Reproduction steps and relevant console logs
If this plugin saved you time or made your server friendlier, consider supporting development:
- PayPal: https://paypal.me/hmdqr/
Even small tips help keep the work going — thank you!
MIT License — see LICENSE for details.