Skip to content

Repository files navigation

Python uv Ruff Pyright Tests License

Clocky-Fill

Calendar → Clockify · Google Calendar · Microsoft 365/Outlook · free, no paid APIs


Sync your calendar events to Clockify time entries automatically. Supports Google Calendar (ICS link), Microsoft 365/Outlook (Microsoft Graph API with device code auth), and any ICS-compatible calendar.


Supported sources

Source Auth What you need
Google Calendar ICS private link The "Secret iCal address" from Calendar settings
Microsoft 365 / Outlook Device code OAuth An Azure AD app registration (client ID only)
Any ICS calendar ICS URL A public or private ICS link

Quick Start

git clone <repo-url> clocky-fill && cd clocky-fill
uv sync

# Configure
cp config.example.json config.json
cp project_map.example.csv project_map.csv

# Dry-run to preview
uv run clocky --date 2026-07-16 --dry-run

# Run for real
uv run clocky --date 2026-07-16

# Use Microsoft Graph
uv run clocky --source microsoft --date 2026-07-16 --dry-run

Configuration

config.json

Field Required Description
clockify_api_key Your Clockify API key
workspace_id Clockify workspace ID
default_project_id Fallback project when no rule matches
timezone IANA timezone (default: America/Mexico_City)
source ics, microsoft, or auto (default: ics)
ics_url for ICS Private ICS link from Google/Outlook
ms_client_id for Microsoft Azure AD app registration client ID

Security: config.json is in .gitignore — never commit your real keys.

Microsoft Graph Setup

  1. Register an app in Azure AD:
    • Supported account types: "Accounts in any organizational directory"
    • Redirect URI: http://localhost (not used, but required)
    • API permissions: Calendars.Read (delegated)
  2. Under Authentication, enable: "Allow public client flows" → Yes
  3. Copy the Application (client) ID → put it in config.json as ms_client_id
  4. On first run, a browser will open for device code authentication. The token is cached in ~/.clocky_fill_ms_token.json (0600 permissions).

project_map.csv

Column Description
match_type contains (substring) or exact
pattern Text to match in the event title
project_id Clockify project ID (leave blank if skip=true)
skip true → never sync, report for manual entry

Rules are evaluated in order — the first match wins. Unmatched events fall to default_project_id.

Where to find your IDs

What Where
API key Clockify → Profile Settings → API
Workspace ID URL: app.clockify.me/workspaces/<ID>/...
Project IDs GET /workspaces/<ID>/projects with X-Api-Key header
ICS URL Google Calendar → Settings → calendar → "Secret iCal address"

CLI Reference

uv run clocky [OPTIONS]
Flag Description
--date YYYY-MM-DD Single day (default: today)
--from YYYY-MM-DD Start of date range
--to YYYY-MM-DD End of date range
--dry-run Preview without creating entries
--source {ics,microsoft,auto} Calendar source (default: auto)
--config PATH Custom config path
--map PATH Custom map path
--log PATH Custom log path
-v, --verbose Show debug output

Automation

Cron (Linux/macOS)

0 23 * * * cd /path/to/clocky-fill && UV_LINK_MODE=copy /path/to/uv run clocky >> sync.log 2>&1

Task Scheduler (Windows)

  • Program: uv
  • Arguments: run clocky
  • Start in: project folder

Architecture

clocky_fill/
├── __init__.py              # package metadata (v0.3.0)
├── cli.py                   # argparse + rich UI
├── config.py                # Config dataclass + validation
├── sync.py                  # orchestration: fetch → match → create
├── project_map.py           # CSV rule loading + event→project matching
├── clockify.py              # Clockify REST API client
├── log.py                   # synced_log.json persistence (dedup)
├── calendar.py              # compatibility re-exports
└── providers/
    ├── __init__.py           # CalendarProvider ABC + CalendarEvent
    ├── ics.py                # ICSCalendarProvider (Google, Outlook ICS, …)
    └── microsoft.py          # MicrosoftGraphProvider (device-code OAuth2)

tests/
├── conftest.py               # shared fixtures
├── test_config.py            # config validation tests
├── test_project_map.py       # CSV loading + matching tests
├── test_clockify.py          # Clockify API client tests
├── test_log.py               # synced_log persistence tests
├── test_sync.py              # orchestration tests
├── test_providers_ics.py     # ICS provider tests
└── test_providers_microsoft.py  # Microsoft Graph provider tests

Dev Commands

uv run ruff check clocky_fill/ tests/   # lint
uv run ruff format clocky_fill/ tests/  # format
uv run pyright clocky_fill/             # type-check
uv run pytest tests/ -v                 # run tests (41/41)
uv run pytest tests/ --cov=clocky_fill  # with coverage

Notes

  • All-day events are skipped (Clockify handles them differently).
  • Recurring events are expanded automatically (ICS provider).
  • synced_log.json prevents duplicate entries across multiple runs.
  • No paid APIs: Google Calendar ICS is free, Clockify API is free on all plans, and Microsoft Graph API with Calendars.Read is free.

License

MIT

About

Sync calendar events (Google Calendar / Microsoft 365 / Outlook ICS) to Clockify time entries automatically. Free, no paid APIs.

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages