Kudosy automatically gives kudos on Strava to activities in your following feed β based on configurable distance and duration rules, with human-like random timing so it doesn't look like a bot.
β οΈ Strava Terms of Service notice: Kudosy authenticates using your personal_strava4_sessionbrowser cookie (web session), not the official Strava API/OAuth. This is a personal/educational tool β use it responsibly. Keep the scheduler interval generous and rely on the built-in delays and jitter to stay under the radar. You are solely responsible for compliance with Strava's ToS.
- π€ β π§ Human-like timing β randomised interval jitter, per-kudos delays, shuffled send order, and automatic backoff on Strava rate limits (HTTP 429) or repeated send failures
- βοΈ Web UI β four tabs (Feed, Configuration, Statistics, Status & Log) in five languages (DE/EN/FR/ES/IT), with light/dark theme (system default + manual override)
- π§© Flexible rules β catch-all, per-category and per-sport-type distance/duration thresholds, activity-name regex overrides, per-athlete allow/deny lists
- π Scheduler β configurable interval + jitter, quiet-hours matrix (7Γ24, drag-to-paint, timezone-aware), enable/disable, dry-run mode
- π‘ Live feed view β see your following feed with per-activity kudo decisions and reasons, send single kudos manually, filter by status/sport/text
- π Statistics β run history with charts and per-sport aggregations
- π Notifications β webhook alerts (ntfy, Slack, Discord, Gotify or generic HTTP) on runs, auth errors, and as a daily digest
- πͺ΅ Live log β the log tab streams run output in real time via Server-Sent Events
- β¬οΈ Update check β footer hint when a newer release is available (optional, max. 1 check/12 h)
- πΎ Backup β export/import config + settings as JSON (session cookie excluded from exports)
- π³ Docker-first β single
docker compose upto run, multi-arch images on GHCR - π§ͺ Test-driven β β₯85% test coverage, pure functions tested in isolation
# Clone the repo
git clone https://github.com/bin101/kudosy.git
cd kudosy
# Copy the example config and fill in your cookie + athlete ID
cp data/config.example.yaml data/config.yaml
$EDITOR data/config.yaml
# Start
docker compose up -d
# Open http://localhost:8080python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
KUDOSY_DATA_DIR=./data KUDOSY_PORT=8080 python -m kudosy- Log in to strava.com in your browser.
- Open DevTools β Application β Cookies β
https://www.strava.com. - Copy the value of
_strava4_session. - Paste it into
data/config.yamlasstravaSessionCookie, or enter it in the web UI.
The cookie expires β if Kudosy suddenly stops finding activities, refresh it here.
All config lives in ./data/ (mounted as /data in Docker):
| File | Purpose |
|---|---|
config.yaml |
Your session cookie, athlete ID, allow/deny lists, catch-all + per-sport rules |
settings.json |
Scheduler interval, jitter, delays, quiet-hours matrix, notifications, dry-run flag |
athlete-labels.json |
Cached athlete ID β name lookups |
athlete-avatars.json |
Cached athlete ID β avatar URL lookups |
kudoed-activities.json |
Already-kudoed activity IDs (skip cache across runs) |
activity-cache.json |
Last parsed feed snapshot (survives restarts) |
run-history.json |
Compact per-run history entries (feeds the Statistics tab) |
last-digest.json |
Timestamp of the last daily-digest notification |
last-run.log |
Output of the most recent run |
A legacy defaults.yaml (from older versions) is automatically migrated into config.yaml
on first boot and renamed to defaults.yaml.migrated.
See data/config.example.yaml for a fully annotated example.
Kudosy has several layers of randomness and restraint to avoid a detectable machine pattern:
- Interval jitter: each scheduled run fires after
intervalMinutes Β± jitterMinutes(uniform random). Default: 60 Β± 15 minutes. - Per-kudos delay: between each individual kudo POST, Kudosy waits a random duration in
[minKudosDelaySeconds, maxKudosDelaySeconds]. Default: 3β25 seconds. - Shuffle order: the list of activities to kudo can be shuffled randomly before sending.
- Quiet hours: the 7Γ24 schedule matrix restricts kudos to allowed weekday/hour slots in your timezone.
- Rate-limit backoff: on HTTP 429 (or three consecutive failed sends) the remaining kudos of the run are skipped; the next scheduled run retries naturally.
All timing parameters are configurable in the web UI on the Configuration tab.
Pre-built multi-arch images (amd64 + arm64) are published to GitHub Container Registry:
docker pull ghcr.io/bin101/kudosy:latestTags: latest (from main), vX.Y.Z (releases), X.Y (minor), commit SHA.
# Install
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
# TDD cycle: write tests first, then implementation
pytest tests/unit/ # pure functions (fast)
pytest --cov=kudosy --cov-report=term-missing
# Lint & type-check
ruff check src tests
ruff format --check src tests
mypy srcSee CLAUDE.md for the full architecture guide.
Semantic Versioning via pyproject.toml. Releases are driven by
Conventional Commits and automated with
release-please.
See CHANGELOG.md for release history.
MIT β see LICENSE.