"""Configuration models and CLI argument parsing for the Max ↔ Telegram bridge.""" from __future__ import annotations import argparse import os from dataclasses import dataclass from pathlib import Path def _parse_bool(value: str) -> bool: normalized = value.strip().lower() if normalized in {"1", "true", "yes", "y", "on"}: return True if normalized in {"0", "false", "no", "n", "off"}: return False raise ValueError(value) @dataclass(slots=True) class Config: max_phone: str max_chat_id: int | None telegram_bot_token: str | None telegram_chat_id: int | None telegram_test_dc: bool max_token: str | None = None max_ws_uri: str | None = None work_dir: str = "./max_session" disable_fake_telemetry: bool = False db_path: str = "" def parse_args() -> tuple[Config, bool, bool]: """Parse CLI arguments and environment variables into a Config.""" parser = argparse.ArgumentParser( description=( "Forward messages from a Max group chat to a Telegram chat. " "Configuration can come from CLI flags or environment variables." ) ) parser.add_argument( "--max-phone", default=os.getenv("MAX_PHONE"), help="Phone number used to authenticate in Max (env: MAX_PHONE)", ) parser.add_argument( "--max-token", default=os.getenv("MAX_TOKEN"), help="Optional auth token for Max session (env: MAX_TOKEN)", ) parser.add_argument( "--max-chat-id", type=int, default=int(os.getenv("MAX_CHAT_ID")) if os.getenv("MAX_CHAT_ID") else None, help="ID of the Max group chat to mirror (env: MAX_CHAT_ID)", ) parser.add_argument( "--max-ws-uri", default=os.getenv("MAX_WS_URI"), help="Override the default Max WebSocket URI (env: MAX_WS_URI)", ) parser.add_argument( "--work-dir", default=os.getenv("MAX_WORKDIR", "./max_session"), help="Directory to store Max session database (env: MAX_WORKDIR)", ) parser.add_argument( "--telegram-bot-token", default=os.getenv("TELEGRAM_BOT_TOKEN"), help="Telegram bot token (env: TELEGRAM_BOT_TOKEN)", ) parser.add_argument( "--telegram-chat-id", type=int, default=( int(os.getenv("TELEGRAM_CHAT_ID")) if os.getenv("TELEGRAM_CHAT_ID") else None ), help="Telegram chat ID that should receive forwarded messages (env: TELEGRAM_CHAT_ID)", ) telegram_test_dc_default = False telegram_test_dc_env = os.getenv("TELEGRAM_TEST_DC") if telegram_test_dc_env is not None: try: telegram_test_dc_default = _parse_bool(telegram_test_dc_env) except ValueError: parser.error( "Invalid boolean value for TELEGRAM_TEST_DC: " f"{telegram_test_dc_env}" ) parser.add_argument( "--telegram-test-dc", dest="telegram_test_dc", action="store_true", help="Use Telegram test data-center for bot (env: TELEGRAM_TEST_DC)", ) parser.add_argument( "--no-telegram-test-dc", dest="telegram_test_dc", action="store_false", help=argparse.SUPPRESS, ) parser.set_defaults(telegram_test_dc=telegram_test_dc_default) parser.add_argument( "--db-path", default=os.getenv("MAX_BRIDGE_DB_PATH"), help=( "Path to SQLite database storing forwarded message mapping " "(env: MAX_BRIDGE_DB_PATH). Defaults to /forwarded_messages.db" ), ) parser.add_argument( "--disable-fake-telemetry", action="store_true", help="Disable sending fake telemetry pings required by the Max client", ) parser.add_argument( "--list-chats", action="store_true", help="List available Max chats and exit without forwarding", ) parser.add_argument( "--debug", action="store_true", help="Enable debug logging", ) args = parser.parse_args() if not args.max_phone: parser.error("--max-phone or MAX_PHONE environment variable is required") if not args.list_chats: missing: list[str] = [] if args.max_chat_id is None: missing.append("--max-chat-id / MAX_CHAT_ID") if not args.telegram_bot_token: missing.append("--telegram-bot-token / TELEGRAM_BOT_TOKEN") if args.telegram_chat_id is None: missing.append("--telegram-chat-id / TELEGRAM_CHAT_ID") if missing: parser.error("Missing required options: " + ", ".join(missing)) db_path = args.db_path or str(Path(args.work_dir) / "forwarded_messages.db") config = Config( max_phone=args.max_phone, max_chat_id=args.max_chat_id, telegram_bot_token=args.telegram_bot_token, telegram_chat_id=args.telegram_chat_id, telegram_test_dc=args.telegram_test_dc, max_token=args.max_token, max_ws_uri=args.max_ws_uri, work_dir=args.work_dir, disable_fake_telemetry=args.disable_fake_telemetry, db_path=db_path, ) return config, bool(args.list_chats), bool(args.debug)