A Playwright-based automation system for syncing LinkedIn messages, executing approved actions, and creating animated social media content.
Built for the AutoSprints AI CEO experiment.
- Message Sync: Pull conversations from LinkedIn into Supabase
- CRM Reconciliation: Auto-link conversations to existing prospects
- Action Execution: Execute approved actions (likes, comments, messages, connection requests)
- Rate Limiting: Built-in daily limits to avoid detection
- Human-like Behavior: Random delays, breaks, and natural interaction patterns
- HTML to GIF: Convert CSS animations directly to GIFs
- No Screen Recording: Automated frame capture using Playwright
- Optimized Output: Palette optimization for smaller file sizes
# Install dependencies
npm install
# Authenticate with LinkedIn (opens browser)
npm run auth
# Sync messages
npm run sync:messages
# Capture an animation to GIF
npm run capture -- docs/example.html -d 10- Setup Guide - Full installation and configuration
- Architecture - Technical design and data flow
- CLAUDE.md - AI assistant context
linkedin-sync/
├── src/
│ ├── index.ts # Main entry, CLI router
│ ├── auth.ts # LinkedIn authentication flow
│ ├── sync-messages.ts # Message sync with safeguards
│ ├── execute-actions.ts # Action execution system
│ └── capture-animation.ts # HTML animation to GIF converter
├── docs/
│ ├── SETUP.md # Setup documentation
│ ├── ARCHITECTURE.md # Technical architecture
│ └── *.html # Animation templates
├── auth/ # Browser state (gitignored)
├── supabase/migrations/ # Database schema
├── Dockerfile # Docker with Xvfb
├── docker-entrypoint.sh # Xvfb startup script
└── .env.example # Environment template
| Command | Description |
|---|---|
npm run auth |
Authenticate with LinkedIn (interactive) |
npm run sync |
Run full sync |
npm run sync:messages |
Sync messages only |
npm run sync:connections |
Sync connection requests |
npm run sync:engagements |
Sync post engagements |
npm run check:status |
Check prospect connection status (Connect/Message/Pending) |
npm run check:status -- --limit 10 |
Check only 10 prospects |
npm run capture -- <html-file> [options]
Options:
-d, --duration Duration in seconds (default: 10)
-f, --fps Frames per second (default: 20)
-w, --width Width in pixels (default: 1080)
-ht, --height Height in pixels (default: 1080)
-o, --output Output file pathSUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=your-anon-key
LINKEDIN_EMAIL=your@email.com # Optional, for auth hintsLinkedIn detects and blocks headless browsers. This tool MUST run with a visible browser window, which means:
- Your Mac must be logged in (not just powered on)
- A Chrome window will pop up briefly during each sync
- Works best when you're at your desk or have the Mac open
This is a LinkedIn anti-bot measure. There's no workaround that doesn't risk account suspension.
-
Authenticate once (session lasts ~7 days):
npm run auth
-
Install the scheduled job:
./scripts/setup-automation.sh
This sets up a launchd job that runs automatically at 9am and 5pm daily.
# View status
launchctl list | grep linkedin
# Run manually now
launchctl start com.autosprints.linkedin-sync
# Stop/disable
launchctl unload ~/Library/LaunchAgents/com.autosprints.linkedin-sync.plist
# Re-enable
launchctl load ~/Library/LaunchAgents/com.autosprints.linkedin-sync.plist
# View logs
tail -f logs/sync.logThe LinkedIn session typically lasts 7 days. If syncs start failing, re-run:
npm run authNo need to reinstall the automation; it will use the new session automatically.
Built-in daily limits to maintain account safety:
| Action | Daily Limit |
|---|---|
| Profile Views | 25 |
| Likes | 30 |
| Comments | 10 |
| Messages | 10 |
| Connection Requests | 10 |
Private - AutoSprints internal tool