- Go 99.4%
- Dockerfile 0.6%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .claude | ||
| .gitignore | ||
| cache.go | ||
| caldav.go | ||
| caldav_test.go | ||
| calendar.go | ||
| calendar_test.go | ||
| Dockerfile | ||
| go.mod | ||
| go.sum | ||
| main.go | ||
| main_test.go | ||
| README.md | ||
| sync.go | ||
| untis.go | ||
| untis_test.go | ||
| untiscal | ||
untiscal
untiscal fetches a WebUntis timetable and exposes it as an ICS calendar feed.
It can also push the next two weeks of events into a CalDAV calendar.
Configuration
The WebUntis settings are required for both the ICS feed and CalDAV sync:
UNTIS_SERVER=example.webuntis.com
UNTIS_SCHOOL=ExampleSchool
UNTIS_USERNAME=...
UNTIS_PASSWORD=...
UNTIS_TIMEZONE=Europe/Berlin
Optional feed/server settings:
LISTEN_ADDR=:8080
CACHE_TTL=5m
FETCH_WEEKS=4
CALENDAR_NAME="Untis Timetable"
TOKEN_SECRET=...
If TOKEN_SECRET is set, requests to the feed must include it as a query
parameter:
http://localhost:8080/feed.ics?token=...
Without TOKEN_SECRET, the feed is available at:
http://localhost:8080/feed.ics
CalDAV Push
Enable CalDAV sync with:
CALDAV_ENABLED=true
CALDAV_URL=https://cal.gametec-live.com/caldav
CALDAV_USERNAME=GameTec_live
CALDAV_PASSWORD=...
CALDAV_CALENDAR=Untis
CALDAV_SYNC_INTERVAL=6h
CALDAV_SKIP_CANCELLED=false
The sync runs once on startup and then repeats every CALDAV_SYNC_INTERVAL.
Each run:
- Fetches WebUntis events from now through the next 14 days.
- Pushes each event to the configured CalDAV calendar using a stable Untis UID.
- Skips cancelled WebUntis events if
CALDAV_SKIP_CANCELLED=true. - Deletes only old Untiscal-created CalDAV events older than 14 days.
- Leaves manually created or non-Untiscal calendar events untouched.
Keep CALDAV_PASSWORD in the runtime environment or secret manager. Do not
commit it to the repository.
Run Locally
export UNTIS_SERVER=example.webuntis.com
export UNTIS_SCHOOL=ExampleSchool
export UNTIS_USERNAME=...
export UNTIS_PASSWORD=...
go run .
With CalDAV enabled:
export CALDAV_ENABLED=true
export CALDAV_URL=https://cal.gametec-live.com/caldav
export CALDAV_USERNAME=GameTec_live
export CALDAV_PASSWORD=...
export CALDAV_CALENDAR=Untis
export CALDAV_SKIP_CANCELLED=true
go run .
Docker
docker build -t untiscal .
docker run --rm -p 8080:8080 \
-e UNTIS_SERVER=example.webuntis.com \
-e UNTIS_SCHOOL=ExampleSchool \
-e UNTIS_USERNAME=... \
-e UNTIS_PASSWORD=... \
-e CALDAV_ENABLED=true \
-e CALDAV_URL=https://cal.gametec-live.com/caldav \
-e CALDAV_USERNAME=GameTec_live \
-e CALDAV_PASSWORD=... \
-e CALDAV_CALENDAR=Untis \
-e CALDAV_SKIP_CANCELLED=true \
untiscal
For RustiCal, use the CalDAV root path /caldav as shown above. If the host
root is configured instead, untiscal will also try RustiCal's standard
/caldav and /caldav-compat discovery paths automatically.
Test
go test ./...