Install
openclaw skills install x-bookmark-triageAutomatically triages X/Twitter bookmarks into structured knowledge cards and posts them to a Discord channel (#knowledge-intake or similar). Captures tweet content via fxtwitter, scores relevance using Claude Haiku, assigns tier (1–10), freshness (evergreen/dated/expired), and topic tags, then optionally unbookmarks after capture. Includes a scheduled poll for new bookmarks, a one-time backlog sweep, and a manual drop handler. Use when: (1) setting up automated bookmark → knowledge card pipeline, (2) draining an existing bookmark backlog, (3) dropping a URL manually for immediate triage, (4) packaging this as a publishable skill for other OpenClaw users. Requires X OAuth 2.0 User Context with bookmark.read scope (+ bookmark.write to unbookmark). Triggers on: "triage my bookmarks", "set up bookmark pipeline", "drain bookmark backlog", "x-bookmark-triage", "knowledge intake".
openclaw skills install x-bookmark-triageTurns X/Twitter bookmarks into searchable, tiered knowledge cards posted to a Discord channel. Captures, scores, and optionally unbookmarks — so your bookmark list stays clean and your knowledge base grows automatically.
Works standalone — no OpenClaw required for core triage. OpenClaw integration is optional (adds scheduled polling via cron and bus events). See
references/adapting.mdfor standalone setup.
X Bookmarks
│
├── Scheduled poll (2×/day) → bookmark-poll.js
├── Backlog sweep (one-time) → backlog-sweep.js
└── Manual drop (on mention) → poll-channel.js (launchd poller)
│
▼
triage-url.js (fetch → Claude Haiku → card)
│
▼
Discord #knowledge-intake (structured card)
│
▼
X API DELETE /bookmarks/:id (unbookmark)
| Requirement | Notes |
|---|---|
| X OAuth 2.0 app | developer.x.com — Free tier works |
| Scopes | bookmark.read (required) + bookmark.write (for unbookmark) |
| Discord bot token | Needs Send Messages permission in target channel |
| Anthropic API key | ANTHROPIC_DEFAULT_KEY env var |
| Node.js 18+ | Scripts use spawnSync, no npm deps |
Get credentials:
references/oauth-setup.md for step-by-step.Send Messages permission in your target channel.Run auth flow: node scripts/x-oauth2-authorize.js → saves refresh token to data/x-oauth2-token-cache.json
Set env vars: Export X_OAUTH2_CLIENT_ID, X_OAUTH2_CLIENT_SECRET, X_OAUTH2_REFRESH_TOKEN, DISCORD_BOT_TOKEN, ANTHROPIC_DEFAULT_KEY
Set your Discord channel: Set env var KNOWLEDGE_INTAKE_CHANNEL_ID=<your-channel-id> (preferred), OR edit scripts/triage-url.js line 19 to hardcode it.
Test triage: node scripts/triage-url.js https://x.com/@username/status/1234567890 --source "manual drop"
Check Discord: You should see a formatted card in your channel
Verify dedup: Run the command again — should skip (already seen)
Done: Your first card is live. Next: set up scheduling (see Steps 3–4 below)
# Run the interactive auth flow
node scripts/x-oauth2-authorize.js
# → Opens browser, captures callback, saves to data/x-oauth2-token-cache.json
Store credentials in your gateway plist (or env):
X_OAUTH2_CLIENT_ID — app OAuth 2.0 client ID
X_OAUTH2_CLIENT_SECRET — app OAuth 2.0 client secret
X_OAUTH2_REFRESH_TOKEN — from auth flow (auto-rotated by scripts)
The scripts also fall back to reading refresh_token from a secrets JSON file at runtime. See references/oauth-setup.md for full details.
Set CHANNEL_ID at the top of scripts/triage-url.js to your Discord channel ID.
# Register a cron job (9 AM + 5 PM daily)
# In OpenClaw: cron add — see references/cron-setup.md
# You can also run manually: node scripts/bookmark-poll.js
Alternatively, drain all bookmarks one-time:
node scripts/backlog-sweep.js --delay 3
Note: scripts/ai.watson.knowledge-intake-poll.plist is a template. Customize it first:
/PATH/TO/skills/x-bookmark-triage/scripts/poll-channel.js with the actual pathYOUR_BOT_TOKEN, YOUR_ANTHROPIC_KEY, YOUR_CHANNEL_ID, /PATH/TO/workspace with real values# After customizing the plist:
cp scripts/ai.watson.knowledge-intake-poll.plist ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/ai.watson.knowledge-intake-poll.plist
Or use OpenClaw to manage it — see references/cron-setup.md.
triage-url.js — Core triage enginenode scripts/triage-url.js <url> [--source "bookmark poll"|"manual drop"|"backlog sweep"]
data/knowledge-intake-seen.jsonbookmark-poll.js — Scheduled sweep (latest 20)node scripts/bookmark-poll.js
triage-url.js for each unseen URLbookmark_sweep_complete to busbacklog-sweep.js — One-time full drainnode scripts/backlog-sweep.js [--dry-run] [--limit 50] [--delay 3] [--no-unbookmark]
--dry-run: list URLs without triaging or unbookmarking--limit N: stop after N bookmarks--delay N: seconds between triage calls (default: 3)backlog_sweep_complete to buspoll-channel.js — Discord drop handlernode scripts/poll-channel.js
# Or via wrapper: bash scripts/run-poll.sh
triage-url.js for each unseen URLTier 3–10 (work-relevant):
🗂️ **Title** @handle
• The Miracle: what's new/impressive
• Why it matters: connection to your work
• Key Features: [list]
• Proposed Action: specific next step
• Tier: 🥈 Tier 2 — Worth tracking (7/10) — relevance summary
• Freshness: 🌿 evergreen | Topic: #ai
• Tags: #tool #infra
• Link: <url>
Tier 1–2 (off-topic/personal):
📌 **Title** @handle — one-liner summary #personal <url>
| Tier | Label | Meaning |
|---|---|---|
| 9–10 | 🥇 Act now | Implement this week |
| 7–8 | 🥈 Worth tracking | Thread + investigate soon |
| 5–6 | 🥉 Knowledge doc | Revisit in a sprint |
| 3–4 | 📌 Low priority | Interesting, not actionable |
| 1–2 | 📌 Off-topic | Personal/entertainment — one-liner only |
evergreen 🌿 — timeless, still valid in 2 yearsdated 📅 — relevant but will age (benchmarks, roadmaps)expired ⏰ — time-sensitive, likely already stale#ai · #veefriends · #product · #revenue · #openclaw · #personal · #x-strategy
Each triage call: ~3.5K avg input + 300 output tokens (claude-haiku-4-5)
URLs are tracked in data/knowledge-intake-seen.json. Cap: 2,000 entries (FIFO). Bookmarks already in the seen cache are still unbookmarked — they were captured in a prior run.
X rotates refresh tokens on each use. The scripts:
data/x-oauth2-new-refresh-token.txtWatson auto-detects and updates the secrets file. For non-Watson deployments, monitor for this warning and update X_OAUTH2_REFRESH_TOKEN in your env.
references/oauth-setup.md — Full OAuth 2.0 setup walkthroughreferences/cron-setup.md — OpenClaw cron registration for scheduled pollsreferences/adapting.md — How to adapt channel IDs, topics, triage prompt for your workspace