telegram: move session secrets to .env, launch MCP via wrapper

- .mcp.json: both telegram servers now start via scripts/telegram-mcp.sh
  <usulsu|helper> instead of hardcoding session strings — config is now
  secret-free and safe to commit.
- scripts/telegram-mcp.sh: sources .env, selects the per-account session
  string (TELEGRAM_SESSION_STRING / TELEGRAM_SESSION_STRING_HELPER), execs
  the telegram-mcp binary (path overridable via TELEGRAM_MCP_BIN).
- scripts/regen_telegram_session.sh: rewritten — captures the generated
  string, saves it to .secrets/session_<account>.txt, and upserts it into
  .env. Fixes the broken /projects/... generator path.
- package.json: tg:session:usulsu / tg:session:helper npm scripts.
- .gitignore: ignore .secrets/.

Root cause of the dead session: hardcoded strings lived in git, so laptop
and VPS shared one auth_key across two IPs and Telegram revoked it. Strings
now live only in local, gitignored files — one per device/account.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
usulpro 2026-06-08 00:44:06 +07:00
parent 631ddddb37
commit 80c918d282
5 changed files with 118 additions and 44 deletions

3
.gitignore vendored
View File

@ -17,6 +17,9 @@ output/html/
# Local Chrome profile (contains cookies, logins — never commit) # Local Chrome profile (contains cookies, logins — never commit)
.chrome/ .chrome/
# Regenerated Telegram session strings (per-account, per-device secrets)
.secrets/
# Telegram fetch outputs — per-machine cursor + per-run scratch # Telegram fetch outputs — per-machine cursor + per-run scratch
tracking/telegram_state.json tracking/telegram_state.json
tracking/telegram_inbox.json tracking/telegram_inbox.json

View File

@ -17,22 +17,18 @@
} }
}, },
"telegram-usulpro": { "telegram-usulpro": {
"command": "/projects/my-utils/telegram/.venv/bin/telegram-mcp", "command": "bash",
"args": [], "args": [
"env": { "/home/usul/workspace/projects/cv-2026/scripts/telegram-mcp.sh",
"TELEGRAM_API_ID": "30708025", "usulsu"
"TELEGRAM_API_HASH": "1de1cfbec7f43f460b4400f72b3093c6", ]
"TELEGRAM_SESSION_STRING": "1ApWapzMBuy6zzXtKHk9qipYPfDHEZOowyn2NukLpKpbRyNggosUMunnjUA7EJTHuwCcf2EWn4Wk6ezjYw8zfczt-nGo4nbQay4a3IfnjHj1byv8sIwIbLqyJzeWlvOU2eO3d9l-5Ys-MY3DbpHC4QaU6MrdizJsxW52hghF8bLUyQ5xw15Ih91X03xG-5XMCeFscwStp2Be8bZgQV1JhiyImufneFt6Z1DjibTnn8U4uYXVG2jd1AmrFna7seGpFBy7vbV4QPjxcYiaOWO_qXH0TSxTHTHmLPK6FAHfkq1L-q5MXlEHIrB4nNeUKKX48gdxW662aYPsH1Audb6-oB8TkycRZbls="
}
}, },
"telegram-helper": { "telegram-helper": {
"command": "/projects/my-utils/telegram/.venv/bin/telegram-mcp", "command": "bash",
"args": [], "args": [
"env": { "/home/usul/workspace/projects/cv-2026/scripts/telegram-mcp.sh",
"TELEGRAM_API_ID": "30708025", "helper"
"TELEGRAM_API_HASH": "1de1cfbec7f43f460b4400f72b3093c6", ]
"TELEGRAM_SESSION_STRING": "1BVtsOJsBu0I61cjJwTKtmzz5BJOz53W5nvAo_aZJvpCl86hUC1zx-CVnYA4QOZ7ZULL3mNG3xg9uvZD7htcSP8QvH7U9VvkZspLT8ygEAX4pu9KJ-shhjYFCWQBDOsOujlOcGBVaVEBDBLMSIEmU7zfg-zhyTOlZ4M3OOfOQqs8nV9BlELaOTsaHwzU3OscKSwBGjewHcTvqCksp9JXFLOda9gMOBVV_Z65dCg9ovwKKOKSUNiIc3zC3f2UkZTq82hkObrhLewjI2Mue4fIEdCY0ziBkjBVTiPi40-wvv5eWopOcnf112Q5ansYoba3rY5ItQZhn7UDKfZk8-EDhnin8tUFSahs="
}
} }
} }
} }

