voice_calls.proto 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. syntax = "proto3";
  2. package chatto.api.v1;
  3. import "buf/validate/validate.proto";
  4. import "chatto/api/v1/rooms.proto";
  5. import "chatto/api/v1/users.proto";
  6. import "google/protobuf/timestamp.proto";
  7. // Room-scoped voice and video calls.
  8. service VoiceCallService {
  9. // Lists member rooms that currently have active calls as a finite
  10. // runtime snapshot. Rooms the caller is not a member of are omitted.
  11. //
  12. // Returns an empty list when LiveKit is not configured.
  13. rpc ListActiveCalls(ListActiveCallsRequest) returns (ListActiveCallsResponse);
  14. // Gets the current active call snapshot for one room.
  15. //
  16. // The caller must be a member of the room. Returns NOT_FOUND when the room
  17. // does not exist, currently has no active call, or voice calls are not
  18. // configured. The returned call_id lets clients ignore stale realtime call
  19. // events from previous calls in the same room.
  20. rpc GetActiveCall(GetActiveCallRequest) returns (GetActiveCallResponse);
  21. // Gets current active call snapshots for many rooms.
  22. //
  23. // Rooms that do not exist, are inaccessible, or currently have no active call
  24. // are omitted. Results preserve first-seen request order and repeated room
  25. // IDs are de-duplicated. Returns an empty list when LiveKit is not configured.
  26. rpc BatchGetActiveCalls(BatchGetActiveCallsRequest) returns (BatchGetActiveCallsResponse);
  27. // Lists participants currently observed in a room's active call as a finite
  28. // runtime snapshot.
  29. //
  30. // The caller must be a member of the room.
  31. // Returns NOT_FOUND when the room does not exist and PERMISSION_DENIED when
  32. // the caller is not a room member.
  33. rpc ListCallParticipants(ListCallParticipantsRequest) returns (ListCallParticipantsResponse);
  34. // Records the caller's intent to join a room call.
  35. //
  36. // Requires room membership and call.join. If no call is active, also
  37. // requires call.start. Publishing permissions do not grant admission.
  38. //
  39. // Returns joined=false when LiveKit is not configured.
  40. rpc JoinCall(JoinCallRequest) returns (JoinCallResponse);
  41. // Issues a LiveKit token for joining the room's active call.
  42. //
  43. // Requires room membership and call.join. A call must already be active.
  44. // The token permits microphone, camera, and screen-share sources only when
  45. // call.voice, call.camera, and call.screenshare respectively allow them.
  46. // A caller without publishing permissions can listen and watch.
  47. // Tokens expire after five minutes. Expiry does not end an established call.
  48. // Chatto checks connected participant permissions on its 30-second LiveKit
  49. // reconciliation cycle. Failed checks retry on subsequent cycles.
  50. // Returns NOT_FOUND when the room does not exist, PERMISSION_DENIED when the
  51. // caller is not a room member, and FAILED_PRECONDITION when no call is active
  52. // or voice and video calls are not configured.
  53. rpc CreateCallToken(CreateCallTokenRequest) returns (CreateCallTokenResponse);
  54. // Issues a short-lived LiveKit token for a native companion publisher owned
  55. // by the caller. Companion publishers contribute media to the caller's
  56. // logical participant without becoming call participants themselves.
  57. //
  58. // Requires room membership, call.join, call.screenshare, and participation
  59. // in the active call. Captured application audio does not need call.voice.
  60. // The credential expires after one minute; an established publisher is
  61. // checked by the same permission reconciliation as the main participant.
  62. // Returns
  63. // FAILED_PRECONDITION when no call is active, the caller has not joined it,
  64. // or voice and video calls are not configured.
  65. rpc CreateCallMediaPublisherToken(CreateCallMediaPublisherTokenRequest) returns (CreateCallMediaPublisherTokenResponse);
  66. // Records the caller's intent to leave a room call.
  67. //
  68. // Requires room membership, but not call.join or a publishing permission.
  69. //
  70. // Returns left=false when LiveKit is not configured.
  71. rpc LeaveCall(LeaveCallRequest) returns (LeaveCallResponse);
  72. }
  73. // Request for active room call snapshots.
  74. message ListActiveCallsRequest {}
  75. // Finite runtime snapshot of active room calls.
  76. message ListActiveCallsResponse {
  77. // Active calls in room order returned by the call-state projection.
  78. repeated ActiveCall calls = 1;
  79. }
  80. // Current active call snapshot for one room.
  81. message ActiveCall {
  82. reserved 1;
  83. reserved "room_id";
  84. // Room containing the active call.
  85. RoomSummary room = 4;
  86. // Active call session ID.
  87. string call_id = 2;
  88. // Participants currently projected for this call.
  89. repeated CallParticipant participants = 3;
  90. }
  91. // Request for one room's active call snapshot.
  92. message GetActiveCallRequest {
  93. // Required. Room whose active call should be inspected.
  94. string room_id = 1 [(buf.validate.field).string.min_len = 1];
  95. }
  96. // Response for one room's active call snapshot.
  97. message GetActiveCallResponse {
  98. // Current active call.
  99. ActiveCall call = 1;
  100. }
  101. // Request active call snapshots for many rooms.
  102. message BatchGetActiveCallsRequest {
  103. // Required room IDs. Unknown, inaccessible, and inactive rooms are omitted.
  104. repeated string room_ids = 1 [(buf.validate.field).repeated = {
  105. min_items: 1
  106. max_items: 100
  107. items: {
  108. string: {min_len: 1}
  109. }
  110. }];
  111. }
  112. // Active call batch response.
  113. message BatchGetActiveCallsResponse {
  114. // Active calls in first-seen request order.
  115. repeated ActiveCall calls = 1;
  116. }
  117. // Request for participants in a room call.
  118. message ListCallParticipantsRequest {
  119. // Required. Room whose active call should be inspected.
  120. string room_id = 1 [(buf.validate.field).string.min_len = 1];
  121. }
  122. // Finite runtime snapshot of participants in one room call.
  123. message ListCallParticipantsResponse {
  124. // Participants currently projected for the room call.
  125. repeated CallParticipant participants = 1;
  126. }
  127. // User currently participating in a room call.
  128. message CallParticipant {
  129. // Participant user.
  130. User user = 1;
  131. // When the user joined this call.
  132. google.protobuf.Timestamp joined_at = 2;
  133. // Active call session ID.
  134. string call_id = 3;
  135. }
  136. // Request to record joining a room call.
  137. message JoinCallRequest {
  138. // Required. Room whose call is being joined.
  139. string room_id = 1 [(buf.validate.field).string.min_len = 1];
  140. }
  141. // Response from recording a join intent.
  142. message JoinCallResponse {
  143. // True when a join fact was recorded.
  144. bool joined = 1;
  145. }
  146. // Request for a LiveKit token for a room call.
  147. message CreateCallTokenRequest {
  148. // Required. Room whose active call should be joined.
  149. string room_id = 1 [(buf.validate.field).string.min_len = 1];
  150. }
  151. // LiveKit token details for joining a room call.
  152. message CreateCallTokenResponse {
  153. // LiveKit JWT token.
  154. string token = 1;
  155. // Shared E2EE key for this active call.
  156. string e2ee_key = 2;
  157. // Active call session ID.
  158. string call_id = 3;
  159. }
  160. // Native companion publisher kind.
  161. enum CallMediaPublisherKind {
  162. // The publisher kind was not specified.
  163. CALL_MEDIA_PUBLISHER_KIND_UNSPECIFIED = 0;
  164. // Native game-window video and application audio.
  165. CALL_MEDIA_PUBLISHER_KIND_GAME_SHARE = 1;
  166. }
  167. // Request for a native companion publisher credential.
  168. message CreateCallMediaPublisherTokenRequest {
  169. // Required. Room whose active call receives the media.
  170. string room_id = 1 [(buf.validate.field).string.min_len = 1];
  171. // Required. Kind of native media publisher being started.
  172. CallMediaPublisherKind kind = 2 [(buf.validate.field).enum = {defined_only: true not_in: [0]}];
  173. }
  174. // Credential for one native companion publisher connection.
  175. message CreateCallMediaPublisherTokenResponse {
  176. reserved 4;
  177. reserved "publisher_identity";
  178. // Short-lived LiveKit JWT token.
  179. string token = 1;
  180. // Shared E2EE key for this active call.
  181. string e2ee_key = 2;
  182. // Active call session ID.
  183. string call_id = 3;
  184. }
  185. // Request to record leaving a room call.
  186. message LeaveCallRequest {
  187. // Required. Room whose call is being left.
  188. string room_id = 1 [(buf.validate.field).string.min_len = 1];
  189. }
  190. // Response from recording a leave intent.
  191. message LeaveCallResponse {
  192. // True when a leave fact was recorded.
  193. bool left = 1;
  194. }