Auto-read articles from daily.dev using Playwright with cookie-based authentication, with Telegram notifications and reading-streak tracking.
- ✅ Reads 2-4 random articles per run
- ✅ Skips promoted/ad articles (detects "Promoted" label)
- ✅ Human-like reading simulation (scrolling, random pauses)
- ✅ Clicks through "Read post" to open and read the external article too
- ✅ Cookie-based authentication (no login required)
- ✅ Auth verification — decodes the session JWT to confirm you're actually logged in before reading
- ✅ Auto-refreshes cookies — persists the browser's refreshed session back to
user-cookie.jsonafter every run - ✅ Reading streak tracking — reports streak before/after each run
- ✅ Telegram notifications for run start, completion, and auth failures
- ✅ Detailed logging with loguru
- Python 3.12+
- uv package manager
# Install dependencies
uv sync
# Install Playwright browsers
uv run playwright install chromium- Login to daily.dev in your browser
- Export cookies using a browser extension (e.g., "Cookie Editor")
- Save the exported cookies as
user-cookie.jsonin the project root
Cookies are automatically refreshed and re-saved to user-cookie.json after each run, so re-exporting is only needed if the session actually expires (auth failures are reported via Telegram).
- Copy
.env.exampleto.env - Create a bot with @BotFather and get the bot token
- Get your chat ID (e.g. via @userinfobot)
- Fill in
TELEGRAM_BOT_TOKEN,TELEGRAM_CHAT_ID, and optionallyTELEGRAM_THREAD_IDin.env
If left unconfigured, the script runs normally and just skips notifications.
# Run the auto reader
uv run python main.pyrun.sh is a cron-ready wrapper that cds into the project, runs it with uv (falling back to the local .venv), and appends output to cron.log. Update PROJECT_DIR in run.sh to match your deployment path, then add it to crontab, e.g.:
0 9,15,20 * * * /path/to/daily-dev-auto-reader/run.shEdit the constants in main.py to customize behavior:
| Setting | Default | Description |
|---|---|---|
MIN_ARTICLES |
2 | Minimum articles to read per run |
MAX_ARTICLES |
4 | Maximum articles to read per run |
READ_TIME_MIN |
15s | Minimum time spent "reading" each article |
READ_TIME_MAX |
40s | Maximum time spent "reading" each article |
SCROLL_PAUSE_MIN |
1.0s | Minimum pause between scroll actions |
SCROLL_PAUSE_MAX |
3.0s | Maximum pause between scroll actions |
FEED_LOAD_WAIT |
5s | Wait time after navigating to the feed |
EXTERNAL_READ_WAIT |
20s | Time spent on the external article opened via "Read post" |
Note: the browser currently launches with headless=False (visible window) — set headless=True in main.py if running on a headless server.
- Launch Chromium browser and load cookies for authentication
- Navigate to the daily.dev feed and verify the session is actually authenticated (decodes the
da3JWT cookie) - Capture the current reading streak
- Scroll through the feed to load articles
- Collect article links (filtering out promoted/ad content)
- Randomly select 2-4 articles and read each one with human-like scroll behavior, following "Read post" through to the external article when available
- Return to the feed and capture the reading streak again
- Persist the refreshed session cookies back to
user-cookie.json - Report results (articles read, streak change, duration) via logs and Telegram