View File

@ -7,7 +7,8 @@
"scripts": { "scripts": {
"pdf": "node scripts/generate-pdf.mjs", "pdf": "node scripts/generate-pdf.mjs",
"chrome": "bash scripts/launch-chrome.sh &", "chrome": "bash scripts/launch-chrome.sh &",
"tg:session": "bash scripts/regen_telegram_session.sh" "tg:session:usulsu": "bash scripts/regen_telegram_session.sh usulsu",
"tg:session:helper": "bash scripts/regen_telegram_session.sh helper"
}, },
"dependencies": { "dependencies": {
"puppeteer": "^24.37.3" "puppeteer": "^24.37.3"

View File

@ -1,44 +1,82 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Regenerate a Telegram session string. # Regenerate a Telegram session string for ONE account, save it to a fixed-name
# Reads TELEGRAM_API_ID / TELEGRAM_API_HASH from the project .env, # temp file under .secrets/, and upsert it into the project .env so the MCP
# then runs the generator from the telegram-mcp install. # server (via scripts/telegram-mcp.sh) and the direct Telethon scripts pick it up.
#
# Why per-account strings: one Telegram authorization (auth_key / session string)
# must be used from ONE source. Sharing a single string across two devices/IPs
# makes Telegram permanently revoke the key. Each device/account gets its own.
# #
# Usage: # Usage:
# bash scripts/regen_telegram_session.sh # regenerate usulsu (main) # bash scripts/regen_telegram_session.sh usulsu # main account -> TELEGRAM_SESSION_STRING
# bash scripts/regen_telegram_session.sh helper # regenerate samuishechka # bash scripts/regen_telegram_session.sh helper # samuishechka -> TELEGRAM_SESSION_STRING_HELPER
# or via npm:
# pnpm tg:session:usulsu
# pnpm tg:session:helper
# #
# After running, paste the printed session string into the project .env: # At the generator prompts:
# usulsu → TELEGRAM_SESSION_STRING=... # - "Account label" -> just press Enter
# helper → TELEGRAM_SESSION_STRING_HELPER=... # - "update your .env? (y/N)" -> answer N (this script writes .env itself)
set -euo pipefail set -euo pipefail
ACCOUNT="${1:-}" # "helper" for samuishechka, empty for usulsu ACCOUNT="${1:-}"
case "$ACCOUNT" in
usulsu) ENV_VAR="TELEGRAM_SESSION_STRING" ;;
helper) ENV_VAR="TELEGRAM_SESSION_STRING_HELPER" ;;
*) echo "usage: $0 <usulsu|helper>" >&2; exit 1 ;;
esac
PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)" PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
TELEGRAM_DIR="/projects/my-utils/telegram" TELEGRAM_DIR="${TELEGRAM_MCP_DIR:-/home/usul/workspace/projects/my-utils/telegram}"
ENV_FILE="$PROJECT_ROOT/.env"
if [ ! -f "$PROJECT_ROOT/.env" ]; then SECRETS_DIR="$PROJECT_ROOT/.secrets"
echo "missing $PROJECT_ROOT/.env" >&2 OUT_FILE="$SECRETS_DIR/session_${ACCOUNT}.txt"
exit 1
fi
set -a
. "$PROJECT_ROOT/.env"
set +a
[ -f "$ENV_FILE" ] || { echo "missing $ENV_FILE" >&2; exit 1; }
set -a; . "$ENV_FILE"; set +a
if [ -z "${TELEGRAM_API_ID:-}" ] || [ -z "${TELEGRAM_API_HASH:-}" ]; then if [ -z "${TELEGRAM_API_ID:-}" ] || [ -z "${TELEGRAM_API_HASH:-}" ]; then
echo "TELEGRAM_API_ID / TELEGRAM_API_HASH missing in $PROJECT_ROOT/.env" >&2 echo "TELEGRAM_API_ID / TELEGRAM_API_HASH missing in $ENV_FILE" >&2
exit 1 exit 1
fi fi
[ -x "$TELEGRAM_DIR/.venv/bin/python" ] || {
echo "generator not found at $TELEGRAM_DIR/.venv/bin/python" >&2
echo "set TELEGRAM_MCP_DIR to your telegram-mcp checkout" >&2; exit 1; }
if [ "$ACCOUNT" = "helper" ]; then mkdir -p "$SECRETS_DIR"
echo "Regenerating session for samuishechka (helper account)." tmp="$(mktemp)"; trap 'rm -f "$tmp"' EXIT
echo "When prompted for label, enter: helper"
else echo ">> Regenerating Telegram session for: $ACCOUNT (-> $ENV_VAR)"
echo "Regenerating session for usulsu (main account)." echo ">> Sign in with the '$ACCOUNT' account when scanning the QR code."
echo "When prompted for label, leave empty (press Enter)." echo ">> At 'Account label' press Enter; at 'update .env' answer N."
fi
echo "" echo ""
cd "$TELEGRAM_DIR" # Run the generator unbuffered; show output live AND capture it to $tmp.
exec .venv/bin/python session_string_generator.py --qr "$@" ( cd "$TELEGRAM_DIR" \
&& TELEGRAM_API_ID="$TELEGRAM_API_ID" TELEGRAM_API_HASH="$TELEGRAM_API_HASH" \
.venv/bin/python -u session_string_generator.py --qr ) 2>&1 | tee "$tmp"
# Extract the session string: first non-empty line after the header marker.
SESSION="$(awk '/----- Your Session String -----/{f=1; next} f && NF {print $1; exit}' "$tmp")"
if [ -z "$SESSION" ]; then
echo "!! Could not capture a session string from the generator output." >&2
echo "!! Nothing written. Re-run and complete the login." >&2
exit 1
fi
# Save to the fixed temp file (owner-only).
umask 077
printf '%s\n' "$SESSION" > "$OUT_FILE"
echo ""
echo ">> Saved session string -> $OUT_FILE"
# Upsert ENV_VAR into .env (replace the existing line or append).
if grep -q "^${ENV_VAR}=" "$ENV_FILE"; then
awk -v k="$ENV_VAR" -v v="$SESSION" \
'$0 ~ "^" k "=" {print k "=" v; done=1; next} {print}
END{if(!done) print k "=" v}' "$ENV_FILE" > "$tmp"
cat "$tmp" > "$ENV_FILE"
else
printf '%s=%s\n' "$ENV_VAR" "$SESSION" >> "$ENV_FILE"
fi
echo ">> Updated $ENV_VAR in $ENV_FILE"
echo ">> Done. Run /mcp (reconnect) to pick up the new session for telegram-$ACCOUNT."

