Skip to content

Latest commit

 

History

History
349 lines (287 loc) · 10.4 KB

API_SPEC.md

File metadata and controls

349 lines (287 loc) · 10.4 KB

API & Signaling Protocol Specification — Sabha (सभा)

Document: docs/API_SPEC.md
Status: Approved | Version: 1.0.0


1. REST / Serverless API Endpoints

1.1 Generate LiveKit Access Token

Generates a signed JSON Web Token (JWT) granting access to join a specified LiveKit meeting room with participant permissions.

  • Route: GET /api/livekit-token
  • Location: app/api/livekit-token/route.ts
  • Auth: Public client endpoint; authenticated via server-side LIVEKIT_API_KEY and LIVEKIT_API_SECRET.

Query Parameters

Parameter Type Required Description Example
room string Yes Unique Sabha room identifier sabha-room-402
username string Yes Participant identity / peer ID peer_9x8f2a or User Name
isHost string No Boolean string (true/false) granting room admin grants true

Responses

200 OK

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "wsUrl": "wss://sabha-meet.livekit.cloud"
}

400 Bad Request

{
  "error": "Missing room or username"
}

500 Internal Server Error

{
  "error": "LiveKit credentials are not configured in environment variables"
}

1.2 Record User Login & IP Audit Endpoint

Logs participant login telemetry, public IP address, user agent, and timestamp to Firestore for compliance and forensic auditing.

Request Body

{
  "uid": "google_user_uid_12345",
  "email": "user@example.com",
  "displayName": "Verified User",
  "photoURL": "https://lh3.googleusercontent.com/..."
}

Responses

1.3 Participant Departure & Room Leave Endpoint

Instantaneous participant teardown endpoint invoked during app close, browser termination, navigation, or participant kick actions via navigator.sendBeacon and fetch. Purges participant documents from Firestore and immediately terminates the LiveKit session.

Request Body

{
  "roomId": "sabha-140-802",
  "participantId": "peer_abc123"
}

Responses

200 OK

{
  "success": true
}

2. Real-Time Signaling & Firestore Data Schema

When falling back to P2P Mesh or synchronizing room state, Sabha uses Firestore document collections under the root path /rooms/{roomId}.

2.1 Room State Document

  • Path: /rooms/{roomId}
  • Interface: RoomSettings (lib/types.ts)
{
  roomId: string;             // Unique room slug or uuid
  hostId: string;             // Authenticated Google UID of the room creator
  hostName: string;           // Display name of the host
  title: string;              // e.g. "Sabha Weekly Sync"
  isLocked: boolean;          // If true, new joiners are denied entry
  requireVideo: boolean;      // If true, host mandates all webcams remain active
  allowScreenShare: boolean;  // Host permission toggle for participants
  allowChat: boolean;         // Host permission toggle for participants
  allowUnmute: boolean;       // Host permission toggle for participants
  createdAt: number;          // Unix timestamp (ms)
  endedAt?: number;           // Unix timestamp if room closed
}

2.2 Participant Presence Document

  • Path: /rooms/{roomId}/participants/{peerId}
  • Interface: Participant (lib/types.ts)
{
  id: string;                 // Client peer ID
  uid: string;                // User UID (Firebase Auth or guest ID)
  name: string;               // Display name
  photoURL?: string | null;   // Google profile avatar or null
  isHost: boolean;            // Whether user is room host (सभापति)
  audioEnabled: boolean;      // Mic muted/unmuted state
  videoEnabled: boolean;      // Camera enabled/disabled state
  screenSharing: boolean;     // Screen share status
  isHandRaised: boolean;      // Hand raise queue status
  isMutedByHost: boolean;     // Whether muted by host command
  joinedAt: number;           // Unix timestamp (ms)
}

2.3 Chat Messages Collection

  • Path: /rooms/{roomId}/messages/{messageId}
  • Interface: ChatMessage (lib/types.ts)
{
  id: string;                 // Document ID
  senderId: string;           // Peer ID of the sender
  senderName: string;         // Display name of sender
  senderPhoto?: string | null;// Avatar image URL
  text: string;               // Message text content
  timestamp: number;          // Unix epoch timestamp (ms)
  isSystem?: boolean;         // System event notifications (e.g. joined/left)
  to?: string;                // 'everyone' or target peerId for private DM
}

2.4 Live Reaction Collection

  • Path: /rooms/{roomId}/reactions/{reactionId}
  • Interface: ReactionItem (lib/types.ts)
{
  id: string;                 // Document ID
  emoji: string;              // Emoji character (e.g. "👍", "❤️", "🎉")
  senderId: string;           // Peer ID of sender
  senderName: string;         // Sender display name
  timestamp: number;          // Unix epoch timestamp
}

2.5 WebRTC Signaling Protocol

  • Path: /rooms/{roomId}/signals/{signalId}
  • Interface: SignalData (lib/types.ts)

