Files
Hermes-Skills/devops/telethon-proxy-docker/SKILL.md
T
Hermes Skills Manager 6770bc9b9d Initial commit: Hermes Agent skills collection
- Trading skills (OKX, dividend, lottery, quantitative)
- Creative skills (ASCII art, diagrams, video)
- Development skills (GitHub, debugging, TDD)
- Research skills (arXiv, blog monitoring)
- Productivity skills (email, documents, notes)
- MCP integration skills
- Custom user skills
2026-07-05 02:31:15 -04:00

5.8 KiB

name, description, tags
name description tags
telethon-proxy-docker Deploy Telethon-based Telegram bots/forwarders behind a SOCKS5 proxy (Mihomo/Clash) on a server with no direct Telegram access. Covers Docker networking, proxy injection, and phone verification workflow.
telethon
telegram
proxy
docker
mihomo
socks5
forwarder

Telethon + Proxy + Docker Deployment

Deploy Telethon-based Telegram bots/forwarders on a server that requires a proxy (Mihomo/Clash) to reach Telegram API servers.

When to Use

  • User asks to deploy a Telegram bot/forwarder that uses Telethon
  • Server has no direct route to Telegram (Mihomo proxy required)
  • Telethon-based app needs to run in Docker behind a proxy
  • Keywords: "Telegram 转发器", "Telethon proxy", "消息转发", "Telegram forwarder"

Core Problem

Telethon uses MTProto (raw TCP), NOT HTTP. Standard HTTP_PROXY / HTTPS_PROXY environment variables do NOT work for Telethon connections. You must pass a proxy parameter explicitly to TelegramClient().

Step-by-Step Setup

1. Verify proxy is a mixed-port (supports SOCKS5)

Mihomo/Clash mixed-port supports both HTTP and SOCKS5 on the same port:

# Check config
grep "mixed-port" /home/openclaw/clash/config/config.yaml
# Output: mixed-port: 7890

2. Patch Telethon client creation

Find where TelegramClient() is instantiated (usually main.py) and add proxy:

import os
try:
    import socks
    HAS_SOCKS = True
except ImportError:
    HAS_SOCKS = False

# Parse proxy from env
proxy_config = None
proxy_addr = os.getenv('HTTP_PROXY') or os.getenv('http_proxy')
if proxy_addr and HAS_SOCKS:
    import re
    m = re.match(r'https?://([\d.]+):(\d+)', proxy_addr)
    if m:
        proxy_config = (socks.SOCKS5, m.group(1), int(m.group(2)))

# Pass to TelegramClient
user_client = TelegramClient('./sessions/user', api_id, api_hash, proxy=proxy_config)
bot_client = TelegramClient('./sessions/bot', api_id, api_hash, proxy=proxy_config)

3. Docker setup with network_mode: host

Docker containers can't reach 127.0.0.1:7890 on the host by default. Use network_mode: host:

# docker-compose.yml
services:
  telegram-forwarder:
    build:
      context: .
      dockerfile: Dockerfile.custom
    container_name: telegram-forwarder
    restart: unless-stopped
    network_mode: host          # Required for 127.0.0.1 proxy access
    environment:
      - HTTP_PROXY=http://127.0.0.1:7890
      - HTTPS_PROXY=http://127.0.0.1:7890
      - http_proxy=http://127.0.0.1:7890
      - https_proxy=http://127.0.0.1:7890
      - NO_PROXY=localhost,127.0.0.1
    volumes:
      - ./db:/app/db
      - ./.env:/app/.env
      - ./sessions:/app/sessions
      # ... other volumes
    stdin_open: true            # Required for phone verification
    tty: true                   # Required for phone verification

4. Custom Dockerfile (adds PySocks)

FROM heavrnl/telegramforwarder:latest  # or whatever base image
RUN pip install --no-cache-dir PySocks
COPY main.py /app/main.py              # patched version with proxy support

5. Phone verification (first run)

First run requires interactive phone verification:

# Run interactively for first-time auth
docker-compose run --rm telegram-forwarder
# → Enter phone code when prompted
# → Session saved to ./sessions/*.session

Use terminal(background=true, pty=true) and process(action='submit') to handle verification code input.

Pitfall: Verification codes expire FAST (~30 seconds). Agent-based submission via process(action='submit') is unreliable due to latency — the code often expires before the agent can submit it. Recommend user SSH directly and run docker-compose run --rm telegram-forwarder themselves for the verification step.

Pitfall: If 2FA is enabled, Telethon will prompt for password AFTER the code. User needs to enter their Telegram two-step verification password (set in TG Settings → Privacy & Security → Two-Step Verification). If forgotten, it can be reset but requires a 7-day wait.

Pitfall: If code expires, clean session files and restart:

rm -f ./sessions/*.session ./sessions/*.session-journal
docker-compose run --rm telegram-forwarder

6. After verification, run as daemon

docker-compose up -d
docker-compose logs -f

Pitfalls

  • HTTP_PROXY alone does NOT work for Telethon — Telethon uses raw TCP (MTProto), not HTTP. Must pass proxy=(socks.SOCKS5, host, port) to TelegramClient().
  • PySocks must be installed — add to Dockerfile if not in base image's requirements.
  • network_mode: host is required for 127.0.0.1 proxy access. Without it, the container can't reach the host's Mihomo. Alternative: use extra_hosts: ["host.docker.internal:host-gateway"] and change proxy to host.docker.internal:7890.
  • Session database lock — if previous run crashed, *.session files may be locked. Delete them before retrying.
  • Don't use same bot token as Hermes — the forwarder bot needs its own BotFather token. Using the same token causes conflicts.
  • Verification code timeout — Telegram codes expire in ~30s. The interactive Docker session may time out if user is slow to respond. Have the code ready before starting.

Reference: Heavrnl/TelegramForwarder

Best full-featured Telegram forwarder (1144+ stars):

  • Repo: https://github.com/Heavrnl/TelegramForwarder
  • Features: /bind command, keyword filtering, regex replace, AI processing, RSS, multi-platform push
  • Commands: /bind, /settings, /add, /replace, /list_keyword, etc.
  • Docker image: heavrnl/telegramforwarder:latest

Server Context

  • Server: Linux (NYC), no direct route to Telegram servers
  • Proxy: Mihomo at 127.0.0.1:7890 (mixed-port, SOCKS5 + HTTP)
  • Telegram API creds in ~/.bashrc: TG_API_ID, TG_API_HASH
  • User prefers Chinese UI/commands