A service that reads events from a Google Sheet and publishes them as an ICS calendar feed that syncs with Apple Calendar, Google Calendar, and other calendar apps.
Environment variables:
PORT: Server port (default: 8080)BASE_URL: Base URL for calendar links (default: http://localhost:8080)SHEET_RANGE: Sheet range to read (default: Events!A:H)TEMPLATE_COPY_URL: URL to Google Sheets template copy link (sample)
- B1: Timezone (IANA name, e.g., Europe/Helsinki)
- A: Event name (required)
- B: Date (required) - e.g., 2026-01-10 or 10.01.2026
- C: Time (optional) - e.g., 14:00 (defaults to 09:00)
- D: Duration (optional) - e.g., 60, 90m, 1:30 (defaults to 60m)
- E: Recurring (optional) - daily, weekly, biweekly, monthly, none
- F: End Date (optional) - for recurring events (inclusive, end-of-day local)
- G: Address (optional) - event location
- H: Description (optional) - event details
GET /- Index pagePOST /- Verify sheet and generate calendar linkGET /cal/{sheetId}.ics- Calendar feed (cached 55 seconds)
# Build the application
go build -o calendar ./cmd/main.go
# Run locally
PORT=8080 BASE_URL=http://localhost:8080 ./calendar
# Or use environment variables for production
PORT=3000 BASE_URL=https://yourdomain.com TEMPLATE_COPY_URL=https://... ./calendarComprehensive unit tests with mocks provide 82.4%+ coverage of core logic.
# Run all tests
go test ./internal/...
# Run tests with verbose output
go test -v ./internal/...
# Run tests with coverage report
go test -cover ./internal/...
# Run specific package tests
go test -v ./internal/app
go test -v ./internal/utils
go test -v ./internal/sheet
# Detect race conditions
go test -race ./internal/...
# Run with coverage percentage by function
go test -coverprofile=coverage.out ./internal/...
go tool cover -html=coverage.out