12 KiB
name, description
| name | description |
|---|---|
| xiaohongshu-reply-notifications | Automatically handle unreplied XiaoHongShu (小红书) items in 通知-评论和@ by opening each note detail, collecting full comment context, conditionally liking high-quality comments, and posting contextual replies with strict login gating and online reply-state checks. |
Xiaohongshu Reply Notifications
Workflow
- Confirm login state and account identity.
- Open
通知and switch to评论和@. - Discover all candidate cards and loop through them (newest to oldest).
- Enter each note detail page and determine whether the target is unreplied.
- Evaluate comment quality and conditionally like the target comment.
- Generate contextual reply text with accuracy-confidence gate.
- Verify online replied-state for target thread and apply runtime dedupe.
- Execute reply according to reply mode.
- Verify result and continue until candidates are exhausted or early-exit triggers.
- Return compact batch report and per-item details.
Shared Session Policy
- Use a per-thread Playwright CLI session:
- Auto session policy:
tools/pwderives one Playwright session perCODEX_THREAD_ID(fallback:PLAYWRIGHT_SESSION_OWNERor explicit--session).
- Auto session policy:
- Use
/Users/xd/java/xhs/tools/pwas the only browser entrypoint. - Prefer the default auto session; pass
--session <name>only when explicit isolation is required.
Network Preflight Gate (Required)
- Before running this flow, run:
tools/pw --help
- If it fails with network sandbox signatures (
ENOTFOUND,EAI_AGAIN,ETIMEDOUT,ECONNREFUSED, orregistry.npmjs.orgfetch failure):- rerun the same command with escalation (
sandbox_permissions=require_escalated).
- rerun the same command with escalation (
- Do not continue the notification-reply flow until preflight succeeds.
Quick run:
python3 scripts/run_reply_notifications.py \
--mode safe \
--max-items 10
Batch live run:
python3 scripts/run_reply_notifications.py \
--mode live \
--max-items 20 \
--early-stop-non-actionable 20
Reply-State Truth Source
- Use online thread state as source of truth:
- check target
parent_comment_idin note detail - expand replies with limits
- if your own account reply is visible, mark
already_replied
- check target
- Do not rely on local persisted “already handled” files.
- Runtime dedupe is memory-only for current run:
target_key = note_id|parent_comment_iddedupe_key = note_id|parent_comment_id|reply_hash- only prevents duplicate sends in the same process run.
1) Login Gate (Required)
- Open
https://www.xiaohongshu.comautomatically. - Confirm login by both signals:
- left sidebar has
我 我links to/user/profile/...
- left sidebar has
- If not logged in:
- stop immediately
- tell user to log in first
- do not continue any reply actions in this turn.
2) Enter Notification Scope
- Open
https://www.xiaohongshu.com/notification(or click left sidebar通知). - Confirm URL contains
/notification. - Click
评论和@tab. - Never operate in
赞和收藏or新增关注for this skill.
3) Discover Candidates (All Unreplied Flow)
Goal: process all unreplied items in 评论和@.
Loop behavior:
- Scroll notification list to load more cards.
- Continue while new actionable cards are still discovered.
- Stop when no new cards appear in two consecutive scroll rounds.
- Safety cap:
max_scan_cards = 300per run (to avoid endless scrolling).
Early-exit optimization (newest -> oldest list):
- Because
评论和@is ordered from new to old, allow early stop when old non-actionable cards dominate. - Maintain
consecutive_old_non_actionablecounter; increment when a card is any of:already_repliedskipped_duplicate(runtime dedupe hit)- older than run time window and not actionable
- Reset this counter to
0whenever an actionable unreplied card is found. - Trigger early exit when:
consecutive_old_non_actionable >= 20, or- one full scroll round yields zero actionable cards and all seen cards in that round are old non-actionable cards.
- Always prefer correctness:
- if card time/order looks ambiguous, do not early-exit; continue scanning.
For each discovered card, extract:
- notifier nickname
- event type:
评论了你的笔记/回复了你的评论/在评论中@了你 - notifier text snippet
- your original-comment snippet if shown on card
- card timestamp text
- card thumbnail/content entry for opening note detail.
4) Enter Note Detail And Collect Context (Required Before Reply)
For each candidate card:
- Open the related note detail from notification card thumbnail/content.
- Collect note context:
- note title/main text
- hashtags
- note author nickname
- Collect thread context from detail comments:
- target commenter nickname and comment text
- target comment timestamp (if visible)
- If event is
回复了你的评论:- locate your original comment in the detail thread before generating reply.
- Prefer match by current account profile id from sidebar
我 -> /user/profile/.... - Fallback: match with the original-comment snippet shown in notification card.
- If event is
在评论中@了你:- locate the mentioning comment in detail thread and capture mention sentence.
- Extract target identifiers:
note_idparent_comment_id(the comment being replied to)
Unreplied decision (required):
- Determine whether current account already replied to this target comment thread.
- If already replied:
- mark
already_replied - skip send for this card.
- mark
- If not replied:
- continue normal flow.
Hard rule:
- Do not directly reply from notification-list
回复when detail context is missing. - Reply should be made after detail context is confirmed.
5) Comment Quality And Conditional Like
After detail context is confirmed, evaluate the target comment quality.
Quality is considered satisfied when comment is at least one of:
- specific and relevant to the note topic
- constructive question or useful follow-up
- polite and non-spam interaction
Quality is not_satisfied when comment is primarily:
- meaningless spam / repeated emojis only
- obvious ad diversion
- abusive or provocative without useful content
Like rule (target comment only):
- if quality is
satisfied, click like (赞) on the target comment row once. - if already liked, keep current state and do not toggle off.
- if quality is
not_satisfied, skip like.
Like is independent from reply mode:
safe_modeandlive_modecan both perform this conditional like action.
6) Reply Drafting Rules
- Use short, natural Chinese.
- Prefer one sentence, <= 35 Chinese characters.
- Must be specific to note/comment context, avoid template spam.
- If asked a concrete question and confidence is high, answer directly.
- If context is unclear, ask one short clarifying follow-up.
- Skip and mark
needs_manual_reviewfor toxic/abusive/high-risk content.
Accuracy-confidence gate (required):
- Before finalizing each reply, assign confidence:
high: question intent is clear and answer can be supported by current note/thread context.medium: intent is mostly clear, but some details are uncertain.low: key context is missing/ambiguous, likely to answer inaccurately.
- Default principle:
- if you can answer clearly, answer directly (do not overuse DM handoff).
- If confidence is
medium:- provide a cautious but useful direct answer, avoid absolute claims.
- If confidence is
low:- prefer private-message handoff reply inviting user to DM you.
DM handoff style:
- concise, polite, no over-commitment
- explicitly state you may explain more accurately in private chat
- example templates:
这个细节怕说不准,方便私信我,我给你详细说下。这块情况有点细,私信我一下,我一对一给你回复更准确。我先不乱说,私信我我按你的情况详细答你。
7) Online Replied-State Check And Runtime Dedupe
Before final send in live_mode, compute:
note_id: from note detail URL or note container attribute.parent_comment_id: the comment being replied to (from comment row context/network metadata).reply_hash: SHA-256 of normalized reply text.
Normalization for reply_hash:
- trim leading/trailing spaces
- collapse repeated internal spaces
- normalize full-width/half-width punctuation when possible
- remove leading
回复 xxx :prefix if present
Key format (runtime):
target_key = note_id + \"|\" + parent_comment_iddedupe_key = note_id + \"|\" + parent_comment_id + \"|\" + reply_hash
Online check rule (required):
- For target
parent_comment_id, inspect thread replies in detail page. - If not enough replies are visible, click expand controls:
展开/更多/查看回复/全部回复(with limits).
- Limits:
max_expand_rounds(default8)max_scan_replies(default200)max_expand_seconds(default20)
- Decision:
already_replied: my reply is visible in thread -> skip send.not_replied: checked within limits and no my reply found -> continue.unknown: cannot determine confidently -> markneeds_manual_review, skip auto-send.
Runtime dedupe rule:
- In current run only:
- if
target_keyordedupe_keyalready seen, markskipped_duplicate. - otherwise continue.
- if
8) Reply Execution
- In note detail comments, click the target comment row's
回复. - Confirm bottom editor shows
回复 <nickname>and quoted context. - Type the generated reply.
- Reply mode:
safe_mode(default): do not click final发送; keep as draft/plan only.live_mode: click发送.- When user request is explicit batch intent such as
自动回复所有未回复, treat this aslive_mode.
9) Verify Success (live_mode)
At least one must be observed:
评论成功toast appears, or- new reply appears in thread, or
- editor exits reply state and send button resets.
If verification fails:
- mark this item as
sent_unknown - do not auto-retry automatically in current run.
10) Reliability And Recovery
- Re-snapshot after every major step:
- tab switch
- note-detail open/close
- reply-mode change
- On click interception/stale refs:
- wait briefly
- snapshot again
- retry once
- If detail overlay blocks notification operations:
- close detail first, then continue next card.
11) Return Report (Batch)
Return compact structured results per processed item:
- note url/title
- note_id
- parent_comment_id
- dedupe_key
- event type
- notifier nickname
- notifier comment
- your original comment (if applicable)
- comment_quality (
satisfiedornot_satisfied) - liked (
yes,no,already_liked,like_failed) - generated reply text
- mode (
safe_modeorlive_mode) - status (
replied,already_replied,planned,skipped_duplicate,needs_manual_review,sent_unknown,failed) - failure reason if any
Return batch summary:
- total cards scanned
- actionable cards
- unreplied cards detected
- replies sent
- already-replied skipped
- duplicate skipped
- failed count
Boundaries
- Do not send private messages, follow/unfollow, or modify account settings.
- Do not like unrelated comments; only like the current target comment when quality is
satisfied. - Do not mass-reply with repeated text.
- In
safe_mode, never click final send. - Stop and notify user if login state is lost or safety/risk prompts appear.
- Do not bypass online replied-state check when state is
unknown.
Script
scripts/run_reply_notifications.py- End-to-end runner with strict login gate,
评论和@scanning, note-detail context extraction, online replied-state checks with expand limits, runtime dedupe, conditional like, and safe/live reply modes. - Exit codes:
0: flow completed (including no-actionable cases)1: execution failure2: not logged in (requires user login and rerun)
- End-to-end runner with strict login gate,