How to set up incident alerts via Telegram for your MU Online server
Build a Telegram bot alert system to get notified within seconds when your MU Online server's GameServer, MySQL, or website goes down, with monitoring scripts, escalation, and controlled failure testing.
When the GameServer goes down at 3 AM and nobody notices until players start complaining on Discord, the cost isn't just technical — it's reputational, and on monetized servers, financial too (donations and paid events interrupted without warning). A Telegram-based alert system solves this blind spo
When the GameServer goes down at 3 AM and nobody notices until players start complaining on Discord, the cost isn't just technical — it's reputational, and on monetized servers, financial too (donations and paid events interrupted without warning). A Telegram-based alert system solves this blind spot, notifying the admin team within seconds, directly on their phone, without relying on someone watching a dashboard. This tutorial shows how to create the bot, write verification scripts for your MU Online server's critical services, configure escalation, and test failures in a controlled way before trusting the system in production.
Why Telegram instead of email or SMS
Email has variable delivery delay and frequently ends up in spam when sent by an automated script without reputable SMTP infrastructure. SMS has a per-message cost and doesn't scale well for frequent alerts. Telegram, on the other hand, offers a free bot API, near-instant delivery via push notification on the phone, and supports groups with multiple admins receiving the same alert simultaneously — it's the most widely used channel today by private server admins precisely because of this combination of zero cost and speed.
Creating the bot on Telegram
- Open a conversation with @BotFather on Telegram.
- Send
/newbotand follow the instructions, setting a name (e.g., "ViciadosMU Monitor") and a username ending in "bot" (e.g.,viciadosmu_monitor_bot). - BotFather returns a token in the format
123456789:ABCdefGhIJKlmNoPQRsTUvwxYZ— guard it with the same care as a database password. - Create a Telegram group with the admins and add the bot to that group.
- Find the group's
chat_idby accessinghttps://api.telegram.org/bot<TOKEN>/getUpdatesafter sending any message in the group — the group'schat_idappears in the returned JSON (usually a negative number).
Monitoring structure: what to check on the MU server
| Service | What to check | Failure signal |
|---|---|---|
| GameServer | Active process and listening port (e.g., 55901) | Dead process or closed port |
| MySQL/MariaDB | Connection and response to a simple query (SELECT 1) | Timeout or connection error |
| ConnectServer | Entry port (e.g., 44405) responding | Closed port |
| Site/panel | HTTP 200 on the home page and login page | Status other than 200 or timeout |
| Host RAM/CPU usage | Percentage above threshold (e.g., 90%) | Resource saturated, risk of imminent crash |
| Disk space | Free percentage below threshold (e.g., 10%) | Log or backup filling up the disk |
Verification script in Bash (Linux)
A simple script, run via cron every minute, covers most cases:
#!/bin/bash
# monitor_mu.sh
TOKEN="123456789:ABCdefGhIJKlmNoPQRsTUvwxYZ"
CHAT_ID="-1001234567890"
STATE_FILE="/tmp/mu_monitor_state"
send_alert() {
local message="$1"
curl -s -X POST "https://api.telegram.org/bot${TOKEN}/sendMessage" \
-d chat_id="${CHAT_ID}" \
-d text="${message}" \
-d parse_mode="Markdown" > /dev/null
}
check_process() {
local name="$1"
local proc="$2"
if ! pgrep -f "${proc}" > /dev/null; then
if ! grep -q "${name}_DOWN" "${STATE_FILE}" 2>/dev/null; then
send_alert "🔴 *ALERT*: ${name} went down on the server!"
echo "${name}_DOWN" >> "${STATE_FILE}"
fi
else
if grep -q "${name}_DOWN" "${STATE_FILE}" 2>/dev/null; then
send_alert "🟢 *RECOVERED*: ${name} is back to normal."
sed -i "/${name}_DOWN/d" "${STATE_FILE}"
fi
fi
}
check_process "GameServer" "GameServer"
check_process "ConnectServer" "ConnectServer"
check_process "MySQL" "mysqld"
Save it as /opt/scripts/monitor_mu.sh, give it execute permission (chmod +x), and schedule it in cron:
* * * * * /opt/scripts/monitor_mu.sh
Monitoring the site and panel
To check HTTP availability, add an equivalent function using curl with status code verification:
check_http() {
local name="$1"
local url="$2"
local status
status=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 "${url}")
if [ "${status}" != "200" ]; then
send_alert "🔴 *ALERT*: ${name} responded with status ${status} (expected 200)."
fi
}
check_http "Main site" "https://www.viciadosmu.com.br"
check_http "Login panel" "https://www.viciadosmu.com.br/login"
Avoiding alert fatigue with cooldown
Sending an alert every minute while the service is down makes the channel useless quickly — the team ends up muting the notifications. The pattern used in the script above (the STATE_FILE state file) solves this: the alert is only resent when the state changes (from "up" to "down" or vice versa), not on every cron run. For cases that require periodic reminders during long incidents, add a second timestamp that fires a "reminder" every 30 minutes while the service remains down.
Escalation by severity
Not every alert has the same urgency. Separate them by severity level so you don't mix a "disk 85% full" alert with "GameServer went down":
| Level | Example | Suggested action |
|---|---|---|
| Critical | GameServer, ConnectServer, or MySQL went down | Immediate send + mention everyone (@all in the group, if supported) |
| High | Site down, high latency | Immediate send to the group |
| Warning | Disk above 80%, RAM above 85% | Single daily send, no repeats |
| Informational | Backup completed, deploy done | Separate channel, no urgent push |
Create separate Telegram groups or topics per level, so critical alerts don't get lost among routine informational messages.
Testing the system before trusting it
Never trust an alert system that has never fired on purpose. Run a controlled test: manually stop the GameServer during a low-traffic time (systemctl stop gameserver or kill the process), confirm the alert arrives on Telegram in under 1 minute, bring the service back up, and confirm the "recovered" alert also fires. Repeat the test for MySQL and for the site, simulating each one going down in isolation.
Integrating with emulator-specific logs
Beyond processes and ports, many emulators generate log files with specific errors (mass authentication failure, account database connection error, unhandled exceptions). A tail -F combined with grep in a loop can trigger alerts when known error patterns appear:
tail -F /home/mu/GameServer/Log/error.log | while read -r line; do
if echo "${line}" | grep -qi "database connection failed"; then
send_alert "⚠️ GameServer log reported a database connection failure."
fi
done
Run this loop as a separate systemd service, not inside the main cron, since it runs continuously.
Bot security best practices
Never leave the bot token in a public repository or in a script accessible via the site's URL. Treat it like a credential: store it in an environment variable or in a file with restricted permissions (chmod 600). If the token leaks, revoke it immediately via BotFather (/revoke) and generate a new one, updating every script that uses it.
Common errors and fixes
| Symptom | Likely cause | Solution |
|---|---|---|
| Bot doesn't send messages | Incorrect token or chat_id | Confirm the token with BotFather and the chat_id via getUpdates |
| Duplicate alerts every minute | Missing state control (cooldown) | Implement a state file to avoid repeating the same alert |
| No alert during a real outage | Cron not running or script stuck | Check crontab -l and cron logs; add monitoring of the monitor itself |
| Message arrives truncated or unformatted | parse_mode incompatible with characters used | Escape special Markdown characters or use HTML as parse_mode |
| Token exposed publicly | Script committed to a public repository | Revoke the token in BotFather and move credentials to an environment variable |
Alert deployment checklist
- Bot created with BotFather and token stored securely.
- Telegram group created with the admins and chat_id identified.
- Process verification script (GameServer, ConnectServer, MySQL) scheduled in cron.
- HTTP verification of the site and panel configured.
- Cooldown/state implemented to avoid alert fatigue.
- Severity levels defined and separated by channel/topic.
- Controlled outage and recovery test performed for each service.
- Monitoring of the monitor itself (watchdog) configured.
With alerts running reliably, the next step is to connect this monitoring to the overall server operation routine described in the tutorial on how to create a MU Online server, ensuring infrastructure, gameplay, and community are all covered by the same incident response process.
Frequently asked questions
Do I need to pay to use a Telegram bot for alerts?
No, the Telegram bot API is free and has no practical usage limit for the alert volume of a MU server. The only cost is the server/VPS running the monitoring script, which usually already exists in your infrastructure.
What's the difference between monitoring via Telegram and using a service like UptimeRobot?
Services like UptimeRobot check from outside whether the port/site responds, which is great for external availability. Your own script running inside the server can check MU-specific things, like stuck processes, GameServer RAM usage, or MySQL replication failures, which a generic external monitor can't see.
Can the bot notify multiple admins at the same time?
Yes, you can send the same message to a Telegram group with all admins, or to multiple individual chat_ids. Groups are simpler to maintain because they don't require updating the recipient list in the script every time someone joins or leaves the team.
How do I avoid being flooded with repeated alerts during a long outage?
Implement a cooldown (e.g., don't resend the same alert for 15 minutes) and a 'recovered' alert when the service comes back. This avoids alert fatigue, which is when the admin starts ignoring notifications due to excessive noise.
Can this system be integrated directly with the game panel (IGCN, MuEMU)?
Yes, if the panel exposes an API or error log, you can read those files/endpoints in the same monitoring script and trigger specific alerts, such as an account database connection drop or a mass authentication error.