diff --git a/app/services/platforms/reddit_comment.py b/app/services/platforms/reddit_comment.py index 62794f1..6135233 100644 --- a/app/services/platforms/reddit_comment.py +++ b/app/services/platforms/reddit_comment.py @@ -134,8 +134,8 @@ class RedditCommentStrategy(PostingStrategy): client = RedditClient(session_file=session_file) comment_url = client.comment(thread_id=thread_id, body=body) - # Reddit comment() may return empty URL; reconstruct from thread_id - if not comment_url: + # Reddit comment() may return bare domain or empty; reconstruct from thread_id + if not comment_url or comment_url.rstrip("/") in ("https://reddit.com", "https://www.reddit.com"): comment_url = f"https://www.reddit.com/r/{target}/comments/{thread_id}/" return PostResult(url=comment_url, metadata={"thread_id": thread_id}) diff --git a/app/services/reddit/client.py b/app/services/reddit/client.py index 37015cf..5ebff9a 100644 --- a/app/services/reddit/client.py +++ b/app/services/reddit/client.py @@ -24,7 +24,7 @@ USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64) Chrome/124.0.0.0" class RedditClient: def __init__(self, session_file: Path | None = None) -> None: settings = get_settings() - self._session_file = session_file or Path(settings.reddit_session_file) + self._session_file = Path(session_file) if session_file else Path(settings.reddit_session_file) ensure_valid_session(self._session_file) self.cookies = load_cookies(self._session_file) self.headers = {"User-Agent": USER_AGENT} @@ -43,43 +43,36 @@ class RedditClient: return self._modhash def post(self, sub: str, title: str, body: str, flair: str | None = None) -> str: - """Submit a text post via Playwright (xvfb-run). Returns the permalink.""" - settings = get_settings() - cmd = [ - "xvfb-run", "--auto-servernum", - sys.executable, str(_POST_SCRIPT), - "--sub", sub, - "--title", title, - "--body", body, - "--yes", - ] - if flair: - cmd += ["--flair", flair] - - result = subprocess.run( - cmd, - capture_output=True, - text=True, - timeout=180, - env={ - **__import__("os").environ, - "REDDIT_SESSION_FILE": str(self._session_file), - }, + """Submit a text post via Reddit legacy API (httpx). Returns the permalink.""" + data = { + "api_type": "json", + "kind": "self", + "sr": sub, + "title": title, + "text": body, + "uh": self.modhash, + "sendreplies": "true", + "nsfw": "false", + "spoiler": "false", + } + resp = httpx.post( + "https://www.reddit.com/api/submit", + cookies=self.cookies, + headers=self.headers, + data=data, + timeout=30, ) - if result.returncode != 0: + resp.raise_for_status() + result = resp.json() + errors = result.get("json", {}).get("errors", []) + if errors: + raise RuntimeError(f"Post to r/{sub} failed: {errors}") + url = result.get("json", {}).get("data", {}).get("url", "") + if not url: raise RuntimeError( - f"Post to r/{sub} failed (exit {result.returncode}):\n" - f"STDOUT:\n{result.stdout}\n" - f"STDERR:\n{result.stderr}" + f"Post to r/{sub} may have failed — no URL in response:\n{result}" ) - for line in result.stdout.splitlines(): - if line.startswith("Posted:"): - url = line.split("Posted:", 1)[-1].strip() - return url - raise RuntimeError( - f"Post to r/{sub} may have failed — no 'Posted:' line in output.\n" - f"Full stdout:\n{result.stdout}" - ) + return url def comment(self, thread_id: str, body: str) -> str: """Post a top-level comment to a thread. Returns the permalink."""