mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-16 23:01:06 +02:00
Comments load over a signed /api/comment/list XHR that TikTok serves to anonymous sessions once the comments panel is opened (unlike profile-video and general-search feeds), so this is a reliable verb. Given video URLs it returns CommentItems (text, author, likes, reply counts; replies carry repliesToId), deduped per video, capped, and degraded to an ErrorItem for empty/withheld videos or a bad_url ErrorItem for non-video inputs. Generalizes the browser capture over a pluggable interaction step so the comments flow (open panel, scroll the panel to paginate) reuses the same warm+capture scaffolding as listing/user-search. Billed per comment on a new TIKTOK_COMMENT meter (TIKTOK_MICROS_PER_COMMENT, matching the per-comment market), surfaced on the chat subagent alongside tiktok.scrape/user_search.
36 lines
1.2 KiB
Python
36 lines
1.2 KiB
Python
"""``tiktok.comments`` executor: video URLs -> scraper -> TikTok comment items."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from collections.abc import Awaitable, Callable
|
|
|
|
from app.capabilities.core import Executor
|
|
from app.capabilities.core.progress import emit_progress
|
|
from app.capabilities.tiktok.comments.schemas import CommentsInput, CommentsOutput
|
|
from app.proprietary.platforms.tiktok import scrape_tiktok_comments
|
|
|
|
CommentsFn = Callable[..., Awaitable[list[dict]]]
|
|
|
|
|
|
def build_comments_executor(comments_fn: CommentsFn | None = None) -> Executor:
|
|
"""Bind the executor to a comments fn (defaults to the proprietary actor)."""
|
|
comments_fn = comments_fn or scrape_tiktok_comments
|
|
|
|
async def execute(payload: CommentsInput) -> CommentsOutput:
|
|
emit_progress(
|
|
"starting",
|
|
"Scraping TikTok comments",
|
|
total=payload.max_items,
|
|
unit="item",
|
|
)
|
|
items = await comments_fn(
|
|
payload.video_urls,
|
|
per_video=payload.comments_per_video,
|
|
limit=payload.max_items,
|
|
)
|
|
emit_progress(
|
|
"done", f"Scraped {len(items)} comment(s)", current=len(items), unit="item"
|
|
)
|
|
return CommentsOutput(items=items)
|
|
|
|
return execute
|