syntax = "proto3"; package chatto.api.v1; import "buf/validate/validate.proto"; import "chatto/api/v1/rooms.proto"; import "chatto/api/v1/users.proto"; import "google/protobuf/timestamp.proto"; // Voice-call request/response APIs backed by Chatto call-state projections. service VoiceCallService { // Lists member rooms that currently have active calls as a finite // runtime snapshot. Rooms the caller is not a member of are omitted. // // Returns an empty list when LiveKit is not configured. rpc ListActiveCalls(ListActiveCallsRequest) returns (ListActiveCallsResponse); // Gets the current active call snapshot for one room. // // The caller must be a member of the room. Returns NOT_FOUND when the room // does not exist, currently has no active call, or voice calls are not // configured. The returned call_id lets clients ignore stale realtime call // events from previous calls in the same room. rpc GetActiveCall(GetActiveCallRequest) returns (GetActiveCallResponse); // Gets current active call snapshots for many rooms. // // Rooms that do not exist, are inaccessible, or currently have no active call // are omitted. Results preserve first-seen request order and repeated room // IDs are de-duplicated. Returns an empty list when LiveKit is not configured. rpc BatchGetActiveCalls(BatchGetActiveCallsRequest) returns (BatchGetActiveCallsResponse); // Lists participants currently observed in a room's active call as a finite // runtime snapshot. // // The caller must be a member of the room. // Returns NOT_FOUND when the room does not exist and PERMISSION_DENIED when // the caller is not a room member. rpc ListCallParticipants(ListCallParticipantsRequest) returns (ListCallParticipantsResponse); // Records the caller's intent to join a room call. // // Returns joined=false when LiveKit is not configured. rpc JoinCall(JoinCallRequest) returns (JoinCallResponse); // Issues a LiveKit token for joining the room's active call. // // The caller must be a member of the room and a call must already be active. // Returns NOT_FOUND when the room does not exist, PERMISSION_DENIED when the // caller is not a room member, and FAILED_PRECONDITION when no call is active // or voice and video calls are not configured. rpc GetCallToken(GetCallTokenRequest) returns (GetCallTokenResponse); // Records the caller's intent to leave a room call. // // Returns left=false when LiveKit is not configured. rpc LeaveCall(LeaveCallRequest) returns (LeaveCallResponse); } // Request for active room call snapshots. message ListActiveCallsRequest {} // Finite runtime snapshot of active room calls. message ListActiveCallsResponse { // Active calls in room order returned by the call-state projection. repeated ActiveCall calls = 1; } // Current active call snapshot for one room. message ActiveCall { reserved 1; reserved "room_id"; // Room containing the active call. RoomSummary room = 4; // Active call session ID. string call_id = 2; // Participants currently projected for this call. repeated CallParticipant participants = 3; } // Request for one room's active call snapshot. message GetActiveCallRequest { // Required. Room whose active call should be inspected. string room_id = 1 [(buf.validate.field).string.min_len = 1]; } // Response for one room's active call snapshot. message GetActiveCallResponse { // Current active call. ActiveCall call = 1; } // Request active call snapshots for many rooms. message BatchGetActiveCallsRequest { // Required room IDs. Unknown, inaccessible, and inactive rooms are omitted. repeated string room_ids = 1 [(buf.validate.field).repeated = { min_items: 1 max_items: 100 items: { string: {min_len: 1} } }]; } // Active call batch response. message BatchGetActiveCallsResponse { // Active calls in first-seen request order. repeated ActiveCall calls = 1; } // Request for participants in a room call. message ListCallParticipantsRequest { // Required. Room whose active call should be inspected. string room_id = 1 [(buf.validate.field).string.min_len = 1]; } // Finite runtime snapshot of participants in one room call. message ListCallParticipantsResponse { // Participants currently projected for the room call. repeated CallParticipant participants = 1; } // User currently participating in a room call. message CallParticipant { // Participant user. User user = 1; // When the user joined this call. google.protobuf.Timestamp joined_at = 2; // Active call session ID. string call_id = 3; } // Request to record joining a room call. message JoinCallRequest { // Required. Room whose call is being joined. string room_id = 1 [(buf.validate.field).string.min_len = 1]; } // Response from recording a join intent. message JoinCallResponse { // True when a join fact was recorded. bool joined = 1; } // Request for a LiveKit token for a room call. message GetCallTokenRequest { // Required. Room whose active call should be joined. string room_id = 1 [(buf.validate.field).string.min_len = 1]; } // LiveKit token details for joining a room call. message GetCallTokenResponse { // LiveKit JWT token. string token = 1; // Shared E2EE key for this active call. string e2ee_key = 2; // Active call session ID. string call_id = 3; } // Request to record leaving a room call. message LeaveCallRequest { // Required. Room whose call is being left. string room_id = 1 [(buf.validate.field).string.min_len = 1]; } // Response from recording a leave intent. message LeaveCallResponse { // True when a leave fact was recorded. bool left = 1; }