Used for SDP offer/answer exchanges and host moderator signals when operating in Mesh mode:

{
  from: string;               // Source peer ID
  to: string;                 // Target peer ID or 'broadcast'
  type: 'offer' | 'answer' | 'candidate' | 'mute-command' | 'kick-command';
  payload: any;               // RTCSessionDescriptionInit, RTCIceCandidateInit, etc.
  timestamp: number;          // Unix epoch timestamp
}

Signal Command Payloads

  • mute-command: Instructs the target participant's client to disable local audio track (stream.getAudioTracks()[0].enabled = false) and update presence state.
  • kick-command: Instructs the target participant's client to unmount WebRTC listeners, tear down streams, and navigate back to the home route (/).

2.6 User Identity & Login History Schema

  • Path: /users/{uid}
  • Subcollection: /users/{uid}/loginHistory/{loginId}
// /users/{uid} document
{
  uid: string;
  email: string;
  displayName: string;
  photoURL: string;
  lastLoginAt: number;
  lastLoginIp: string;
}

// /users/{uid}/loginHistory/{loginId} document
{
  ip: string;
  userAgent: string;
  timestamp: number;
}

3. Web BroadcastChannel Protocol (Local Multi-Tab)

When running multiple tabs on the same origin (such as during local development and testing):

  • Channel Name: sabha_room_${roomId}
  • Payload Format: Emits exact SignalData JSON frames directly over the browser's native BroadcastChannel API, bypassing Firestore round-trips for zero network overhead.

4. LiveKit Real-Time DataChannel Protocol

When operating in LiveKit SFU mode, real-time collaboration messages (such as Whiteboard strokes) are transmitted using reliable binary DataChannels (room.localParticipant.publishData):

4.1 Whiteboard Stroke Event

{
  "type": "whiteboard",
  "event": {
    "type": "draw",
    "x": 240,
    "y": 180,
    "prevX": 235,
    "prevY": 178,
    "color": "#10b981",
    "width": 3,
    "isErasing": false
  }
}

4.2 Whiteboard Clear Canvas Event

{
  "type": "whiteboard",
  "event": {
    "type": "clear"
  }
}

5. Meeting Summarization & Email Delivery API

POST /api/meeting/summarize-and-email

Generates an executive AI summary using Google Gemini (gemini-3.5-flash with fallback to gemini-3.8-flash and gemini-flash-latest) from speaker-tagged meeting transcripts and dispatches emails via Zoho Mail SMTP (smtp.zoho.in:465).

  • Hosts & Co-hosts: Receive the formatted AI Executive Summary + Action Items with the complete verbatim transcript attached as sabha-[roomId]-transcript.txt (including bilingual Hindi dialogue and English translations).
  • Participants/Attendees: Receive the clean AI Executive Summary & Action Items notes delivered individually to their email inbox.
  • Roster Resilience: Automatically queries Firestore /rooms/{roomId}/participants to merge any attendee who registered their email upon entry, ensuring no attendee is missed even if disconnected right before call end.

Request Body

{
  "roomId": "string",
  "title": "string (optional)",
  "durationMinutes": 15,
  "participants": [
    {
      "id": "string",
      "name": "string",
      "email": "user@example.com",
      "isHost": true,
      "isCoHost": false
    }
  ],
  "transcript": [
    {
      "senderName": "Harsh",
      "text": "नमस्ते, सभा में आपका स्वागत है।",
      "translation": "Hello, welcome to Sabha.",
      "timestamp": 1727700000000
    }
  ]
}

Response (200 OK)

{
  "success": true,
  "summary": "# 📋 Sabha Meeting Summary\n...",
  "emailsDispatched": {
    "hosts": 1,
    "attendees": 4
  },
  "totalHostRecipients": 1,
  "totalAttendeeRecipients": 4
}

6. Real-Time Translation API

POST /api/translate

Translates spoken Hindi speech segments to English using Gemini (gemini-3-flash-preview / gemini-3.5-flash / gemini-3.8-flash) with fast public gateway fallback.

Request Body

{
  "text": "नमस्ते आप सब कैसे हैं?",
  "from": "hi",
  "to": "en"
}

Response (200 OK)

{
  "translation": "Hello, how are you all?"
}

7. AI Audio Speech Transcription API (Brave Browser & Fallback)

POST /api/transcribe-audio

Transcribes microphone audio segments for browsers where Google Web Speech API is blocked or disabled (such as Brave Browser due to privacy shields) using Google Gemini multimodal audio understanding.

Request Body

{
  "audio": "<base64_encoded_audio_data>",
  "mimeType": "audio/webm",
  "language": "hi-IN"
}

Response (200 OK)

{
  "text": "नमस्ते, क्या आप मुझे सुन सकते हैं?",
  "translation": "Hello, can you hear me?"
}