Skip to content

bigbag/temprix

Repository files navigation

Temprix

CI Go Version license

Self-hosted scheduling tool for booking meetings. Simple alternative to Calendly with Google Calendar integration.

Features

  • Meeting types - Create multiple meeting types with configurable duration, buffers, and daily limits
  • Weekly availability - Set recurring availability per day of week
  • Google Calendar sync - Automatic free/busy check and event creation
  • Public booking links - Share /book/{slug} URLs for each meeting type
  • Guest timezone selection - Guests see times in their timezone
  • Calendar export - .ics file download after booking
  • Simple admin UI - Server-rendered HTML, no JavaScript framework

Quick Start

  1. Set up Google OAuth credentials (see Configuration)

  2. Set environment variables:

export TEMPRIX_ENCRYPTION_SECRET="your-32-character-secret-key!!"
export TEMPRIX_GOOGLE_CLIENT_ID="your-client-id.apps.googleusercontent.com"
export TEMPRIX_GOOGLE_CLIENT_SECRET="your-client-secret"
  1. Run the server:
make build
./bin/temprix
  1. Visit http://localhost:8080/admin and login with Google

Installation

# Clone the repository
git clone https://github.com/bigbag/temprix.git
cd temprix

# Build
make build

# Or install to GOPATH/bin
make install

Docker

# Build image
make docker-build

# Run container
docker run -d \
  -p 8080:8080 \
  -v temprix-data:/app/data \
  -e TEMPRIX_BASE_URL=https://your-domain.com \
  -e TEMPRIX_ENCRYPTION_SECRET=your-32-character-secret-key!! \
  -e TEMPRIX_GOOGLE_CLIENT_ID=your-client-id \
  -e TEMPRIX_GOOGLE_CLIENT_SECRET=your-client-secret \
  temprix

Configuration

Environment Variables

Required:

  • TEMPRIX_ENCRYPTION_SECRET - 32+ character secret for token encryption
  • TEMPRIX_GOOGLE_CLIENT_ID - Google OAuth Client ID
  • TEMPRIX_GOOGLE_CLIENT_SECRET - Google OAuth Client Secret

