# Stop any old instance (ignore errors if it didn't exist)
sudo systemctl disable --now mbot.service 2>/dev/null || true
# Prepare clean workspace
cd ~
rm -rf ~/mBot-main ~/mbot.tar.gz
# Download public fork (no login needed) and build
sudo apt update && sudo apt -y install jq
sudo apt update && sudo apt -y install git curl
curl -L -o mbot.tar.gz https://codeload.github.com/hunter0x8/mBot/tar.gz/refs/heads/main
tar -xzf mbot.tar.gz
cd mBot-main
# Ensure Go exists, install if missing
go version >/dev/null 2>&1 || { \
curl -OL https://go.dev/dl/go1.22.5.linux-amd64.tar.gz && \
sudo tar -C /usr/local -xzf go1.22.5.linux-amd64.tar.gz && \
echo 'export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin' >> ~/.profile && source ~/.profile; }
go build .
cat > ~/mBot-main/run_mbot.sh <<'SH'
#!/usr/bin/env bash
# run_mbot.sh — self-supervising wrapper for mBot with Discord alerts
# Usage: ./run_mbot.sh <RAW_TOKEN> [DELAY_SECONDS] <DISCORD_WEBHOOK_URL>
# Notes:
# - Pass the RAW token (NO "Bearer " prefix). The bot adds Bearer itself.
# - Set ALERT_COOLDOWN env (seconds) to change alert cooldown (default 300).
set -euo pipefail
TOKEN="${1:-}" # RAW token (no "Bearer ")
DELAY="${2:-30}" # seconds
WEBHOOK="${3:-}" # Discord webhook URL
HOSTNAME="$(hostname)"
ALERT_COOLDOWN="${ALERT_COOLDOWN:-300}" # 5 minutes default
COOLDOWN_FILE="/run/mbot_alert_last.ts"
if [[ -z "$TOKEN" || -z "$WEBHOOK" ]]; then
echo "Usage: $0 <RAW_TOKEN> [DELAY_SECONDS] <DISCORD_WEBHOOK_URL>"
exit 1
fi
send() {
# JSON-safe post to Discord using jq for proper escaping
local msg="$1"
local payload out code
payload=$(printf '%s' "$msg" | jq -Rs '{content: .}')
out="$(mktemp /tmp/mbot_send.XXXXXX)"
code=$(curl -sS -o "$out" -w '%{http_code}' \
-H "Content-Type: application/json" \
-d "$payload" "$WEBHOOK" || echo '000')
if [[ "$code" != "204" && "$code" != "200" ]]; then
echo "SEND FAIL http=$code body=$(cat "$out")" >&2
else
echo "SEND OK http=$code" >&2
fi
rm -f "$out"
}
should_alert_now() {
local now ts=0
now="$(date +%s)"
[[ -f "$COOLDOWN_FILE" ]] && ts="$(cat "$COOLDOWN_FILE" 2>/dev/null || echo 0)"
if (( now - ts >= ALERT_COOLDOWN )); then
echo "$now" > "$COOLDOWN_FILE"
return 0
fi
return 1
}
while true; do
LOG="/tmp/mbot.$(date +%s).log"
echo "---- starting mBot at $(date -Is) ----" | tee -a "$LOG"
# Run mBot with line-buffered output; capture the whole run to LOG
stdbuf -oL -eL ./mBot -t "$TOKEN" -d "$DELAY" 2>&1 | tee -a "$LOG"
rc=${PIPESTATUS[0]}
# Decide on a single alert per cycle (prefer auth error over generic exit)
alerted=0
if grep -qiE 'Bearer token expired|401|unauthori(z|s)ed|forbidden' "$LOG"; then
if should_alert_now; then
send "⚠️ **mbot** on \`$HOSTNAME\`: token/auth issue detected.
$(tail -n 5 "$LOG")
(If this persists: update the token with \`~/update-token.sh\` or edit \`/etc/mbot.env\` and restart.)"
else
echo "ALERT SUPPRESSED (cooldown)"
fi
alerted=1
fi
if [[ $rc -ne 0 && $alerted -eq 0 ]]; then
if should_alert_now; then
send "⚠️ **mbot** on \`$HOSTNAME\` exited with code $rc.
$(tail -n 5 "$LOG")"
else
echo "ALERT SUPPRESSED (cooldown)"
fi
fi
# Brief backoff before relaunch so we don't tight-loop on failures
sleep 5
done
SH
chmod +x ~/mBot-main/run_mbot.sh
sudo bash -c 'cat > /etc/mbot.env <<EOF
TOKEN=withoutthebreaerpart
WEBHOOK=https://discord.com/api/webhooks/bluhhhhhhhbluhhhhhhhh
DELAY=20
EOF'
sudo chmod 600 /etc/mbot.env
ME=$(whoami)
sudo tee /etc/systemd/system/mbot.service >/dev/null <<UNIT
[Unit]
Description=Synack mBot + Discord notifier
After=network-online.target
[Service]
User=$ME
WorkingDirectory=/home/$ME/mBot-main
EnvironmentFile=/etc/mbot.env
ExecStart=/home/$ME/mBot-main/run_mbot.sh "\${TOKEN}" "\${DELAY}" "\${WEBHOOK}"
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
UNIT
sudo systemctl daemon-reload
sudo systemctl enable --now mbot.service
journalctl -u mbot -f
cat > ~/update-token.sh <<'SH'
#!/usr/bin/env bash
read -p "Paste RAW token (no 'Bearer '): " NEWTOK
sudo sed -i "s|^TOKEN=.*|TOKEN=${NEWTOK}|" /etc/mbot.env
sudo systemctl restart mbot.service
sleep 1
journalctl -u mbot -n 30 --no-pager
SH
chmod +x ~/update-token.sh
When the token actually expires, you’ll get the
~/update-token.sh # paste RAW token (no "Bearer ")
If logs look good (no “expired” error), you’re set.
a quick double-check, run:
# 1) Service state (should print "active")
systemctl is-active mbot && echo "mbot is active"
# 2) Show brief status (look for Active: active (running))
systemctl status mbot --no-pager
# 3) Confirm a single running process
ps -o pid,etimes,cmd -u $(whoami) | grep -E '[m]Bot|run_mbot.sh'
# 4) Tail recent logs (no "expired" messages should appear)
journalctl -u mbot -n 40 --no-pager
To Trim old logs
sudo journalctl --vacuum-time=7d