feat: initial commit
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 4m50s
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 4m50s
This commit is contained in:
159
bridge_app/config.py
Normal file
159
bridge_app/config.py
Normal file
@@ -0,0 +1,159 @@
|
||||
"""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 <work-dir>/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)
|
||||
Reference in New Issue
Block a user