Files
all-by-skill/skills/xiaohongshu-reply-notifications/SKILL.md
T

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

  1. Confirm login state and account identity.
  2. Open 通知 and switch to 评论和@.
  3. Discover all candidate cards and loop through them (newest to oldest).
  4. Enter each note detail page and determine whether the target is unreplied.
  5. Evaluate comment quality and conditionally like the target comment.
  6. Generate contextual reply text with accuracy-confidence gate.
  7. Verify online replied-state for target thread and apply runtime dedupe.
  8. Execute reply according to reply mode.
  9. Verify result and continue until candidates are exhausted or early-exit triggers.
  10. Return compact batch report and per-item details.

Shared Session Policy

  • Use a per-thread Playwright CLI session:
    • Auto session policy: tools/pw derives one Playwright session per CODEX_THREAD_ID (fallback: PLAYWRIGHT_SESSION_OWNER or explicit --session).
  • Use /Users/xd/java/xhs/tools/pw as 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, or registry.npmjs.org fetch failure):
    • rerun the same command with escalation (sandbox_permissions=require_escalated).
  • 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_id in note detail
    • expand replies with limits
    • if your own account reply is visible, mark already_replied
  • Do not rely on local persisted “already handled” files.
  • Runtime dedupe is memory-only for current run:
    • target_key = note_id|parent_comment_id
    • dedupe_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.com automatically.
  • Confirm login by both signals:
    • left sidebar has
    • links to /user/profile/...
  • 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 = 300 per 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_actionable counter; increment when a card is any of:
    • already_replied
    • skipped_duplicate (runtime dedupe hit)
    • older than run time window and not actionable
  • Reset this counter to 0 whenever 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_id
    • parent_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.
  • 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_mode and live_mode can 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_review for 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_id
  • dedupe_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 (default 8)
    • max_scan_replies (default 200)
    • max_expand_seconds (default 20)
  • 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 -> mark needs_manual_review, skip auto-send.

Runtime dedupe rule:

  • In current run only:
    • if target_key or dedupe_key already seen, mark skipped_duplicate.
    • otherwise continue.

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 as live_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 (satisfied or not_satisfied)
  • liked (yes, no, already_liked, like_failed)
  • generated reply text
  • mode (safe_mode or live_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 failure
      • 2: not logged in (requires user login and rerun)