diff --git a/README.md b/README.md index a9c3ce4..76624fa 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,9 @@ OverUB is a modular Telegram userbot built around a plugin-first architecture. - `qr` (QR login) - `sms` (force SMS code) 5. Optional: set `bot.session_string` or `OVERUB_SESSION_STRING` to use a Telethon StringSession +6. Optional: import Telegram Desktop session: + - `pip install opentele` + - `python scripts/import-tdata.py --tdata /path/to/tdata` ## CLI - `python -m __main__ create-plugin ` diff --git a/scripts/import-tdata.py b/scripts/import-tdata.py new file mode 100644 index 0000000..3d190d4 --- /dev/null +++ b/scripts/import-tdata.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 +""" +Import Telegram Desktop tdata into a Telethon StringSession. +Requires `opentele` (pip install opentele). +""" + +import argparse +import asyncio +import os +from pathlib import Path + +from telethon.sessions import StringSession + + +def load_env() -> None: + if not os.path.exists(".env"): + return + with open(".env", "r", encoding="utf-8") as handle: + for line in handle: + line = line.strip() + if not line or line.startswith("#") or "=" not in line: + continue + key, value = line.split("=", 1) + os.environ.setdefault(key.strip(), value.strip().strip('"').strip("'")) + + +def find_tdata_path() -> Path: + candidates = [ + Path.home() / ".local" / "share" / "TelegramDesktop" / "tdata", + Path.home() / "AppData" / "Roaming" / "Telegram Desktop" / "tdata", + Path.home() / "Library" / "Application Support" / "Telegram Desktop" / "tdata", + ] + for candidate in candidates: + if candidate.exists(): + return candidate + return candidates[0] + + +async def import_tdata(args: argparse.Namespace) -> None: + load_env() + api_id = args.api_id or os.getenv("OVERUB_API_ID") or os.getenv("API_ID") + api_hash = args.api_hash or os.getenv("OVERUB_API_HASH") or os.getenv("API_HASH") + if not api_id or not api_hash: + print("API_ID/API_HASH required (set in .env or pass --api-id/--api-hash).") + return + try: + api_id = int(api_id) + except ValueError: + print("API_ID must be an integer") + return + + tdata = Path(args.tdata or find_tdata_path()) + if not tdata.exists(): + print(f"tdata not found: {tdata}") + return + + try: + from opentele.td import TDesktop # type: ignore + except Exception: + try: + from opentele import TDesktop # type: ignore + except Exception as exc: + print("opentele not installed. Install with: pip install opentele") + print(f"Import error: {exc}") + return + + client = None + td = TDesktop(str(tdata)) + if hasattr(td, "to_telethon"): + try: + client = td.to_telethon(session=StringSession(), api_id=api_id, api_hash=api_hash) + except TypeError: + client = td.to_telethon(StringSession(), api_id, api_hash) + if client is None: + try: + from opentele.tl import TelegramClient as OTClient # type: ignore + except Exception: + print("Unsupported opentele version. Try upgrading opentele.") + return + client = OTClient(td, api_id, api_hash) + + await client.connect() + session_string = client.session.save() + await client.disconnect() + + print("\nSession string:") + print(session_string) + print("\nAdd to .env as OVERUB_SESSION_STRING=" + session_string) + + +def main() -> None: + parser = argparse.ArgumentParser(description="Import Telegram Desktop tdata to Telethon StringSession") + parser.add_argument("--tdata", default="", help="Path to Telegram Desktop tdata directory") + parser.add_argument("--api-id", default="") + parser.add_argument("--api-hash", default="") + args = parser.parse_args() + asyncio.run(import_tdata(args)) + + +if __name__ == "__main__": + main()