Geen omschrijving

ZiB 6c9dda4ce0 diff: use CalPrice public API in _diff_prices 4 maanden geleden
.githooks b24d6678af Initial commit 4 maanden geleden
docker 624e5c5394 Optimize Dockerfile layer ordering and drop redundant uv sync 4 maanden geleden
room_cal 6c9dda4ce0 diff: use CalPrice public API in _diff_prices 4 maanden geleden
scripts d535e6c0ef Query update 4 maanden geleden
tests 9e728f3193 tests: gate live service-api tests behind ROOM_CAL_LIVE_TESTS=1 4 maanden geleden
.dockerignore b24d6678af Initial commit 4 maanden geleden
.gitignore b24d6678af Initial commit 4 maanden geleden
README.md e640220c65 Update README: booking-2fa baked into refresh-creds, add Vite build step 4 maanden geleden
pyproject.toml 9e728f3193 tests: gate live service-api tests behind ROOM_CAL_LIVE_TESTS=1 4 maanden geleden
uv.lock 0224814b1f New deps 4 maanden geleden

README.md

room-cal

A self-hosted calendar management tool for short-term rental hosts. It syncs pricing, availability, reservations, and discounts between a local CalDAV calendar and external booking platforms (Airbnb, Booking.com). A FastAPI HTTP server exposes the data to a Vue-based web calendar, and a FastMCP server exposes health checks to AI assistants.


Installation

See docker/README.md for container-based deployment (recommended for production).

For local development:

# Install dependencies (requires uv)
uv sync --group dev

# Activate git hooks
git config core.hooksPath .githooks

# Build the Vue frontend (required before running room-api locally)
cd room_cal/vue && npm ci && npm run build

Configuration

Start from room_cal/config.json (the bundled defaults) and place an override at ~/.local/room_cal/config.json (or $ROOM_CAL_DATA_HOME/config.json). Keys are deep-merged — you only need to include what you want to change.

room_cal/config-all.json is a generated file that shows every available config key with its default value. It is kept up to date automatically by the pre-commit hook and is the canonical reference for what can be configured.


Usage

CLI

# Sync reservations, prices, and availability for a date range
uv run room-cal fetch-reservations 2026-07-01 2026-07-31
uv run room-cal fetch-prices       2026-07-01 2026-07-31
uv run room-cal push-prices        2026-07-01 2026-07-31
uv run room-cal fetch-closed       2026-07-01 2026-07-31
uv run room-cal push-closed        2026-07-01 2026-07-31

# Apply discount rules and show a diff
uv run room-cal apply-rules        2026-07-01 2026-07-31
uv run room-cal apply-discounts    2026-07-01 2026-07-31
uv run room-cal diff               2026-07-01 2026-07-31

# Create default prices for dates with no local price set
uv run room-cal fill-prices        2026-07-01 2026-07-31 [--weekday 150] [--weekend 200]

# Fetch an external iCal feed
uv run room-cal fetch-feed         2026-07-01 2026-07-31 --feed-name Fire

# Sync from user calendar; push busy export calendar
uv run room-cal fetch-user-cal     2026-07-01 2026-07-31
uv run room-cal push-busy          2026-07-01 2026-07-31

# Local-only workflows (no service API calls)
uv run room-cal local-sync         2026-07-01 2026-07-31   # feeds + rules + fill + busy
uv run room-cal local-refresh      2026-07-01 2026-07-31   # rewrite all local Room calendar events

API server

uv run room-api

Serves the web calendar at http://localhost:8000 and exposes REST endpoints for all sync operations.


Refreshing credentials (refresh-creds)

Session cookies for Airbnb and Booking.com are obtained via a Playwright browser session and must be periodically refreshed.

uv run refresh-creds [--output=file|stdout|api]

Three output modes are available:

Mode Behaviour
file (default) Writes credentials to airbnb.env and booking.env in $ROOM_CAL_DATA_HOME
stdout Prints credentials to stdout — useful for piping or inspection
api POSTs credentials directly to a running room-api instance

The api mode requires api_url to be set in your config.json:

{
  "api_url": "https://your-room-cal-instance.example.com"
}

Booking.com chat 2FA

Booking.com requires an SMS 2FA challenge before the messaging API will accept outgoing messages. This step is handled automatically as part of every refresh-creds run — no separate command is needed.

If the SMS challenge is triggered, the script polls $ROOM_CAL_DATA_HOME/sms_code.txt for the code. An SMS gateway configured to POST incoming codes to POST /sms/code on the running room-api will supply this automatically.

Set SKIP_CHAT_2FA=1 to bypass the messaging step during a refresh when you know the messaging session is still valid.


Web calendar (calendar.html)

The web calendar provides a month view of all pricing and availability data. Key features:

  • Month navigation — prev/next buttons to move between months
  • Day detail panel — click any day to see its price, discount, reservation, and closed status for each service; prices and discounts are editable inline
  • Sync mode — toggle the sync bar on to see which days have mismatches between local CalDAV and remote platforms; a badge shows the total number of days with issues
  • Per-day sync controls — push (↑) or fetch (↓) prices, closed status, discounts, reservations, and user calendar data for individual days
  • Per-month sync controls — bulk push or fetch prices and closed status for the entire visible month; a Fill button creates default local prices for any missing dates
  • iCal feed blocks — external feed closures (e.g. a fire safety calendar) are shown and can be fetched per day
  • Rule discounts — pipeline-generated discounts are shown alongside manual discounts; mismatches between the rule output and what's on the calendar are surfaced
  • Chat panel — select a reservation to open a message thread; shows guest conversation history and a send field
  • Health indicator — a header button polls GET /health and shows green/amber/red based on CalDAV connectivity and service credential status

Developer notes

Git hooks

The repo includes a pre-commit hook that regenerates room_cal/config-all.json automatically on every commit. After cloning, activate it with:

git config core.hooksPath .githooks

To regenerate the file manually:

uv run python scripts/gen_example_config.py > room_cal/config-all.json

Tests

Store tests run without any live server. Service API and CalDAV tests require live credentials:

uv run --group dev python -m pytest