Skip to main content

Twitter aggregator for market-relevant signals

Project description

twag 📊

Twitter/X market-signal aggregation with LLM-powered triage, enrichment, and digest generation.

twag pulls tweets from your timeline, scores them for market relevance using LLMs, enriches high-signal content, and generates daily digests. It's designed for traders and investors who want signal without the noise.

Example telegram notification. Chart emojis are links to tweets that have charts:

telegram-cloud-photo-size-1-4911387561196981374-x

Features

  • Smart Scoring — LLM-powered triage (0-10) with category tagging
  • Full-Text Search — SQLite FTS5 with boolean queries and filters
  • X Article Summaries — Extracts key points and action items from long-form posts
  • Telegram Alerts — Real-time notifications for high-signal tweets
  • Web Feed — FastAPI + React UI for browsing processed tweets
  • OpenClaw Skill — Native integration with OpenClaw agents

Prerequisites

bird CLI (Required)

twag uses bird to access Twitter/X. Install it first:

# npm (recommended)
npm install -g @steipete/bird

# or pnpm/bun
pnpm add -g @steipete/bird
bun add -g @steipete/bird

# or Homebrew (macOS)
brew install steipete/tap/bird

Verify installation:

bird --version

Twitter Authentication

bird uses cookie-based auth. You need two cookies from your browser:

  1. AUTH_TOKEN — Your auth_token cookie
  2. CT0 — Your ct0 cookie

Getting Your Cookies

  1. Log into x.com in your browser
  2. Open DevTools (F12) → Application → Cookies → https://x.com
  3. Copy the values of auth_token and ct0

Set them as environment variables:

export AUTH_TOKEN="your_auth_token_here"
export CT0="your_ct0_here"

Or add to ~/.env (twag will source this automatically):

echo 'export AUTH_TOKEN="..."' >> ~/.env
echo 'export CT0="..."' >> ~/.env

Verify auth works:

bird whoami

LLM API Keys

Required:

Optional:

  • ANTHROPIC_API_KEY — For higher-quality enrichment on high-signal tweets
export GEMINI_API_KEY="your_gemini_key"
export ANTHROPIC_API_KEY="your_anthropic_key"  # optional

Installation

From PyPI (Recommended)

pip install twag

From Source

git clone https://github.com/clifton/twag.git
cd twag
pip install -e .

Using uv

uv pip install twag
# or from source
uv pip install -e .

Quick Start

# 1. Initialize config and database
twag init

# 2. Verify dependencies and environment
twag doctor

# 3. Fetch tweets from your timeline
twag fetch

# 4. Score and process tweets
twag process

# 5. Generate today's digest
twag digest --stdout

# 6. Search for specific topics
twag search "fed rate" --today

Core Workflow

FETCH → PROCESS → DIGEST
  1. Fetch — Pull tweets from home timeline, tier-1 accounts, bookmarks
  2. Process — Score tweets with LLM, categorize, enrich high-signal content
  3. Digest — Generate markdown summaries grouped by theme

CLI Reference

Setup Commands

twag init              # Initialize config and database
twag init --force      # Overwrite existing config file
twag doctor            # Check dependencies and environment

Fetch Commands

# Default: home timeline + tier-1 accounts + bookmarks
twag fetch

# Single tweet (ID or URL)
twag fetch 1234567890123456789
twag fetch https://x.com/user/status/1234567890123456789

# User timeline
twag fetch --source user --handle @NickTimiraos --count 50

# Search
twag fetch --source search --query "Fed Powell rate" --count 30

# Control sources
twag fetch --no-tier1 --no-bookmarks

# Tier-1 rotation and pacing
twag fetch --stagger 5          # Only fetch 5 least-recent tier-1 accounts
twag fetch --delay 5.0          # 5s delay between tier-1 fetches (default: 3s)

Process Commands

twag process                    # Process unscored tweets (no alerts by default)
twag process --limit 100        # Limit batch size
twag process --dry-run          # Preview only
twag process --notify           # Send Telegram alerts

# Quote/reply reprocessing
twag process --no-reprocess-quotes       # Skip reprocessing dependency tweets
twag process --reprocess-min-score 5     # Min score for reprocessing (default: 3)

# Process specific tweet
twag process 1234567890123456789

Search Commands

# Basic search
twag search "inflation fed"

# With filters
twag search "rate hike" --category fed_policy
twag search "NVDA" --author zerohedge
twag search "earnings" --ticker AAPL

# Time filters
twag search "breaking" --today              # Since last market close
twag search "fed" --time 7d                 # Last 7 days
twag search "macro" --since 2026-01-15      # From specific date

# Output formats
twag search "fed" --format brief            # Compact output
twag search "fed" --format full             # Digest-style
twag search "fed" --format json             # JSON output

# Score threshold
twag search "market" --min-score 7          # High-signal only

# Additional filters
twag search --bookmarks                     # Only bookmarked tweets
twag search "fed" --tier 1                  # Filter by signal tier
twag search "fed" --order score             # Sort by: rank, score, or time

Query syntax:

  • Simple: inflation fed (matches both)
  • Phrase: "rate hike" (exact match)
  • Boolean: inflation AND fed, fed NOT fomc
  • Prefix: infla* (wildcard)

Narrative Commands

twag narratives list            # List active narratives with mention counts

Analyze Commands

twag analyze 1234567890123456789              # Analyze by ID
twag analyze https://x.com/user/status/123    # Analyze by URL
twag analyze 1234567890123456789 --reprocess  # Force re-analyze
twag analyze 1234567890123456789 -m gemini-2.0-flash  # Override model

Digest Commands

twag digest                     # Generate today's digest
twag digest --date 2026-02-06   # Specific date
twag digest --stdout            # Output to terminal
twag digest --min-score 6       # Custom threshold

Account Management

twag accounts list              # All tracked accounts
twag accounts list --tier 1     # Tier-1 only
twag accounts add @handle       # Add account
twag accounts add @handle -t 1  # Add as tier-1
twag accounts promote @handle   # Promote to tier-1
twag accounts demote @handle    # Demote to tier-2
twag accounts mute @handle      # Mute account
twag accounts boost @handle --amount 10  # Boost weight
twag accounts decay             # Apply daily decay
twag accounts import            # Import from following.txt

Stats & Maintenance

twag stats                      # All-time stats
twag stats --today              # Today's stats

twag prune --days 14            # Delete old tweets
twag prune --dry-run            # Preview prune

twag export --days 7            # Export recent data

Narratives

twag narratives list            # List active narratives

Database Commands

twag db path                    # Show database location
twag db shell                   # Open SQLite shell
twag db init                    # Initialize/reset database
twag db rebuild-fts             # Rebuild search index
twag db dump                    # Backup database (auto-named file)
twag db dump --stdout           # Backup to stdout
twag db restore backup.sql      # Restore from backup
twag db restore backup.sql --force  # Restore without confirmation

Web Interface

twag web                        # Start web UI (localhost:5173)
twag web --host 127.0.0.1       # Bind to localhost only
twag web --port 8080            # Custom port
twag web --dev                  # Dev mode (Vite + hot reload)
twag web --no-reload            # Disable auto-reload on code changes

⚠️ Security: The web interface has no authentication. Only run on trusted networks or bind to localhost.

Configuration

twag config show                # Show current config
twag config path                # Show config file path
twag config set llm.triage_model gemini-2.0-flash
twag config set scoring.alert_threshold 8

Data Paths

twag follows XDG defaults:

Path Purpose
~/.config/twag/config.json Configuration
~/.local/share/twag/twag.db SQLite database
~/.local/share/twag/digests/ Generated digests
~/.local/share/twag/following.txt Followed accounts

Override with TWAG_DATA_DIR environment variable.

Scoring System

Tweets are scored 0-10:

Score Signal Level Behavior
8-10 Alert Telegram alert (if configured)
7 High signal Enriched, included in digests
5-6 Market relevant Included in digests
3-4 News/context Searchable, not in digests
0-2 Noise Stored but filtered out

Categories

fed_policy, inflation, job_market, macro_data, earnings, equities, rates_fx, credit, banks, consumer_spending, capex, commodities, energy, metals_mining, geopolitical, sanctions, tech_business, ai_advancement, crypto, noise

Automation

Data Collection (systemd timer)

Create ~/.config/systemd/user/twag-aggregator.service:

[Unit]
Description=TWAG Twitter Aggregator
After=network.target

