X Bookmark Triage
Automatically triages X/Twitter bookmarks into structured knowledge cards and posts them to a Discord channel (#knowledge-intake or similar). Captures tweet...
Description
name: x-bookmark-triage description: > Automatically 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".
x-bookmark-triage
Turns 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.
Architecture
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)
Prerequisites
| 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 |
Quick Start (8-step MVP)
-
Get credentials:
- X OAuth 2.0 app: Create at developer.x.com — Free tier. See
references/oauth-setup.mdfor step-by-step. - Discord bot token: Create at discord.com/developers — Bot needs
Send Messagespermission in your target channel. - Anthropic API key: From console.anthropic.com
- X OAuth 2.0 app: Create at developer.x.com — Free tier. See
-
Run auth flow:
node scripts/x-oauth2-authorize.js→ saves refresh token todata/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 editscripts/triage-url.jsline 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)
Setup
1. OAuth 2.0 Authorization
# 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.
2. Configure Target Channel
Set CHANNEL_ID at the top of scripts/triage-url.js to your Discord channel ID.
3. Register the Scheduled Poll (Optional — for automated polling)
# 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
4. Register the launchd Poller (Optional — for automated polling)
Note: scripts/ai.watson.knowledge-intake-poll.plist is a template. Customize it first:
- Edit the file to replace
/PATH/TO/skills/x-bookmark-triage/scripts/poll-channel.jswith the actual path - Replace
YOUR_BOT_TOKEN,YOUR_ANTHROPIC_KEY,YOUR_CHANNEL_ID,/PATH/TO/workspacewith real values - Copy to LaunchAgents and load:
# 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.
Scripts
triage-url.js — Core triage engine
node scripts/triage-url.js <url> [--source "bookmark poll"|"manual drop"|"backlog sweep"]
- Fetches content (fxtwitter for tweets, markdown.new for web pages)
- Triages with Claude Haiku → produces tier, freshness, topic, tags, proposed action
- Posts formatted card to Discord
- Marks URL as seen in
data/knowledge-intake-seen.json - Exits 0 on success or "already seen"; exits 1 on hard failure
bookmark-poll.js — Scheduled sweep (latest 20)
node scripts/bookmark-poll.js
- Refreshes OAuth token, fetches 20 most recent bookmarks
- Calls
triage-url.jsfor each unseen URL - Unbookmarks after successful triage (+ already-seen items)
- Emits
bookmark_sweep_completeto bus
backlog-sweep.js — One-time full drain
node scripts/backlog-sweep.js [--dry-run] [--limit 50] [--delay 3] [--no-unbookmark]
- Pages through ALL bookmarks (up to API limit)
--dry-run: list URLs without triaging or unbookmarking--limit N: stop after N bookmarks--delay N: seconds between triage calls (default: 3)- Emits
backlog_sweep_completeto bus
poll-channel.js — Discord drop handler
node scripts/poll-channel.js
# Or via wrapper: bash scripts/run-poll.sh
- Polls a Discord channel every 2 min for new messages
- Extracts URLs from message content
- Calls
triage-url.jsfor each unseen URL - Intended to run as a persistent launchd service
Card Format
Tier 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 Guide
| 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 |
Freshness Values
evergreen🌿 — timeless, still valid in 2 yearsdated📅 — relevant but will age (benchmarks, roadmaps)expired⏰ — time-sensitive, likely already stale
Topic Values (one per card)
#ai · #veefriends · #product · #revenue · #openclaw · #personal · #x-strategy
Token / Cost Estimate
Each triage call: ~3.5K avg input + 300 output tokens (claude-haiku-4-5)
- Per URL: ~$0.003
- 20 new bookmarks/run: ~$0.06
- 2 runs/day at typical throughput: ~$3.60/month
- Full 1000-bookmark backlog: ~$3.50
Seen-URL Deduplication
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.
Refresh Token Rotation
X rotates refresh tokens on each use. The scripts:
- Detect rotation (new token in response)
- Save new token to
data/x-oauth2-new-refresh-token.txt - Log a warning to update the plist env var
Watson 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
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
Reviews (0)
No reviews yet. Be the first to review!
Comments (0)
No comments yet. Be the first to share your thoughts!