Optional:

  • TEMPRIX_PORT - Server port (default: 8080)
  • TEMPRIX_BASE_URL - Public URL for OAuth callback and booking links (default: http://localhost:8080)
  • TEMPRIX_DB_PATH - SQLite database path (default: ./data/temprix.db)

Google OAuth Setup

  1. Go to Google Cloud Console
  2. Create a new project or select existing one
  3. Enable the Google Calendar API
  4. Go to Credentials > Create Credentials > OAuth 2.0 Client ID
  5. Set Application type to Web application
  6. Add authorized redirect URI: http://localhost:8080/auth/callback (or your production URL)
  7. Note the Client ID and Client Secret

Adding Test Users

New OAuth apps are in "Testing" mode and require adding test users before they can login:

  1. Go to Google Cloud Console
  2. Select your project
  3. Go to APIs & Services > OAuth consent screen > Audience
  4. In the Test users section, click + Add users
  5. Add your email address
  6. Save

You can add up to 100 test users in testing mode. For production use with any Google account, submit for Google verification (requires privacy policy, terms of service, etc.).

Architecture

+------------------+     +------------------+     +------------------+
|   Public User    |     |    Admin User    |     |  Google Calendar |
+--------+---------+     +--------+---------+     +--------+---------+
         |                        |                        ^
         | /book/{slug}           | /admin                 |
         v                        v                        |
+--------------------------------------------------+       |
|                  Temprix Server                  |       |
|                                                  |       |
|  +-------------+  +-------------+  +-----------+ |       |
|  |  Handlers   |  |    Auth     |  | Calendar  |-+-------+
|  |             |  | (Google     |  |  (Event   |
|  | - Admin     |  |  OAuth)     |  |  create,  |
|  | - Booking   |  |             |  |  free/    |
|  | - Auth      |  +-------------+  |  busy)    |
|  +------+------+                   +-----------+
|         |                                        |
|         v                                        |
|  +-------------+  +-------------+  +-----------+ |
|  | Availability|  |   Models    |  |    ICS    | |
|  |   Engine    |  |             |  | Generator | |
|  |             |  | - Meeting   |  |           | |
|  | - Slots     |  | - Booking   |  | - RFC5545 | |
|  | - Filters   |  | - User      |  |           | |
|  +------+------+  +-------------+  +-----------+ |
|         |                                        |
|         v                                        |
|  +----------------------------------------------+|
|  |              SQLite Database                 ||
|  |                                              ||
|  |  - meeting_types  - bookings  - users        ||
|  +----------------------------------------------+|
+--------------------------------------------------+

How It Works

Admin Flow

  1. Visit /admin - redirected to Google OAuth
  2. After login, see dashboard with meeting types
  3. Create meeting types with name, duration, buffers, schedule
  4. View and manage bookings

Booking Flow

  1. Guest visits /book/{slug} (e.g., /book/30min-call)
  2. Selects their timezone
  3. Picks a date - available time slots are shown
  4. Selects a time slot
  5. Enters name and email
  6. Confirms booking - event created in your Google Calendar
  7. Downloads .ics file to add to their calendar

Availability Calculation

  1. Get weekly schedule for the meeting type
  2. Generate all possible slots for selected date
  3. Query Google Calendar free/busy API
  4. Remove slots that conflict with existing events
  5. Remove slots that conflict with existing bookings
  6. Check max bookings per day limit
  7. Apply buffer times (before/after)
  8. Return available slots

Technical Details

Database Schema

SQLite stores all data:

CREATE TABLE users (
    id TEXT PRIMARY KEY,
    google_id TEXT UNIQUE NOT NULL,
    email TEXT NOT NULL,
    access_token TEXT NOT NULL,      -- AES-GCM encrypted
    refresh_token TEXT NOT NULL,     -- AES-GCM encrypted
    calendar_id TEXT DEFAULT 'primary'
);

CREATE TABLE meeting_types (
    id TEXT PRIMARY KEY,
    slug TEXT UNIQUE NOT NULL,       -- URL-friendly identifier
    name TEXT NOT NULL,
    description TEXT,
    duration_minutes INTEGER NOT NULL,
    buffer_before_minutes INTEGER DEFAULT 0,
    buffer_after_minutes INTEGER DEFAULT 0,
    max_per_day INTEGER DEFAULT 0,   -- 0 = unlimited
    meeting_link TEXT,               -- manual Zoom/Meet link
    timezone TEXT NOT NULL,
    weekly_schedule TEXT NOT NULL,   -- JSON: {"mon": [{"start": "09:00", "end": "17:00"}]}
    active INTEGER DEFAULT 1
);

CREATE TABLE bookings (
    id TEXT PRIMARY KEY,
    meeting_type_id TEXT NOT NULL,
    guest_name TEXT NOT NULL,
    guest_email TEXT NOT NULL,
    start_time DATETIME NOT NULL,    -- stored in UTC
    end_time DATETIME NOT NULL,
    guest_timezone TEXT NOT NULL,
    google_event_id TEXT,
    status TEXT DEFAULT 'confirmed'  -- confirmed, cancelled
);

Token Encryption

Google OAuth tokens are encrypted at rest using AES-256-GCM:

  • 32-byte key derived from TEMPRIX_ENCRYPTION_SECRET
  • Random 12-byte nonce per encryption
  • Base64 encoded for storage

Timezone Handling

  • Meeting type timezone: used to interpret weekly schedule
  • Guest timezone: for display in booking UI
  • Storage: all times stored in UTC
  • Conversion: handled at display time using Go's time.LoadLocation

Project Structure

temprix/
├── main.go                    # Entry point, routes
├── internal/
│   ├── config/config.go       # Environment variable loading
│   ├── db/
│   │   ├── db.go              # SQLite connection, migrations
│   │   └── queries.go         # All SQL operations
│   ├── models/models.go       # Data structures
│   ├── auth/google.go         # OAuth flow, token encryption
│   ├── calendar/google.go     # Calendar API wrapper
│   ├── availability/slots.go  # Slot calculation
│   ├── handlers/handlers.go   # HTTP handlers
│   └── ics/generator.go       # .ics file generation
├── templates/
│   ├── admin/                 # Admin UI templates
│   └── booking/               # Public booking templates
├── static/style.css           # Styling
├── Dockerfile
├── Makefile
└── README.md

Make Commands

make build       # Build binary to bin/temprix
make test        # Run tests
make clean       # Remove build artifacts
make install     # Install to GOPATH/bin
make tidy        # Tidy Go modules
make vet         # Run go vet
make run         # Build and run
make build-all   # Build for linux/darwin amd64/arm64
make docker-build # Build Docker image
make docker-run  # Run Docker container

License

MIT License - see LICENSE file.

About

Self-hosted scheduling tool for booking meetings. Simple Calendly alternative with Google Calendar integration, public booking links, and timezone support.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Contributors