[Service]
Type=oneshot
ExecStart=%h/.local/bin/twag fetch && %h/.local/bin/twag process
WorkingDirectory=%h
EnvironmentFile=%h/.env

Create ~/.config/systemd/user/twag-aggregator.timer:

[Unit]
Description=Run TWAG every 15 minutes

[Timer]
OnBootSec=5min
OnUnitActiveSec=15min
Persistent=true

[Install]
WantedBy=timers.target

Enable:

systemctl --user daemon-reload
systemctl --user enable --now twag-aggregator.timer

macOS (launchd)

See SUGGESTED_CRON_SCHEDULE.md for launchd plist examples.

Telegram Alerts

  1. Create a bot via @BotFather
  2. Get your chat ID by messaging the bot
  3. Set environment variables:
export TELEGRAM_BOT_TOKEN="your_bot_token"
export TELEGRAM_CHAT_ID="your_chat_id"

Tweets scoring 8+ will trigger alerts when you run twag process --notify.

OpenClaw Integration

twag is an OpenClaw skill. Once installed, agents can:

# Search for market-relevant tweets
twag search "fed rate" --today -s 7

# Generate digests
twag digest --stdout

# Analyze specific tweets
twag analyze https://x.com/user/status/123

Skill Installation

The skill is auto-discovered if twag is in PATH. For manual setup:

# Link skill to OpenClaw
ln -s /path/to/twag ~/.openclaw/skills/twag

Scheduled Digests

See SUGGESTED_CRON_SCHEDULE.md for OpenClaw cron job examples that deliver digests to Telegram.

Environment Variables

Variable Required Purpose
AUTH_TOKEN Yes Twitter auth cookie
CT0 Yes Twitter ct0 cookie
GEMINI_API_KEY Yes LLM triage/vision
ANTHROPIC_API_KEY No Enhanced enrichment
TELEGRAM_BOT_TOKEN No Alert delivery
TELEGRAM_CHAT_ID No Alert destination
TWAG_DATA_DIR No Override data directory

Troubleshooting

"bird not found"

# Check if bird is installed
which bird

# Install if missing
npm install -g @steipete/bird

"Authentication failed" / 401 errors

# Verify cookies are set
echo $AUTH_TOKEN
echo $CT0

# Test bird auth
bird whoami

# If expired, get fresh cookies from browser

"Query IDs stale" / 404 errors

# Refresh GraphQL query cache
bird query-ids --fresh

"GEMINI_API_KEY not set"

# Verify key is exported
echo $GEMINI_API_KEY

# Test with curl
curl "https://generativelanguage.googleapis.com/v1/models?key=$GEMINI_API_KEY"

Database issues

# Check database location
twag db path

# Rebuild search index
twag db rebuild-fts

# Backup and restore
twag db dump backup.sql
twag db restore backup.sql --force

Development

# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Lint and format
ruff check .
ruff format .

# Frontend development
cd twag/web/frontend
npm install
npm run dev

License

MIT. See LICENSE.

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

twag-0.1.31.tar.gz (335.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

twag-0.1.31-py3-none-any.whl (204.8 kB view details)

Uploaded Python 3

File details

Details for the file twag-0.1.31.tar.gz.

File metadata

  • Download URL: twag-0.1.31.tar.gz
  • Upload date:
  • Size: 335.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for twag-0.1.31.tar.gz
Algorithm Hash digest
SHA256 2618e4d2febabcf3b5ab5b6a50b42956aa348af64f24087c335b448a52250a05
MD5 dd1b6e7f71d6c8d0968b1d515926edb7
BLAKE2b-256 784adfc48820761145c7f52aaee8b572b4554577530645b0e02a7b0ba6168e4a

See more details on using hashes here.

File details

Details for the file twag-0.1.31-py3-none-any.whl.

File metadata

  • Download URL: twag-0.1.31-py3-none-any.whl
  • Upload date:
  • Size: 204.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for twag-0.1.31-py3-none-any.whl
Algorithm Hash digest
SHA256 22b9728d8a56ad76e96d37c6508a730a7aa951d0ec861022d9019e636e93eee9
MD5 51d5c37f5bc7a3e9edd919ebc14e6ab1
BLAKE2b-256 e4d83a7a26fe7c392c6ce8943265cf8be42b1a7f57c51326f6bee6d5ab503cfe

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page