Autonomous Twitter/X bookmark processor with AI-powered triage, enrichment, and Notion sync.
┌─────────────────────────────────────────────────────────────────────────────┐
│ GRABBER │
│ Autonomous Bookmark Processing Pipeline │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ PHASE 1: FETCH │
│ Bird CLI → Bookmarks → Check if processed → Queue for analysis │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ PHASE 2: TRIAGE (Agent decides autonomously) │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Gemini 3.0 Flash → Structured Output │ │
│ │ • needsArticleScrape: [{url, reason, priority}] │ │
│ │ • needsYoutubeTranscript: [{url, reason}] │ │
│ │ • needsImageAnalysis: [{url, expectedContent}] │ │
│ │ • needsThreadExpansion: boolean │ │
│ │ • estimatedValue: high | medium | low | skip │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ PHASE 3: ENRICH (Parallel fetching based on triage) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Scraper │ │ YouTube │ │ Vision AI │ │ Bird CLI │ │
│ │ (Readability)│ │ (yt-dlp) │ │ (Gemini 3) │ │ (threads) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ PHASE 4: ANALYZE (Final analysis with full context) │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Gemini 3.0 Flash → Structured Output │ │
│ │ • category, summary, tldr, keyInsights[] │ │
│ │ • extractedLinks[{url, title, type, description}] │ │
│ │ • tags[], relevanceScore (1-10) │ │
│ │ • actionItems[{action, priority, context}] │ │
│ │ • quotes[], connections[] │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
│
┌───────────────┴───────────────┐
▼ ▼
┌──────────────────────────────────┐ ┌────────────────────────────────────────┐
│ SQLite (internal) │ │ Notion (UI/Database) │
│ • Deduplication │ │ • TL;DR, Summary, Category, Priority │
│ • Weekly stats │ │ • Tags, Relevance Score, Action Items │
│ • Tracking │ │ • Key Insights, Quotes, Links │
└──────────────────────────────────┘ │ • YouTube Transcripts, Article Content│
└────────────────────────────────────────┘
- Fetch: Bird CLI fetches Twitter/X bookmarks every 60s
- Triage: AI autonomously decides what enrichment is needed:
- Should we scrape article content?
- Should we get YouTube transcript?
- Should we analyze images with vision AI?
- Is this worth processing at all?
- Enrich: Based on triage, fetch all context in parallel
- Analyze: With full context, AI produces comprehensive analysis
- Sync: Structured data saved to Notion database
- Notify: Telegram alerts on errors + weekly digest
review- Articles/threads to read latertry- Tools/products to tryknowledge- Info for knowledge basepodcast- Audio contentvideo- Video contentarticle- Blog posts/long-formtool- Dev tools/librariesproject- Ideas/inspiration
- Node.js 20+
birdCLI (brew install steipete/tap/birdornpm i -g @steipete/bird)yt-dlp(optional, for YouTube transcripts)- Firecrawl API key (optional, for article scraping)
- Twitter/X account with bookmarks
- Notion integration token
- Telegram bot (for notifications)
- Google Gemini API key
pnpm install
cp .env.example .env
# Edit .env with your credentials| Variable | Required | Default | Description |
|---|---|---|---|
TWITTER_AUTH_TOKEN |
Yes | - | Twitter auth_token cookie |
TWITTER_CT0 |
Yes | - | Twitter ct0 cookie |
GOOGLE_GENERATIVE_AI_API_KEY |
Yes | - | Gemini API key |
NOTION_TOKEN |
Yes | - | Notion integration secret |
NOTION_PARENT_PAGE_ID |
Yes | - | Page ID where DB will be created |
TELEGRAM_BOT_TOKEN |
Yes | - | Telegram bot token |
TELEGRAM_CHAT_ID |
Yes | - | Chat ID for notifications |
FIRECRAWL_API_KEY |
No | - | Firecrawl API key for article scraping |
FIRST_RUN_LIMIT |
No | 200 |
Bookmarks to fetch on first run |
POLL_INTERVAL_SECONDS |
No | 60 |
Polling interval in seconds |
DB_PATH |
No | ./data/grabber.db |
SQLite database path |
DIGEST_CRON |
No | 0 10 * * 0 |
Weekly digest schedule (Sunday 10:00) |
- Log into X/Twitter in Chrome
- Open DevTools → Application → Cookies
- Copy
auth_tokenandct0values
- Create a Notion integration
- Create a page where the database will live
- Share the page with your integration
- Copy the page ID from the URL
# Development (watch mode)
pnpm dev
# Production
pnpm build
pnpm start
# Docker
docker-compose up -dWraps the bird CLI for Twitter API access:
getBookmarks(limit)- Fetch bookmarksreadTweet(id)- Read single tweetgetThread(id)- Fetch full threadcheckAuth()- Validate credentials
AI analysis using Gemini 2.0 Flash:
analyzeTweet(tweet, options)- Categorize and extract insightsanalyzeImage(url)- Vision analysis for imagesgenerateDigest(stats, highlights)- Weekly summary
YouTube transcript extraction via yt-dlp:
getTranscript(url)- Extract video transcriptgetVideoInfo(url)- Get video metadata
Notion database management:
- Auto-creates "Grabber Bookmarks" database
- Creates structured pages with:
- Category, author, relevance score
- Tags (multi-select)
- Original tweet, summary, quotes
- Extracted links, YouTube transcripts
Notifications:
notifyError(error)- Error alerts with retry statusnotifyAuthExpired()- Cookie expiration warningsendDigest(markdown)- Weekly summary
SQLite persistence (WAL mode):
- Deduplication via tweet ID
- Weekly stats aggregation
- Top tags and highlights extraction
Bird CLI → Bookmarks → [YouTube?] → Gemini Analysis → Notion Page
↓ ↓
SQLite DB Telegram (errors)
↓
Weekly Digest → Telegram
| Error Code | Meaning | Auto-Retry |
|---|---|---|
AUTH_EXPIRED |
Twitter cookies expired | No |
RATE_LIMIT |
Twitter rate limit hit | Yes |
NETWORK |
Network/timeout error | Yes |
NOTION |
Notion API error | Yes |
TELEGRAM |
Telegram send failed | Yes |
pnpm test # Watch mode
pnpm test:run # Single run| Script | Description |
|---|---|
pnpm dev |
Development with hot reload |
pnpm build |
Compile TypeScript |
pnpm start |
Run compiled code |
pnpm typecheck |
Type checking only |
pnpm test |
Run tests (watch) |
pnpm test:run |
Run tests (once) |
# docker-compose.yml
services:
grabber:
build: .
env_file: .env
volumes:
- ./data:/app/data
restart: unless-stoppedMIT