36
scripts/telegram-mcp.sh Executable file
View File

@ -0,0 +1,36 @@
#!/usr/bin/env bash
# Launch the telegram-mcp server for one account, reading API creds and the
# session string from the project .env. Used by .mcp.json so that NO secrets
# are hardcoded in the committed config.
#
# Usage (from .mcp.json):
# bash scripts/telegram-mcp.sh usulsu # main account -> TELEGRAM_SESSION_STRING
# bash scripts/telegram-mcp.sh helper # samuishechka -> TELEGRAM_SESSION_STRING_HELPER
#
# The telegram-mcp binary path can be overridden with TELEGRAM_MCP_BIN.
set -euo pipefail
ACCOUNT="${1:?usage: telegram-mcp.sh <usulsu|helper>}"
PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
BIN="${TELEGRAM_MCP_BIN:-/home/usul/workspace/projects/my-utils/telegram/.venv/bin/telegram-mcp}"
[ -f "$PROJECT_ROOT/.env" ] || { echo "missing $PROJECT_ROOT/.env" >&2; exit 1; }
set -a; . "$PROJECT_ROOT/.env"; set +a
case "$ACCOUNT" in
usulsu) export TELEGRAM_SESSION_STRING="${TELEGRAM_SESSION_STRING:-}" ;;
helper) export TELEGRAM_SESSION_STRING="${TELEGRAM_SESSION_STRING_HELPER:-}" ;;
*) echo "account must be 'usulsu' or 'helper'" >&2; exit 1 ;;
esac
if [ -z "${TELEGRAM_API_ID:-}" ] || [ -z "${TELEGRAM_API_HASH:-}" ]; then
echo "TELEGRAM_API_ID / TELEGRAM_API_HASH missing in $PROJECT_ROOT/.env" >&2
exit 1
fi
if [ -z "${TELEGRAM_SESSION_STRING:-}" ]; then
echo "session string for '$ACCOUNT' is empty in .env — regenerate it with:" >&2
echo " pnpm tg:session:$ACCOUNT" >&2
exit 1
fi
exec "$BIN"