From f2cfe72d631eb3b5d2a3cabb0257c6681283886b Mon Sep 17 00:00:00 2001 From: Danny Date: Tue, 24 Mar 2026 20:35:05 +0100 Subject: [PATCH] Switch from localtunnel to cloudflared, fix static file serving - Replace localtunnel with cloudflared (no interstitial password page) - Wait for "Registered tunnel connection" before starting bot - Serve index.html at / instead of directory listing - Remove localtunnel npm package build from flake.nix Co-Authored-By: Claude Opus 4.6 (1M context) --- flake.nix | 16 ++-------------- server.py | 7 ++++++- start.py | 19 ++++++++++++------- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/flake.nix b/flake.nix index 78aaba1..eaaa362 100644 --- a/flake.nix +++ b/flake.nix @@ -19,22 +19,10 @@ aiohttp ]); - localtunnel = pkgs.buildNpmPackage { - pname = "localtunnel"; - version = "2.0.2"; - src = pkgs.fetchFromGitHub { - owner = "localtunnel"; - repo = "localtunnel"; - rev = "v2.0.2"; - hash = "sha256-6gEK1VjF25Kbe2drxbxUKDNJGqZ+OXgkulPkAkMR2+k="; - }; - npmDepsHash = "sha256-R9FYkEe93oGF+dR7i1MxwzEW3EM3SasH/B6LLC2CNXM="; - dontNpmBuild = true; - }; in { devShells.default = pkgs.mkShell { - packages = [ pythonEnv localtunnel ]; + packages = [ pythonEnv pkgs.cloudflared ]; shellHook = '' echo "💪 BigBiggerBiggestBot dev shell" echo " Run: python start.py (server + tunnel + bot)" @@ -46,7 +34,7 @@ apps.default = { type = "app"; program = toString (pkgs.writeShellScript "run-fitness-bot" '' - export PATH="${pkgs.lib.makeBinPath [ pythonEnv localtunnel ]}:$PATH" + export PATH="${pkgs.lib.makeBinPath [ pythonEnv pkgs.cloudflared ]}:$PATH" exec ${pythonEnv}/bin/python "$PWD/start.py" ''); }; diff --git a/server.py b/server.py index 10623a1..963ea78 100644 --- a/server.py +++ b/server.py @@ -202,7 +202,12 @@ def create_app() -> web.Application: # Serve the webapp/ folder import pathlib webapp_dir = pathlib.Path(__file__).parent / "webapp" - app.router.add_static("/", webapp_dir, show_index=True) + + async def index_handler(request): + return web.FileResponse(webapp_dir / "index.html") + + app.router.add_get("/", index_handler) + app.router.add_static("/", webapp_dir) return app diff --git a/start.py b/start.py index d507858..37cc268 100644 --- a/start.py +++ b/start.py @@ -62,13 +62,14 @@ def start_server(port: int, bot_token: str) -> subprocess.Popen: def start_tunnel(port: int) -> tuple[subprocess.Popen, str]: print(f" Starting tunnel to port {port}...") proc = subprocess.Popen( - ["lt", "--port", str(port)], + ["cloudflared", "tunnel", "--url", f"http://localhost:{port}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, ) url = None + connected = False deadline = time.time() + 30 while time.time() < deadline: line = proc.stdout.readline() @@ -78,16 +79,20 @@ def start_tunnel(port: int) -> tuple[subprocess.Popen, str]: break continue line = line.strip() - print(f" [tunnel] {line}") - match = re.search(r"https?://\S+", line) - if match: - url = match.group(0) + if line: + print(f" [tunnel] {line}") + if not url: + match = re.search(r"https://\S+\.trycloudflare\.com", line) + if match: + url = match.group(0) + if "Registered tunnel connection" in line: + connected = True break - if not url: + if not url or not connected: proc.kill() print("\n Could not get a tunnel URL.") - print(" Make sure localtunnel is working: lt --port 8080\n") + print(" Make sure cloudflared is installed: cloudflared tunnel --url http://localhost:8080\n") sys.exit(1) return proc, url