From dcc0838d4b611503faa9972d32453679462296ba Mon Sep 17 00:00:00 2001 From: Darshak03 <115038906+Darshak03@users.noreply.github.com> Date: Tue, 8 Sep 2026 00:22:21 +0530 Subject: [PATCH] Add room-scoped webhook configuration Rooms can currently only be observed through the globally configured webhook URLs. Egress already supports per-resource webhooks by carrying a `repeated WebhookConfig webhooks` on the request that created it and deriving notify options from it at emit time; this applies the same shape to rooms. - CreateRoomRequest.webhooks lets an API caller attach webhooks to a single room, and RoomConfiguration.webhooks does the same for a named room preset. - RoomInternal.webhooks persists the resolved list. It is the analogue of EgressInfo.Request: server-side state that travels with the resource. The public Room proto deliberately does not carry it, since entries hold signing keys and Room is returned by ListRooms. - webhook.GetRoomNotifyOptions mirrors egress.GetEgressNotifyOptions, turning a room's webhook list into a WithExtraWebhooks option. It lives in the webhook package rather than a new one because the event constants are already there and a `room` package would collide with the ubiquitous `room` variable at the call sites. Only room, participant and track events are delivered to room webhooks. Egress, ingress and agent events are excluded by an allowlist: those resources carry their own webhook config, so forwarding them here would both duplicate delivery and leak beyond the room's scope. No new delivery machinery is needed. DefaultNotifier.QueueNotify already fans out to the static URLs first and then to each extra webhook, resolving SigningKey through the KeyProvider and honouring per-webhook FilterParams. --- livekit/livekit_internal.pb.go | 37 +++-- livekit/livekit_room.pb.go | 150 +++++++++++--------- livekit/livekit_room.twirp.go | 206 ++++++++++++++-------------- protobufs/livekit_internal.proto | 3 + protobufs/livekit_room.proto | 11 +- webhook/room_notify_options.go | 48 +++++++ webhook/room_notify_options_test.go | 62 +++++++++ 7 files changed, 338 insertions(+), 179 deletions(-) create mode 100644 webhook/room_notify_options.go create mode 100644 webhook/room_notify_options_test.go diff --git a/livekit/livekit_internal.pb.go b/livekit/livekit_internal.pb.go index ef6e48a30..d36843917 100644 --- a/livekit/livekit_internal.pb.go +++ b/livekit/livekit_internal.pb.go @@ -15,7 +15,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.12 -// protoc v7.35.1 +// protoc v5.29.3 // source: livekit_internal.proto package livekit @@ -1323,8 +1323,11 @@ type RoomInternal struct { ReplayEnabled bool `protobuf:"varint,6,opt,name=replay_enabled,json=replayEnabled,proto3" json:"replay_enabled,omitempty"` ExportRoom bool `protobuf:"varint,7,opt,name=export_room,json=exportRoom,proto3" json:"export_room,omitempty"` Tags map[string]string `protobuf:"bytes,8,rep,name=tags,proto3" json:"tags,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // room-scoped webhooks, resolved from CreateRoomRequest/RoomConfiguration at + // room creation. Not exposed on the public Room proto: entries carry signing keys. + Webhooks []*WebhookConfig `protobuf:"bytes,9,rep,name=webhooks,proto3" json:"webhooks,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *RoomInternal) Reset() { @@ -1413,6 +1416,13 @@ func (x *RoomInternal) GetTags() map[string]string { return nil } +func (x *RoomInternal) GetWebhooks() []*WebhookConfig { + if x != nil { + return x.Webhooks + } + return nil +} + type ICEConfig struct { state protoimpl.MessageState `protogen:"open.v1"` PreferenceSubscriber ICECandidateType `protobuf:"varint,1,opt,name=preference_subscriber,json=preferenceSubscriber,proto3,enum=livekit.ICECandidateType" json:"preference_subscriber,omitempty"` @@ -1611,7 +1621,7 @@ const file_livekit_internal_proto_rawDesc = "" + "\x1ause_single_peer_connection\x18\x18 \x01(\bR\x17useSinglePeerConnection\x12(\n" + "\x10token_expires_at\x18\x1a \x01(\x03R\x0etokenExpiresAtB\x1c\n" + "\x1a_auto_subscribe_data_trackB\x19\n" + - "\x17_subscriber_allow_pause\"\xf6\x03\n" + + "\x17_subscriber_allow_pause\"\xaa\x04\n" + "\fRoomInternal\x12;\n" + "\ftrack_egress\x18\x01 \x01(\v2\x18.livekit.AutoTrackEgressR\vtrackEgress\x12M\n" + "\x12participant_egress\x18\x02 \x01(\v2\x1e.livekit.AutoParticipantEgressR\x11participantEgress\x12:\n" + @@ -1621,7 +1631,8 @@ const file_livekit_internal_proto_rawDesc = "" + "\x0ereplay_enabled\x18\x06 \x01(\bR\rreplayEnabled\x12\x1f\n" + "\vexport_room\x18\a \x01(\bR\n" + "exportRoom\x123\n" + - "\x04tags\x18\b \x03(\v2\x1f.livekit.RoomInternal.TagsEntryR\x04tags\x1a7\n" + + "\x04tags\x18\b \x03(\v2\x1f.livekit.RoomInternal.TagsEntryR\x04tags\x122\n" + + "\bwebhooks\x18\t \x03(\v2\x16.livekit.WebhookConfigR\bwebhooks\x1a7\n" + "\tTagsEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xa9\x01\n" + @@ -1684,6 +1695,7 @@ var file_livekit_internal_proto_goTypes = []any{ (*AutoParticipantEgress)(nil), // 17: livekit.AutoParticipantEgress (*PlayoutDelay)(nil), // 18: livekit.PlayoutDelay (*RoomAgentDispatch)(nil), // 19: livekit.RoomAgentDispatch + (*WebhookConfig)(nil), // 20: livekit.WebhookConfig } var file_livekit_internal_proto_depIdxs = []int32{ 4, // 0: livekit.Node.stats:type_name -> livekit.NodeStats @@ -1701,13 +1713,14 @@ var file_livekit_internal_proto_depIdxs = []int32{ 18, // 12: livekit.RoomInternal.playout_delay:type_name -> livekit.PlayoutDelay 19, // 13: livekit.RoomInternal.agent_dispatches:type_name -> livekit.RoomAgentDispatch 9, // 14: livekit.RoomInternal.tags:type_name -> livekit.RoomInternal.TagsEntry - 2, // 15: livekit.ICEConfig.preference_subscriber:type_name -> livekit.ICECandidateType - 2, // 16: livekit.ICEConfig.preference_publisher:type_name -> livekit.ICECandidateType - 17, // [17:17] is the sub-list for method output_type - 17, // [17:17] is the sub-list for method input_type - 17, // [17:17] is the sub-list for extension type_name - 17, // [17:17] is the sub-list for extension extendee - 0, // [0:17] is the sub-list for field type_name + 20, // 15: livekit.RoomInternal.webhooks:type_name -> livekit.WebhookConfig + 2, // 16: livekit.ICEConfig.preference_subscriber:type_name -> livekit.ICECandidateType + 2, // 17: livekit.ICEConfig.preference_publisher:type_name -> livekit.ICECandidateType + 18, // [18:18] is the sub-list for method output_type + 18, // [18:18] is the sub-list for method input_type + 18, // [18:18] is the sub-list for extension type_name + 18, // [18:18] is the sub-list for extension extendee + 0, // [0:18] is the sub-list for field type_name } func init() { file_livekit_internal_proto_init() } diff --git a/livekit/livekit_room.pb.go b/livekit/livekit_room.pb.go index 1c2535d4e..5ab18e75f 100644 --- a/livekit/livekit_room.pb.go +++ b/livekit/livekit_room.pb.go @@ -15,7 +15,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.12 -// protoc v7.35.1 +// protoc v5.29.3 // source: livekit_room.proto package livekit @@ -65,7 +65,10 @@ type CreateRoomRequest struct { // replay ReplayEnabled bool `protobuf:"varint,13,opt,name=replay_enabled,json=replayEnabled,proto3" json:"replay_enabled,omitempty"` // Define agents that should be dispatched to this room - Agents []*RoomAgentDispatch `protobuf:"bytes,14,rep,name=agents,proto3" json:"agents,omitempty"` + Agents []*RoomAgentDispatch `protobuf:"bytes,14,rep,name=agents,proto3" json:"agents,omitempty"` + // Optional additional webhook config, scoped to this room. Egress and ingress + // events are never delivered to these; use the egress request webhooks for those. + Webhooks []*WebhookConfig `protobuf:"bytes,16,rep,name=webhooks,proto3" json:"webhooks,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -198,6 +201,13 @@ func (x *CreateRoomRequest) GetAgents() []*RoomAgentDispatch { return nil } +func (x *CreateRoomRequest) GetWebhooks() []*WebhookConfig { + if x != nil { + return x.Webhooks + } + return nil +} + type RoomEgress struct { state protoimpl.MessageState `protogen:"open.v1"` Room *RoomCompositeEgressRequest `protobuf:"bytes,1,opt,name=room,proto3" json:"room,omitempty"` @@ -1189,7 +1199,9 @@ type RoomConfiguration struct { // Define agents that should be dispatched to this room Agents []*RoomAgentDispatch `protobuf:"bytes,10,rep,name=agents,proto3" json:"agents,omitempty"` // Tags to attach to the room - Tags map[string]string `protobuf:"bytes,12,rep,name=tags,proto3" json:"tags,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + Tags map[string]string `protobuf:"bytes,12,rep,name=tags,proto3" json:"tags,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // Optional additional webhook config, scoped to rooms created with this preset + Webhooks []*WebhookConfig `protobuf:"bytes,13,rep,name=webhooks,proto3" json:"webhooks,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1301,6 +1313,13 @@ func (x *RoomConfiguration) GetTags() map[string]string { return nil } +func (x *RoomConfiguration) GetWebhooks() []*WebhookConfig { + if x != nil { + return x.Webhooks + } + return nil +} + type ForwardParticipantRequest struct { state protoimpl.MessageState `protogen:"open.v1"` // room to forward participant from @@ -1623,7 +1642,7 @@ var File_livekit_room_proto protoreflect.FileDescriptor const file_livekit_room_proto_rawDesc = "" + "\n" + - "\x12livekit_room.proto\x12\alivekit\x1a\x14livekit_models.proto\x1a\x14livekit_egress.proto\x1a\x1clivekit_agent_dispatch.proto\x1a\x14logger/options.proto\"\xa1\x05\n" + + "\x12livekit_room.proto\x12\alivekit\x1a\x14livekit_models.proto\x1a\x14livekit_egress.proto\x1a\x1clivekit_agent_dispatch.proto\x1a\x14logger/options.proto\"\xd5\x05\n" + "\x11CreateRoomRequest\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12\x1f\n" + "\vroom_preset\x18\f \x01(\tR\n" + @@ -1640,7 +1659,8 @@ const file_livekit_room_proto_rawDesc = "" + "\x11max_playout_delay\x18\b \x01(\rR\x0fmaxPlayoutDelay\x12!\n" + "\fsync_streams\x18\t \x01(\bR\vsyncStreams\x12%\n" + "\x0ereplay_enabled\x18\r \x01(\bR\rreplayEnabled\x122\n" + - "\x06agents\x18\x0e \x03(\v2\x1a.livekit.RoomAgentDispatchR\x06agents\x1a7\n" + + "\x06agents\x18\x0e \x03(\v2\x1a.livekit.RoomAgentDispatchR\x06agents\x122\n" + + "\bwebhooks\x18\x10 \x03(\v2\x16.livekit.WebhookConfigR\bwebhooks\x1a7\n" + "\tTagsEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xb9\x01\n" + @@ -1710,7 +1730,7 @@ const file_livekit_room_proto_rawDesc = "" + "\x10SendDataResponse\"q\n" + "\x19UpdateRoomMetadataRequest\x12\x12\n" + "\x04room\x18\x01 \x01(\tR\x04room\x12@\n" + - "\bmetadata\x18\x02 \x01(\tB$\xb2P\x1e\xc0P\x01R\bmetadata\"\xb5\x04\n" + + "\bmetadata\x18\x02 \x01(\tB$\xb2P\x1e\xc0P\x01R\bmetadata\"\xe9\x04\n" + "\x11RoomConfiguration\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12#\n" + "\rempty_timeout\x18\x02 \x01(\rR\femptyTimeout\x12+\n" + @@ -1723,7 +1743,8 @@ const file_livekit_room_proto_rawDesc = "" + "\fsync_streams\x18\t \x01(\bR\vsyncStreams\x122\n" + "\x06agents\x18\n" + " \x03(\v2\x1a.livekit.RoomAgentDispatchR\x06agents\x128\n" + - "\x04tags\x18\f \x03(\v2$.livekit.RoomConfiguration.TagsEntryR\x04tags\x1a7\n" + + "\x04tags\x18\f \x03(\v2$.livekit.RoomConfiguration.TagsEntryR\x04tags\x122\n" + + "\bwebhooks\x18\r \x03(\v2\x16.livekit.WebhookConfigR\bwebhooks\x1a7\n" + "\tTagsEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"v\n" + @@ -1808,67 +1829,70 @@ var file_livekit_room_proto_goTypes = []any{ nil, // 27: livekit.UpdateParticipantRequest.AttributesEntry nil, // 28: livekit.RoomConfiguration.TagsEntry (*RoomAgentDispatch)(nil), // 29: livekit.RoomAgentDispatch - (*RoomCompositeEgressRequest)(nil), // 30: livekit.RoomCompositeEgressRequest - (*AutoParticipantEgress)(nil), // 31: livekit.AutoParticipantEgress - (*AutoTrackEgress)(nil), // 32: livekit.AutoTrackEgress - (*Room)(nil), // 33: livekit.Room - (*ParticipantInfo)(nil), // 34: livekit.ParticipantInfo - (*TrackInfo)(nil), // 35: livekit.TrackInfo - (*ParticipantPermission)(nil), // 36: livekit.ParticipantPermission - (*ParticipantTracks)(nil), // 37: livekit.ParticipantTracks - (DataPacket_Kind)(0), // 38: livekit.DataPacket.Kind + (*WebhookConfig)(nil), // 30: livekit.WebhookConfig + (*RoomCompositeEgressRequest)(nil), // 31: livekit.RoomCompositeEgressRequest + (*AutoParticipantEgress)(nil), // 32: livekit.AutoParticipantEgress + (*AutoTrackEgress)(nil), // 33: livekit.AutoTrackEgress + (*Room)(nil), // 34: livekit.Room + (*ParticipantInfo)(nil), // 35: livekit.ParticipantInfo + (*TrackInfo)(nil), // 36: livekit.TrackInfo + (*ParticipantPermission)(nil), // 37: livekit.ParticipantPermission + (*ParticipantTracks)(nil), // 38: livekit.ParticipantTracks + (DataPacket_Kind)(0), // 39: livekit.DataPacket.Kind } var file_livekit_room_proto_depIdxs = []int32{ 26, // 0: livekit.CreateRoomRequest.tags:type_name -> livekit.CreateRoomRequest.TagsEntry 1, // 1: livekit.CreateRoomRequest.egress:type_name -> livekit.RoomEgress 29, // 2: livekit.CreateRoomRequest.agents:type_name -> livekit.RoomAgentDispatch - 30, // 3: livekit.RoomEgress.room:type_name -> livekit.RoomCompositeEgressRequest - 31, // 4: livekit.RoomEgress.participant:type_name -> livekit.AutoParticipantEgress - 32, // 5: livekit.RoomEgress.tracks:type_name -> livekit.AutoTrackEgress - 29, // 6: livekit.RoomAgent.dispatches:type_name -> livekit.RoomAgentDispatch - 33, // 7: livekit.ListRoomsResponse.rooms:type_name -> livekit.Room - 34, // 8: livekit.ListParticipantsResponse.participants:type_name -> livekit.ParticipantInfo - 35, // 9: livekit.MuteRoomTrackResponse.track:type_name -> livekit.TrackInfo - 36, // 10: livekit.UpdateParticipantRequest.permission:type_name -> livekit.ParticipantPermission - 27, // 11: livekit.UpdateParticipantRequest.attributes:type_name -> livekit.UpdateParticipantRequest.AttributesEntry - 37, // 12: livekit.UpdateSubscriptionsRequest.participant_tracks:type_name -> livekit.ParticipantTracks - 38, // 13: livekit.SendDataRequest.kind:type_name -> livekit.DataPacket.Kind - 1, // 14: livekit.RoomConfiguration.egress:type_name -> livekit.RoomEgress - 29, // 15: livekit.RoomConfiguration.agents:type_name -> livekit.RoomAgentDispatch - 28, // 16: livekit.RoomConfiguration.tags:type_name -> livekit.RoomConfiguration.TagsEntry - 0, // 17: livekit.RoomService.CreateRoom:input_type -> livekit.CreateRoomRequest - 3, // 18: livekit.RoomService.ListRooms:input_type -> livekit.ListRoomsRequest - 5, // 19: livekit.RoomService.DeleteRoom:input_type -> livekit.DeleteRoomRequest - 7, // 20: livekit.RoomService.ListParticipants:input_type -> livekit.ListParticipantsRequest - 9, // 21: livekit.RoomService.GetParticipant:input_type -> livekit.RoomParticipantIdentity - 9, // 22: livekit.RoomService.RemoveParticipant:input_type -> livekit.RoomParticipantIdentity - 11, // 23: livekit.RoomService.MutePublishedTrack:input_type -> livekit.MuteRoomTrackRequest - 13, // 24: livekit.RoomService.UpdateParticipant:input_type -> livekit.UpdateParticipantRequest - 14, // 25: livekit.RoomService.UpdateSubscriptions:input_type -> livekit.UpdateSubscriptionsRequest - 16, // 26: livekit.RoomService.SendData:input_type -> livekit.SendDataRequest - 18, // 27: livekit.RoomService.UpdateRoomMetadata:input_type -> livekit.UpdateRoomMetadataRequest - 20, // 28: livekit.RoomService.ForwardParticipant:input_type -> livekit.ForwardParticipantRequest - 22, // 29: livekit.RoomService.MoveParticipant:input_type -> livekit.MoveParticipantRequest - 24, // 30: livekit.RoomService.PerformRpc:input_type -> livekit.PerformRpcRequest - 33, // 31: livekit.RoomService.CreateRoom:output_type -> livekit.Room - 4, // 32: livekit.RoomService.ListRooms:output_type -> livekit.ListRoomsResponse - 6, // 33: livekit.RoomService.DeleteRoom:output_type -> livekit.DeleteRoomResponse - 8, // 34: livekit.RoomService.ListParticipants:output_type -> livekit.ListParticipantsResponse - 34, // 35: livekit.RoomService.GetParticipant:output_type -> livekit.ParticipantInfo - 10, // 36: livekit.RoomService.RemoveParticipant:output_type -> livekit.RemoveParticipantResponse - 12, // 37: livekit.RoomService.MutePublishedTrack:output_type -> livekit.MuteRoomTrackResponse - 34, // 38: livekit.RoomService.UpdateParticipant:output_type -> livekit.ParticipantInfo - 15, // 39: livekit.RoomService.UpdateSubscriptions:output_type -> livekit.UpdateSubscriptionsResponse - 17, // 40: livekit.RoomService.SendData:output_type -> livekit.SendDataResponse - 33, // 41: livekit.RoomService.UpdateRoomMetadata:output_type -> livekit.Room - 21, // 42: livekit.RoomService.ForwardParticipant:output_type -> livekit.ForwardParticipantResponse - 23, // 43: livekit.RoomService.MoveParticipant:output_type -> livekit.MoveParticipantResponse - 25, // 44: livekit.RoomService.PerformRpc:output_type -> livekit.PerformRpcResponse - 31, // [31:45] is the sub-list for method output_type - 17, // [17:31] is the sub-list for method input_type - 17, // [17:17] is the sub-list for extension type_name - 17, // [17:17] is the sub-list for extension extendee - 0, // [0:17] is the sub-list for field type_name + 30, // 3: livekit.CreateRoomRequest.webhooks:type_name -> livekit.WebhookConfig + 31, // 4: livekit.RoomEgress.room:type_name -> livekit.RoomCompositeEgressRequest + 32, // 5: livekit.RoomEgress.participant:type_name -> livekit.AutoParticipantEgress + 33, // 6: livekit.RoomEgress.tracks:type_name -> livekit.AutoTrackEgress + 29, // 7: livekit.RoomAgent.dispatches:type_name -> livekit.RoomAgentDispatch + 34, // 8: livekit.ListRoomsResponse.rooms:type_name -> livekit.Room + 35, // 9: livekit.ListParticipantsResponse.participants:type_name -> livekit.ParticipantInfo + 36, // 10: livekit.MuteRoomTrackResponse.track:type_name -> livekit.TrackInfo + 37, // 11: livekit.UpdateParticipantRequest.permission:type_name -> livekit.ParticipantPermission + 27, // 12: livekit.UpdateParticipantRequest.attributes:type_name -> livekit.UpdateParticipantRequest.AttributesEntry + 38, // 13: livekit.UpdateSubscriptionsRequest.participant_tracks:type_name -> livekit.ParticipantTracks + 39, // 14: livekit.SendDataRequest.kind:type_name -> livekit.DataPacket.Kind + 1, // 15: livekit.RoomConfiguration.egress:type_name -> livekit.RoomEgress + 29, // 16: livekit.RoomConfiguration.agents:type_name -> livekit.RoomAgentDispatch + 28, // 17: livekit.RoomConfiguration.tags:type_name -> livekit.RoomConfiguration.TagsEntry + 30, // 18: livekit.RoomConfiguration.webhooks:type_name -> livekit.WebhookConfig + 0, // 19: livekit.RoomService.CreateRoom:input_type -> livekit.CreateRoomRequest + 3, // 20: livekit.RoomService.ListRooms:input_type -> livekit.ListRoomsRequest + 5, // 21: livekit.RoomService.DeleteRoom:input_type -> livekit.DeleteRoomRequest + 7, // 22: livekit.RoomService.ListParticipants:input_type -> livekit.ListParticipantsRequest + 9, // 23: livekit.RoomService.GetParticipant:input_type -> livekit.RoomParticipantIdentity + 9, // 24: livekit.RoomService.RemoveParticipant:input_type -> livekit.RoomParticipantIdentity + 11, // 25: livekit.RoomService.MutePublishedTrack:input_type -> livekit.MuteRoomTrackRequest + 13, // 26: livekit.RoomService.UpdateParticipant:input_type -> livekit.UpdateParticipantRequest + 14, // 27: livekit.RoomService.UpdateSubscriptions:input_type -> livekit.UpdateSubscriptionsRequest + 16, // 28: livekit.RoomService.SendData:input_type -> livekit.SendDataRequest + 18, // 29: livekit.RoomService.UpdateRoomMetadata:input_type -> livekit.UpdateRoomMetadataRequest + 20, // 30: livekit.RoomService.ForwardParticipant:input_type -> livekit.ForwardParticipantRequest + 22, // 31: livekit.RoomService.MoveParticipant:input_type -> livekit.MoveParticipantRequest + 24, // 32: livekit.RoomService.PerformRpc:input_type -> livekit.PerformRpcRequest + 34, // 33: livekit.RoomService.CreateRoom:output_type -> livekit.Room + 4, // 34: livekit.RoomService.ListRooms:output_type -> livekit.ListRoomsResponse + 6, // 35: livekit.RoomService.DeleteRoom:output_type -> livekit.DeleteRoomResponse + 8, // 36: livekit.RoomService.ListParticipants:output_type -> livekit.ListParticipantsResponse + 35, // 37: livekit.RoomService.GetParticipant:output_type -> livekit.ParticipantInfo + 10, // 38: livekit.RoomService.RemoveParticipant:output_type -> livekit.RemoveParticipantResponse + 12, // 39: livekit.RoomService.MutePublishedTrack:output_type -> livekit.MuteRoomTrackResponse + 35, // 40: livekit.RoomService.UpdateParticipant:output_type -> livekit.ParticipantInfo + 15, // 41: livekit.RoomService.UpdateSubscriptions:output_type -> livekit.UpdateSubscriptionsResponse + 17, // 42: livekit.RoomService.SendData:output_type -> livekit.SendDataResponse + 34, // 43: livekit.RoomService.UpdateRoomMetadata:output_type -> livekit.Room + 21, // 44: livekit.RoomService.ForwardParticipant:output_type -> livekit.ForwardParticipantResponse + 23, // 45: livekit.RoomService.MoveParticipant:output_type -> livekit.MoveParticipantResponse + 25, // 46: livekit.RoomService.PerformRpc:output_type -> livekit.PerformRpcResponse + 33, // [33:47] is the sub-list for method output_type + 19, // [19:33] is the sub-list for method input_type + 19, // [19:19] is the sub-list for extension type_name + 19, // [19:19] is the sub-list for extension extendee + 0, // [0:19] is the sub-list for field type_name } func init() { file_livekit_room_proto_init() } diff --git a/livekit/livekit_room.twirp.go b/livekit/livekit_room.twirp.go index 122269f8a..85803b970 100644 --- a/livekit/livekit_room.twirp.go +++ b/livekit/livekit_room.twirp.go @@ -4167,106 +4167,108 @@ func (s *roomServiceServer) PathPrefix() string { } var twirpFileDescriptor5 = []byte{ - // 1612 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x5b, 0x6f, 0x13, 0xd7, - 0x16, 0x3e, 0x4e, 0x6c, 0xc7, 0x5e, 0xce, 0xcd, 0x3b, 0x01, 0x26, 0x13, 0x2e, 0x66, 0xc2, 0x39, - 0xc7, 0x1c, 0x0e, 0xe6, 0x90, 0xa3, 0x0a, 0x14, 0x51, 0x4a, 0x42, 0x02, 0x8d, 0x20, 0x92, 0x35, - 0x49, 0xd5, 0x8b, 0x54, 0x4d, 0xc7, 0x9e, 0x8d, 0xb3, 0x15, 0xcf, 0x85, 0xd9, 0xdb, 0x01, 0x17, - 0xf1, 0xce, 0xdf, 0xe8, 0x6b, 0x1f, 0x2b, 0xf5, 0xa1, 0x55, 0x55, 0xf5, 0x47, 0xf4, 0x17, 0xf4, - 0xb1, 0xbf, 0xa2, 0xda, 0x97, 0x19, 0x6f, 0xdb, 0x63, 0x03, 0x51, 0x2b, 0xf5, 0x89, 0xec, 0x75, - 0xdf, 0xdf, 0xac, 0xb5, 0xf6, 0x67, 0x00, 0x75, 0xc9, 0x29, 0x3e, 0x21, 0xcc, 0x89, 0xc3, 0xd0, - 0x6f, 0x44, 0x71, 0xc8, 0x42, 0x34, 0xa7, 0x64, 0xe6, 0x6a, 0xa2, 0xf4, 0x43, 0x0f, 0x77, 0xa9, - 0x54, 0x0f, 0xa4, 0xb8, 0x13, 0x63, 0x9a, 0x48, 0x2f, 0x26, 0x52, 0xb7, 0x83, 0x03, 0xe6, 0x78, - 0x84, 0x46, 0x2e, 0x6b, 0x1f, 0xa7, 0x3e, 0x61, 0xa7, 0x83, 0xe3, 0x5b, 0x61, 0xc4, 0x48, 0x18, - 0x28, 0x1f, 0xeb, 0x9b, 0x02, 0x54, 0x1f, 0xc6, 0xd8, 0x65, 0xd8, 0x0e, 0x43, 0xdf, 0xc6, 0xcf, - 0x7b, 0x98, 0x32, 0x84, 0x20, 0x1f, 0xb8, 0x3e, 0x36, 0x72, 0xb5, 0x5c, 0xbd, 0x6c, 0x8b, 0xbf, - 0xd1, 0x15, 0xa8, 0xf0, 0x02, 0x9d, 0x28, 0xc6, 0x14, 0x33, 0x63, 0x5e, 0xa8, 0x80, 0x8b, 0x9a, - 0x42, 0x82, 0x36, 0x60, 0x01, 0xfb, 0x11, 0xeb, 0x3b, 0x8c, 0xf8, 0x38, 0xec, 0x31, 0x63, 0xa6, - 0x96, 0xab, 0x2f, 0xd8, 0xf3, 0x42, 0x78, 0x24, 0x65, 0xe8, 0x06, 0x54, 0x3d, 0x1c, 0xb9, 0x31, - 0xeb, 0xc5, 0x38, 0x35, 0x04, 0x61, 0xb8, 0x9c, 0x2a, 0x12, 0xe3, 0xeb, 0xb0, 0xec, 0xbb, 0x2f, - 0x1d, 0x2e, 0x25, 0x6d, 0x12, 0xb9, 0x01, 0xa3, 0xc6, 0xac, 0xb0, 0x5d, 0xf2, 0xdd, 0x97, 0x4d, - 0x4d, 0x8c, 0x2c, 0x98, 0x0b, 0x42, 0x0f, 0x3b, 0xc4, 0x33, 0xf2, 0xbc, 0xb2, 0x9d, 0xf2, 0x8f, - 0xcd, 0x22, 0x97, 0xec, 0xef, 0xda, 0xf2, 0x5f, 0x0f, 0x3d, 0x80, 0x92, 0x8f, 0x99, 0xeb, 0xb9, - 0xcc, 0x35, 0x0a, 0xc2, 0xe8, 0xda, 0x77, 0xcd, 0xcb, 0xf7, 0x62, 0xec, 0xb9, 0x6d, 0x86, 0xbd, - 0x5a, 0xfd, 0xd5, 0xab, 0x5a, 0xe3, 0x90, 0x7c, 0x8d, 0x6b, 0xaf, 0x5f, 0xd7, 0x5a, 0x7d, 0x86, - 0xe9, 0xf5, 0xfb, 0xbf, 0x34, 0x73, 0x76, 0xea, 0x85, 0xee, 0x42, 0x9e, 0xb9, 0x1d, 0x6a, 0x2c, - 0xd5, 0x66, 0xeb, 0x95, 0xcd, 0x6b, 0x0d, 0x05, 0x78, 0x63, 0x0c, 0xc1, 0xc6, 0x91, 0xdb, 0xa1, - 0x7b, 0x01, 0x8b, 0xfb, 0xb6, 0xf0, 0x40, 0x37, 0xa0, 0x28, 0xbf, 0x95, 0x51, 0xac, 0xe5, 0xea, - 0x95, 0xcd, 0x95, 0xd4, 0x97, 0x7b, 0xed, 0x09, 0x95, 0xad, 0x4c, 0xd0, 0x7f, 0xa0, 0xea, 0x93, - 0xc0, 0x89, 0xba, 0x6e, 0x3f, 0xec, 0x31, 0xc7, 0xc3, 0x5d, 0xb7, 0x6f, 0xcc, 0xa9, 0x8b, 0x93, - 0xa0, 0x29, 0xe5, 0xbb, 0x5c, 0x2c, 0x6c, 0x39, 0x46, 0x43, 0xb6, 0xa5, 0x01, 0x48, 0xba, 0xed, - 0x55, 0x98, 0xa7, 0xfd, 0xa0, 0xed, 0x50, 0x16, 0x63, 0xd7, 0xa7, 0x46, 0xb9, 0x96, 0xab, 0x97, - 0xec, 0x0a, 0x97, 0x1d, 0x4a, 0x11, 0xfa, 0x27, 0x2c, 0xc6, 0x98, 0x07, 0x73, 0x70, 0xe0, 0xb6, - 0xba, 0xd8, 0x33, 0x16, 0x84, 0xd1, 0x82, 0x94, 0xee, 0x49, 0x21, 0xda, 0x84, 0xa2, 0x68, 0x32, - 0x6a, 0x2c, 0x0a, 0x28, 0xcc, 0xa1, 0xeb, 0x6c, 0x73, 0xd5, 0xae, 0x6a, 0x3f, 0x5b, 0x59, 0x9a, - 0x77, 0xa0, 0x9c, 0xa2, 0x82, 0x96, 0x61, 0xf6, 0x04, 0xf7, 0x55, 0x83, 0xf1, 0x3f, 0xd1, 0x2a, - 0x14, 0x4e, 0xdd, 0x6e, 0x0f, 0x8b, 0xb6, 0x29, 0xdb, 0xf2, 0xb0, 0x35, 0x73, 0x37, 0x67, 0xfd, - 0x90, 0x03, 0x18, 0xa0, 0x84, 0xee, 0x40, 0x9e, 0x77, 0x9d, 0xf0, 0xad, 0x6c, 0x6e, 0x0c, 0x65, - 0x7e, 0x18, 0xfa, 0x51, 0x48, 0x09, 0xc3, 0x0a, 0x51, 0xf9, 0x35, 0x6c, 0xe1, 0x80, 0x1e, 0x40, - 0x45, 0x6b, 0x25, 0xd1, 0x49, 0x95, 0xcd, 0xcb, 0xa9, 0xff, 0x76, 0x8f, 0x85, 0x5a, 0x4f, 0xa9, - 0x08, 0xba, 0x0b, 0xfa, 0x1f, 0x14, 0x59, 0xec, 0xb6, 0x4f, 0xa8, 0x28, 0xb2, 0xb2, 0x69, 0x0c, - 0x39, 0x1f, 0x71, 0x55, 0xf2, 0x29, 0xa5, 0x9d, 0xf5, 0x18, 0xca, 0x29, 0x22, 0x68, 0x0b, 0x20, - 0x19, 0x4a, 0x4c, 0x8d, 0xdc, 0x5b, 0x91, 0xd3, 0xac, 0xad, 0x3a, 0x2c, 0x3f, 0x25, 0x94, 0x71, - 0xa3, 0xe4, 0x5a, 0x1c, 0x32, 0x3e, 0x9a, 0x32, 0x54, 0xd9, 0x96, 0x07, 0xeb, 0x2e, 0x54, 0x35, - 0x4b, 0x1a, 0x85, 0x01, 0xc5, 0x68, 0x03, 0x0a, 0x1c, 0x83, 0x24, 0xeb, 0xc2, 0x50, 0x56, 0x5b, - 0xea, 0xac, 0x7f, 0x43, 0x75, 0x17, 0x77, 0xf1, 0xd8, 0x2e, 0x48, 0xe1, 0x2e, 0x4b, 0x24, 0xad, - 0x55, 0x40, 0xba, 0xa1, 0xcc, 0x61, 0xdd, 0x84, 0x0b, 0x3c, 0xb1, 0x3e, 0x97, 0xd3, 0x82, 0x7c, - 0x06, 0xc6, 0xb8, 0xb9, 0x2a, 0xf7, 0x1e, 0xcc, 0x0f, 0x4d, 0xbd, 0xac, 0x7a, 0x00, 0xb7, 0xe6, - 0xb4, 0x1f, 0x3c, 0x0b, 0xed, 0x21, 0x6b, 0xeb, 0x39, 0x5c, 0xe0, 0x85, 0xe9, 0x46, 0x1e, 0x0e, - 0x18, 0x61, 0xfd, 0xac, 0x42, 0x90, 0x09, 0x25, 0xa2, 0xf4, 0xaa, 0xf9, 0xd2, 0x33, 0xfa, 0x17, - 0x2c, 0xc5, 0xf8, 0x34, 0x3c, 0xc1, 0x0e, 0x0b, 0x4f, 0x70, 0xe0, 0xa8, 0x0d, 0x34, 0xcb, 0x07, - 0x82, 0x8b, 0x8f, 0xb8, 0xf4, 0x88, 0x5a, 0xeb, 0xb0, 0x66, 0x63, 0x3f, 0x3c, 0xc5, 0x5a, 0xd2, - 0x14, 0x98, 0x3e, 0xac, 0x1e, 0xf4, 0x24, 0x58, 0xa2, 0x47, 0xa6, 0xa0, 0x32, 0xb5, 0x98, 0x75, - 0x28, 0x8b, 0xb6, 0x72, 0x28, 0xf1, 0x44, 0x19, 0x65, 0xbb, 0x24, 0x04, 0x87, 0xc4, 0xe3, 0xcd, - 0xe0, 0xf7, 0x18, 0x96, 0xfb, 0xaf, 0x64, 0xcb, 0x83, 0xb5, 0x0d, 0xe7, 0x46, 0x52, 0x2b, 0x84, - 0xeb, 0x50, 0x10, 0xae, 0x6a, 0x8c, 0x50, 0x0a, 0xad, 0x30, 0x13, 0xa0, 0x4a, 0x03, 0xeb, 0xe7, - 0x59, 0x30, 0x3e, 0x89, 0x3c, 0x97, 0x0d, 0xdf, 0xed, 0x6c, 0x57, 0xd0, 0x77, 0xf0, 0xec, 0x99, - 0x76, 0xf0, 0x7d, 0x80, 0x08, 0xc7, 0x3e, 0xa1, 0x94, 0x84, 0x81, 0xb8, 0xac, 0x3e, 0xc4, 0x5a, - 0x89, 0xcd, 0xd4, 0xca, 0xd6, 0x3c, 0xf8, 0x0e, 0x17, 0x6f, 0xdb, 0xfb, 0xbc, 0x00, 0xf2, 0x05, - 0x7c, 0x01, 0xe0, 0x32, 0x16, 0x93, 0x56, 0x8f, 0x61, 0xbe, 0xc7, 0x79, 0x4b, 0xde, 0x4e, 0x33, - 0x4f, 0x82, 0xa8, 0xb1, 0x9d, 0xfa, 0x88, 0xd5, 0xf7, 0x8e, 0x29, 0xb5, 0x54, 0xe6, 0x87, 0xb0, - 0x34, 0x12, 0xe4, 0xbd, 0xf6, 0xe7, 0xaf, 0x39, 0x30, 0x65, 0x75, 0x87, 0xbd, 0x16, 0x6d, 0xc7, - 0x44, 0x32, 0x80, 0xb3, 0x7e, 0xc2, 0x4b, 0x00, 0x69, 0x17, 0xf2, 0x69, 0xe0, 0xab, 0xa7, 0x9c, - 0xb4, 0x21, 0x45, 0x17, 0xa1, 0x4c, 0x65, 0x9a, 0x16, 0x56, 0xbd, 0x38, 0x10, 0xa0, 0x7d, 0x40, - 0xda, 0xa8, 0x3a, 0x6a, 0x9b, 0x16, 0x46, 0x56, 0xa1, 0x86, 0xa2, 0x68, 0x47, 0x6a, 0x57, 0xa3, - 0x51, 0x91, 0x75, 0x09, 0xd6, 0x33, 0x6f, 0xa5, 0x86, 0xee, 0xcd, 0x0c, 0x2c, 0x1d, 0xe2, 0xc0, - 0xdb, 0x75, 0x99, 0x3b, 0xed, 0xaa, 0x08, 0xf2, 0xa2, 0x1b, 0xf9, 0x35, 0xe7, 0x6d, 0xf1, 0x37, - 0xfa, 0x2f, 0xe4, 0x4f, 0x48, 0x20, 0x67, 0x6c, 0x51, 0x5b, 0x3b, 0x3c, 0x56, 0xd3, 0x6d, 0x9f, - 0x60, 0xd6, 0x78, 0x42, 0x02, 0xcf, 0x16, 0x56, 0xe8, 0x26, 0x2c, 0x7b, 0x98, 0x32, 0x12, 0xb8, - 0xbc, 0x02, 0x09, 0x4b, 0x9e, 0xc3, 0xb2, 0x33, 0x63, 0xe4, 0xec, 0x25, 0x4d, 0x27, 0x00, 0xfa, - 0x00, 0xce, 0xeb, 0xe6, 0x0a, 0x57, 0xa2, 0x5a, 0xaa, 0x6c, 0x9f, 0xd3, 0xb4, 0xfb, 0xa9, 0x12, - 0xad, 0x41, 0x81, 0x85, 0x11, 0x69, 0xcb, 0xc6, 0xfd, 0xf8, 0x1f, 0xb6, 0x3c, 0xbe, 0xc9, 0xe5, - 0xc4, 0x3b, 0x10, 0x06, 0x6d, 0x2c, 0x38, 0xc2, 0xbc, 0x2d, 0x0f, 0x3b, 0x25, 0x28, 0x3a, 0xc2, - 0xc4, 0x42, 0xb0, 0x3c, 0x40, 0x42, 0xc1, 0xf3, 0x1c, 0xd6, 0x24, 0x7a, 0x7c, 0x35, 0x1c, 0xa8, - 0xe1, 0x9a, 0x86, 0x93, 0x3e, 0xb9, 0x33, 0x67, 0x99, 0x5c, 0xeb, 0xfb, 0x3c, 0x54, 0xe5, 0x23, - 0x1d, 0x3c, 0x23, 0x9d, 0x5e, 0x2c, 0x6e, 0x98, 0xc9, 0x35, 0xcf, 0x4e, 0x25, 0x67, 0xdf, 0x83, - 0x4a, 0xe6, 0xb3, 0xa9, 0xa4, 0x7e, 0xd1, 0xca, 0x99, 0x56, 0xd4, 0x80, 0xec, 0x15, 0xfe, 0xd6, - 0x64, 0x6f, 0xc0, 0xe2, 0xe0, 0x5d, 0x59, 0x5c, 0x4a, 0x81, 0xe7, 0x47, 0x28, 0xf0, 0xd8, 0x87, - 0x1d, 0xa5, 0xc0, 0x67, 0xe7, 0x7f, 0xa7, 0xb0, 0xf6, 0x28, 0x8c, 0x5f, 0xb8, 0xb1, 0xf7, 0x27, - 0x3c, 0x40, 0xd7, 0x87, 0x87, 0x55, 0xf8, 0xca, 0xa7, 0x54, 0x1f, 0x54, 0x7e, 0x1b, 0xeb, 0x22, - 0x98, 0x59, 0x79, 0xd5, 0x00, 0x51, 0x38, 0x7f, 0x30, 0xfa, 0xde, 0xff, 0xe5, 0x25, 0xad, 0xc1, - 0x85, 0x83, 0x09, 0x24, 0xe3, 0xa7, 0x1c, 0x54, 0x9b, 0x38, 0x7e, 0x16, 0xc6, 0xbe, 0x1d, 0xb5, - 0xa7, 0xd5, 0x72, 0x1b, 0x56, 0x33, 0x16, 0x50, 0x52, 0xd7, 0xca, 0xf8, 0xfa, 0xe9, 0xa3, 0xf3, - 0x50, 0xf4, 0x31, 0x3b, 0x0e, 0x13, 0xda, 0xa1, 0x4e, 0xc8, 0x80, 0xb9, 0xc8, 0xed, 0x77, 0x43, - 0x57, 0xfd, 0xec, 0xb2, 0x93, 0x23, 0x6a, 0xc0, 0x4a, 0xac, 0x4a, 0x4b, 0x86, 0xd3, 0xf1, 0xe5, - 0x40, 0x2c, 0xd8, 0xd5, 0x44, 0xa5, 0xc6, 0xf3, 0x80, 0x5a, 0x0d, 0x40, 0x7a, 0xf5, 0x8a, 0xa5, - 0x68, 0xf1, 0x73, 0x43, 0xf1, 0x37, 0x7f, 0x2b, 0x41, 0x85, 0x43, 0x72, 0x88, 0xe3, 0x53, 0xd2, - 0xc6, 0xe8, 0x0e, 0xc0, 0xe0, 0x57, 0x18, 0x32, 0x27, 0xff, 0x34, 0x33, 0x87, 0xb9, 0x2f, 0xda, - 0x81, 0x72, 0x4a, 0x97, 0xd1, 0x5a, 0xaa, 0x1b, 0x25, 0xdb, 0xa6, 0x99, 0xa5, 0x52, 0x65, 0xee, - 0x01, 0x0c, 0xf8, 0xb0, 0x96, 0x7c, 0x8c, 0x4d, 0x9b, 0xeb, 0x99, 0x3a, 0x15, 0xe6, 0x53, 0xc9, - 0xf1, 0x87, 0xb6, 0x51, 0x6d, 0x28, 0x6d, 0x06, 0xb7, 0x36, 0xaf, 0x4e, 0xb1, 0x50, 0x81, 0x9f, - 0xc2, 0xe2, 0x63, 0xac, 0xab, 0xb4, 0xb0, 0x13, 0x98, 0xb2, 0x39, 0x91, 0x6c, 0xa3, 0xcf, 0xa1, - 0x3a, 0xc6, 0x75, 0xdf, 0x21, 0xa0, 0x35, 0xb0, 0x98, 0xc4, 0x94, 0xd1, 0x21, 0x20, 0x4e, 0x57, - 0x9b, 0xbd, 0x56, 0x97, 0xd0, 0x63, 0xec, 0x89, 0xa7, 0x1e, 0x5d, 0x4a, 0x3d, 0xb3, 0x68, 0xb4, - 0x79, 0x79, 0x92, 0x5a, 0x05, 0x6d, 0x42, 0x75, 0x8c, 0x9c, 0xa1, 0xab, 0x6f, 0x25, 0x6e, 0x53, - 0x10, 0xf8, 0x0a, 0x56, 0x32, 0xa8, 0x07, 0xda, 0x18, 0x89, 0x99, 0x45, 0xb7, 0xcc, 0x6b, 0xd3, - 0x8d, 0x54, 0xcd, 0x1f, 0x41, 0x29, 0x79, 0xb2, 0xd1, 0xa0, 0x8e, 0x11, 0x3e, 0x63, 0xae, 0x65, - 0x68, 0x54, 0x80, 0xc7, 0x80, 0xc6, 0xdf, 0x77, 0x64, 0x8d, 0x24, 0xcf, 0x78, 0xfc, 0x47, 0xe7, - 0xe3, 0x4b, 0x40, 0xe3, 0x5b, 0x50, 0x0b, 0x34, 0x71, 0x35, 0x9b, 0x1b, 0x53, 0x6d, 0x54, 0x9d, - 0x47, 0xb0, 0x34, 0xb2, 0xd1, 0xd0, 0x95, 0xc1, 0xf7, 0xcc, 0x5c, 0xb0, 0x66, 0x6d, 0xb2, 0xc1, - 0x60, 0x20, 0x07, 0xdb, 0x44, 0x1b, 0xc8, 0xb1, 0x05, 0xa9, 0x0d, 0xe4, 0xf8, 0xfa, 0xd9, 0x79, - 0xf4, 0xc5, 0x46, 0x87, 0xb0, 0xe3, 0x5e, 0xab, 0xd1, 0x0e, 0xfd, 0x5b, 0xca, 0xf0, 0x96, 0xf8, - 0x9f, 0xb3, 0x76, 0xd8, 0x4d, 0x04, 0xdf, 0xce, 0x2c, 0x3c, 0x25, 0xa7, 0xf8, 0x09, 0x8f, 0xc1, - 0x55, 0xbf, 0xcf, 0x2c, 0xaa, 0xf3, 0xd6, 0x96, 0x10, 0xb4, 0x8a, 0xc2, 0xe5, 0xff, 0x7f, 0x04, - 0x00, 0x00, 0xff, 0xff, 0x6d, 0xbd, 0x61, 0x8a, 0xeb, 0x13, 0x00, 0x00, + // 1642 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0xdd, 0x6e, 0xdb, 0xc8, + 0x15, 0xae, 0x6c, 0x49, 0x96, 0x8e, 0x2c, 0xdb, 0x1a, 0x3b, 0x0e, 0x4d, 0xe7, 0x47, 0xa1, 0xd3, + 0x56, 0x69, 0x1a, 0xa5, 0x51, 0x51, 0x24, 0x30, 0xd2, 0x34, 0x76, 0xec, 0xa4, 0x46, 0x62, 0x40, + 0xa0, 0x5d, 0xa4, 0x2d, 0x50, 0xb0, 0x94, 0x38, 0x91, 0x09, 0x89, 0x1c, 0x86, 0x33, 0x72, 0xa2, + 0x06, 0xb9, 0xcf, 0xb3, 0xf4, 0xb2, 0x77, 0x2d, 0x8a, 0xc5, 0x3e, 0xc4, 0xee, 0x0b, 0xec, 0xdd, + 0xee, 0x53, 0x2c, 0xe6, 0x87, 0xd4, 0xe8, 0x37, 0x89, 0xb1, 0x01, 0xf6, 0xca, 0x9a, 0x73, 0xbe, + 0x33, 0x73, 0xe6, 0xe3, 0x39, 0x87, 0x1f, 0x0d, 0xa8, 0xe7, 0x9f, 0xe3, 0xae, 0xcf, 0x9c, 0x98, + 0x90, 0xa0, 0x1e, 0xc5, 0x84, 0x11, 0xb4, 0xa4, 0x6c, 0xe6, 0x46, 0xe2, 0x0c, 0x88, 0x87, 0x7b, + 0x54, 0xba, 0x87, 0x56, 0xdc, 0x89, 0x31, 0x4d, 0xac, 0x57, 0x12, 0xab, 0xdb, 0xc1, 0x21, 0x73, + 0x3c, 0x9f, 0x46, 0x2e, 0x6b, 0x9f, 0xa5, 0x31, 0xa4, 0xd3, 0xc1, 0xf1, 0x5d, 0x12, 0x31, 0x9f, + 0x84, 0x2a, 0xc6, 0xfa, 0x36, 0x07, 0x95, 0x27, 0x31, 0x76, 0x19, 0xb6, 0x09, 0x09, 0x6c, 0xfc, + 0xba, 0x8f, 0x29, 0x43, 0x08, 0xb2, 0xa1, 0x1b, 0x60, 0x23, 0x53, 0xcd, 0xd4, 0x8a, 0xb6, 0xf8, + 0x8d, 0xae, 0x43, 0x89, 0x27, 0xe8, 0x44, 0x31, 0xa6, 0x98, 0x19, 0xcb, 0xc2, 0x05, 0xdc, 0xd4, + 0x14, 0x16, 0xb4, 0x03, 0x65, 0x1c, 0x44, 0x6c, 0xe0, 0x30, 0x3f, 0xc0, 0xa4, 0xcf, 0x8c, 0x85, + 0x6a, 0xa6, 0x56, 0xb6, 0x97, 0x85, 0xf1, 0x54, 0xda, 0xd0, 0x6d, 0xa8, 0x78, 0x38, 0x72, 0x63, + 0xd6, 0x8f, 0x71, 0x0a, 0x04, 0x01, 0x5c, 0x4b, 0x1d, 0x09, 0xf8, 0x16, 0xac, 0x05, 0xee, 0x5b, + 0x87, 0x5b, 0xfd, 0xb6, 0x1f, 0xb9, 0x21, 0xa3, 0xc6, 0xa2, 0xc0, 0xae, 0x06, 0xee, 0xdb, 0xa6, + 0x66, 0x46, 0x16, 0x2c, 0x85, 0xc4, 0xc3, 0x8e, 0xef, 0x19, 0x59, 0x9e, 0xd9, 0x7e, 0xf1, 0x7f, + 0xcd, 0x3c, 0xb7, 0x1c, 0x1d, 0xd8, 0xf2, 0xaf, 0x87, 0x1e, 0x43, 0x21, 0xc0, 0xcc, 0xf5, 0x5c, + 0xe6, 0x1a, 0x39, 0x01, 0xba, 0xf9, 0x9f, 0xe6, 0xb5, 0x87, 0x31, 0xf6, 0xdc, 0x36, 0xc3, 0x5e, + 0xb5, 0xf6, 0xee, 0x5d, 0xb5, 0x7e, 0xe2, 0xff, 0x0b, 0x57, 0xdf, 0xbf, 0xaf, 0xb6, 0x06, 0x0c, + 0xd3, 0x5b, 0x8f, 0xbe, 0x6e, 0x66, 0xec, 0x34, 0x0a, 0x3d, 0x80, 0x2c, 0x73, 0x3b, 0xd4, 0x58, + 0xad, 0x2e, 0xd6, 0x4a, 0x8d, 0x9b, 0x75, 0x45, 0x78, 0x7d, 0x82, 0xc1, 0xfa, 0xa9, 0xdb, 0xa1, + 0x87, 0x21, 0x8b, 0x07, 0xb6, 0x88, 0x40, 0xb7, 0x21, 0x2f, 0x9f, 0x95, 0x91, 0xaf, 0x66, 0x6a, + 0xa5, 0xc6, 0x7a, 0x1a, 0xcb, 0xa3, 0x0e, 0x85, 0xcb, 0x56, 0x10, 0xf4, 0x1b, 0xa8, 0x04, 0x7e, + 0xe8, 0x44, 0x3d, 0x77, 0x40, 0xfa, 0xcc, 0xf1, 0x70, 0xcf, 0x1d, 0x18, 0x4b, 0xea, 0xe2, 0x7e, + 0xd8, 0x94, 0xf6, 0x03, 0x6e, 0x16, 0x58, 0xce, 0xd1, 0x08, 0xb6, 0x30, 0x24, 0x49, 0xc7, 0xde, + 0x80, 0x65, 0x3a, 0x08, 0xdb, 0x0e, 0x65, 0x31, 0x76, 0x03, 0x6a, 0x14, 0xab, 0x99, 0x5a, 0xc1, + 0x2e, 0x71, 0xdb, 0x89, 0x34, 0xa1, 0x5f, 0xc2, 0x4a, 0x8c, 0xf9, 0x66, 0x0e, 0x0e, 0xdd, 0x56, + 0x0f, 0x7b, 0x46, 0x59, 0x80, 0xca, 0xd2, 0x7a, 0x28, 0x8d, 0xa8, 0x01, 0x79, 0x51, 0x64, 0xd4, + 0x58, 0x11, 0x54, 0x98, 0x23, 0xd7, 0xd9, 0xe3, 0xae, 0x03, 0x55, 0x7e, 0xb6, 0x42, 0xa2, 0x06, + 0x14, 0xde, 0xe0, 0xd6, 0x19, 0x21, 0x5d, 0x6a, 0xac, 0x89, 0xa8, 0xcd, 0x34, 0xea, 0xa5, 0x74, + 0x3c, 0x21, 0xe1, 0x2b, 0xbf, 0x63, 0xa7, 0x38, 0xf3, 0x3e, 0x14, 0x53, 0x26, 0xd1, 0x1a, 0x2c, + 0x76, 0xf1, 0x40, 0x15, 0x25, 0xff, 0x89, 0x36, 0x20, 0x77, 0xee, 0xf6, 0xfa, 0x58, 0x94, 0x5a, + 0xd1, 0x96, 0x8b, 0xdd, 0x85, 0x07, 0x19, 0xeb, 0xbf, 0x19, 0x80, 0x21, 0xb3, 0xe8, 0x3e, 0x64, + 0x79, 0xa5, 0x8a, 0xd8, 0x52, 0x63, 0x67, 0x24, 0xdb, 0x27, 0x24, 0x88, 0x08, 0xf5, 0x19, 0x56, + 0x4f, 0x41, 0x3e, 0x41, 0x5b, 0x04, 0xa0, 0xc7, 0x50, 0xd2, 0xca, 0x4f, 0x54, 0x5f, 0xa9, 0x71, + 0x2d, 0x8d, 0xdf, 0xeb, 0x33, 0xa2, 0xd5, 0xa1, 0xda, 0x41, 0x0f, 0x41, 0xbf, 0x83, 0x3c, 0x8b, + 0xdd, 0x76, 0x97, 0x8a, 0x24, 0x4b, 0x0d, 0x63, 0x24, 0xf8, 0x94, 0xbb, 0x92, 0xc7, 0x2f, 0x71, + 0xd6, 0x33, 0x28, 0xa6, 0x2c, 0xa2, 0x5d, 0x80, 0xa4, 0x91, 0x31, 0x35, 0x32, 0x1f, 0x65, 0x5b, + 0x43, 0x5b, 0x35, 0x58, 0x7b, 0xe1, 0x53, 0xc6, 0x41, 0xc9, 0xb5, 0x38, 0x65, 0xbc, 0x9d, 0xe5, + 0x56, 0x45, 0x5b, 0x2e, 0xac, 0x07, 0x50, 0xd1, 0x90, 0x34, 0x22, 0x21, 0xc5, 0x68, 0x07, 0x72, + 0x9c, 0x83, 0xe4, 0xd4, 0xf2, 0xc8, 0xa9, 0xb6, 0xf4, 0x59, 0xbf, 0x86, 0xca, 0x01, 0xee, 0xe1, + 0x89, 0xf9, 0x91, 0xd2, 0x5d, 0x94, 0x4c, 0x5a, 0x1b, 0x80, 0x74, 0xa0, 0x3c, 0xc3, 0xba, 0x03, + 0x97, 0xf9, 0xc1, 0x7a, 0x2f, 0xcf, 0xdb, 0xe4, 0xaf, 0x60, 0x4c, 0xc2, 0x55, 0xba, 0x0f, 0x61, + 0x79, 0x64, 0x52, 0xc8, 0xac, 0x87, 0x74, 0x6b, 0x41, 0x47, 0xe1, 0x2b, 0x62, 0x8f, 0xa0, 0xad, + 0xd7, 0x70, 0x99, 0x27, 0xa6, 0x83, 0x3c, 0x1c, 0x32, 0x9f, 0x0d, 0xa6, 0x25, 0x82, 0x4c, 0x28, + 0xf8, 0xca, 0xaf, 0x8a, 0x2f, 0x5d, 0xa3, 0x5f, 0xc1, 0x6a, 0x8c, 0xcf, 0x49, 0x17, 0x3b, 0x8c, + 0x74, 0x71, 0xe8, 0xa8, 0xa9, 0xb5, 0xc8, 0x9b, 0x88, 0x9b, 0x4f, 0xb9, 0xf5, 0x94, 0x5a, 0xdb, + 0xb0, 0x65, 0xe3, 0x80, 0x9c, 0x63, 0xed, 0xd0, 0x94, 0x98, 0x01, 0x6c, 0x1c, 0xf7, 0x25, 0x59, + 0xa2, 0x46, 0xe6, 0xb0, 0x32, 0x37, 0x99, 0x6d, 0x28, 0x8a, 0xb2, 0x72, 0xa8, 0xef, 0x89, 0x34, + 0x8a, 0x76, 0x41, 0x18, 0x4e, 0x7c, 0x8f, 0x17, 0x43, 0xd0, 0x67, 0x58, 0xce, 0xcc, 0x82, 0x2d, + 0x17, 0xd6, 0x1e, 0x5c, 0x1a, 0x3b, 0x5a, 0x31, 0x5c, 0x83, 0x9c, 0x08, 0x55, 0x6d, 0x84, 0x52, + 0x6a, 0x05, 0x4c, 0x90, 0x2a, 0x01, 0xd6, 0x57, 0x8b, 0x60, 0xfc, 0x25, 0xf2, 0x5c, 0x36, 0x7a, + 0xb7, 0x8b, 0x5d, 0x41, 0x9f, 0xdb, 0x8b, 0x17, 0x9a, 0xdb, 0x8f, 0x00, 0x22, 0x1c, 0x07, 0x3e, + 0xa5, 0x3e, 0x09, 0xc5, 0x65, 0xf5, 0x26, 0xd6, 0x52, 0x6c, 0xa6, 0x28, 0x5b, 0x8b, 0xe0, 0x73, + 0x5f, 0xbc, 0x0f, 0x3f, 0xe7, 0xad, 0x21, 0xdf, 0x9a, 0x6f, 0x00, 0x5c, 0xc6, 0x62, 0xbf, 0xd5, + 0x67, 0x98, 0xcf, 0x7e, 0x5e, 0x92, 0xf7, 0xd2, 0x93, 0x67, 0x51, 0x54, 0xdf, 0x4b, 0x63, 0xc4, + 0xe8, 0xfb, 0xc4, 0x23, 0xb5, 0xa3, 0xcc, 0x3f, 0xc2, 0xea, 0xd8, 0x26, 0x9f, 0x35, 0x3f, 0xbf, + 0xc9, 0x80, 0x29, 0xb3, 0x3b, 0xe9, 0xb7, 0x68, 0x3b, 0xf6, 0xa5, 0x6a, 0xb8, 0xe8, 0x23, 0xbc, + 0x0a, 0x90, 0x56, 0x21, 0xef, 0x06, 0x3e, 0x7a, 0x8a, 0x49, 0x19, 0x52, 0x74, 0x05, 0x8a, 0x54, + 0x1e, 0xd3, 0xc2, 0xaa, 0x16, 0x87, 0x06, 0x74, 0x04, 0x48, 0x6b, 0x55, 0x47, 0x4d, 0xd3, 0xdc, + 0xd8, 0x28, 0xd4, 0x58, 0x14, 0xe5, 0x48, 0xed, 0x4a, 0x34, 0x6e, 0xb2, 0xae, 0xc2, 0xf6, 0xd4, + 0x5b, 0xa9, 0xa6, 0xfb, 0xb0, 0x00, 0xab, 0x27, 0x38, 0xf4, 0x0e, 0x5c, 0xe6, 0xce, 0xbb, 0x2a, + 0x82, 0xac, 0xa8, 0x46, 0x7e, 0xcd, 0x65, 0x5b, 0xfc, 0x46, 0xbf, 0x85, 0x6c, 0xd7, 0x0f, 0x65, + 0x8f, 0xad, 0x68, 0x63, 0x87, 0xef, 0xd5, 0x74, 0xdb, 0x5d, 0xcc, 0xea, 0xcf, 0xfd, 0xd0, 0xb3, + 0x05, 0x0a, 0xdd, 0x81, 0x35, 0x0f, 0x53, 0xe6, 0x87, 0x2e, 0xcf, 0x40, 0xd2, 0x92, 0xe5, 0xb4, + 0xec, 0x2f, 0x18, 0x19, 0x7b, 0x55, 0xf3, 0x09, 0x82, 0xfe, 0x00, 0x9b, 0x3a, 0x5c, 0xf1, 0xea, + 0xab, 0x92, 0x2a, 0xda, 0x97, 0x34, 0xef, 0x51, 0xea, 0x44, 0x5b, 0x90, 0x63, 0x24, 0xf2, 0xdb, + 0xb2, 0x70, 0xff, 0xfc, 0x0b, 0x5b, 0x2e, 0x3f, 0x64, 0x32, 0xe2, 0x3d, 0x40, 0xc2, 0x36, 0x16, + 0xba, 0x62, 0xd9, 0x96, 0x8b, 0xfd, 0x02, 0xe4, 0x1d, 0x01, 0xb1, 0x10, 0xac, 0x0d, 0x99, 0x50, + 0xf4, 0xbc, 0x86, 0x2d, 0xc9, 0x1e, 0x1f, 0x0d, 0xc7, 0xaa, 0xb9, 0xe6, 0xf1, 0xa4, 0x77, 0xee, + 0xc2, 0x45, 0x3a, 0xd7, 0xfa, 0x3e, 0x0b, 0x15, 0xf9, 0x92, 0xe6, 0xca, 0xa0, 0x1f, 0x8b, 0x1b, + 0x4e, 0xd5, 0xa7, 0x17, 0x97, 0x9f, 0x8b, 0x9f, 0x21, 0x3f, 0xb3, 0xd3, 0xe5, 0xa7, 0x7e, 0xd1, + 0xd2, 0x85, 0x46, 0xd4, 0x50, 0x20, 0xe6, 0x7e, 0xd6, 0x02, 0x71, 0xa8, 0xfc, 0xe0, 0x93, 0x95, + 0x5f, 0x22, 0x9b, 0x97, 0xc7, 0x64, 0xf3, 0xc4, 0x83, 0x9d, 0x90, 0xcd, 0xba, 0x66, 0x2c, 0x7f, + 0x69, 0xcd, 0x78, 0x0e, 0x5b, 0x4f, 0x49, 0xfc, 0xc6, 0x8d, 0xbd, 0x9f, 0xe0, 0xa5, 0x75, 0x6b, + 0xb4, 0xc1, 0x45, 0xac, 0x7c, 0xfd, 0xea, 0xcd, 0xcd, 0x19, 0xb0, 0xae, 0x80, 0x39, 0xed, 0x5c, + 0xd5, 0x74, 0x14, 0x36, 0x8f, 0xc7, 0x35, 0xc2, 0x17, 0x4f, 0x69, 0x0b, 0x2e, 0x1f, 0xcf, 0x10, + 0x26, 0xff, 0xcf, 0x40, 0xa5, 0x89, 0xe3, 0x57, 0x24, 0x0e, 0xec, 0xa8, 0x3d, 0x2f, 0x97, 0x7b, + 0xb0, 0x31, 0x65, 0x68, 0x25, 0x79, 0xad, 0x4f, 0x8e, 0xac, 0x01, 0xda, 0x84, 0x7c, 0x80, 0xd9, + 0x19, 0x49, 0xa4, 0x8a, 0x5a, 0x21, 0x03, 0x96, 0x22, 0x77, 0xd0, 0x23, 0xae, 0xfa, 0xbc, 0xb3, + 0x93, 0x25, 0xaa, 0xc3, 0x7a, 0xac, 0x52, 0x4b, 0x1a, 0xda, 0x09, 0x64, 0x13, 0x95, 0xed, 0x4a, + 0xe2, 0x52, 0x2d, 0x7d, 0x4c, 0xad, 0x3a, 0x20, 0x3d, 0x7b, 0xa5, 0x6c, 0xb4, 0xfd, 0x33, 0x23, + 0xfb, 0x37, 0xbe, 0x2b, 0x40, 0x89, 0x53, 0x72, 0x82, 0xe3, 0x73, 0xbf, 0x8d, 0xd1, 0x7d, 0x80, + 0xe1, 0xd7, 0x1e, 0x32, 0x67, 0x7f, 0x02, 0x9a, 0xa3, 0x7a, 0x19, 0xed, 0x43, 0x31, 0x95, 0xd8, + 0x68, 0x2b, 0xf5, 0x8d, 0x0b, 0x74, 0xd3, 0x9c, 0xe6, 0x52, 0x69, 0x1e, 0x02, 0x0c, 0x35, 0xb4, + 0x76, 0xf8, 0x84, 0x02, 0x37, 0xb7, 0xa7, 0xfa, 0xd4, 0x36, 0x2f, 0xe5, 0x77, 0xc1, 0xc8, 0x04, + 0xab, 0x8e, 0x1c, 0x3b, 0x45, 0x8f, 0x9b, 0x37, 0xe6, 0x20, 0xd4, 0xc6, 0x2f, 0x60, 0xe5, 0x19, + 0xd6, 0x5d, 0xda, 0xb6, 0x33, 0xd4, 0xb5, 0x39, 0x53, 0xa0, 0xa3, 0xbf, 0x41, 0x65, 0x42, 0x1f, + 0x7f, 0xc2, 0x86, 0xd6, 0x10, 0x31, 0x4b, 0x5d, 0xa3, 0x13, 0x40, 0x5c, 0xe2, 0x36, 0xfb, 0xad, + 0x9e, 0x4f, 0xcf, 0xb0, 0x27, 0xe4, 0x01, 0xba, 0x9a, 0x46, 0x4e, 0x93, 0xde, 0xe6, 0xb5, 0x59, + 0x6e, 0xb5, 0x69, 0x13, 0x2a, 0x13, 0x82, 0x0e, 0xdd, 0xf8, 0xa8, 0xd8, 0x9b, 0xc3, 0xc0, 0x3f, + 0x61, 0x7d, 0x8a, 0x5c, 0x41, 0x3b, 0x63, 0x7b, 0x4e, 0x93, 0x68, 0xe6, 0xcd, 0xf9, 0x20, 0x95, + 0xf3, 0x9f, 0xa0, 0x90, 0xbc, 0xe6, 0xd1, 0x30, 0x8f, 0x31, 0x0d, 0x64, 0x6e, 0x4d, 0xf1, 0xa8, + 0x0d, 0x9e, 0x01, 0x9a, 0xd4, 0x04, 0xc8, 0x1a, 0x3b, 0x7c, 0x8a, 0x60, 0x18, 0xef, 0x8f, 0x7f, + 0x00, 0x9a, 0x9c, 0x82, 0xda, 0x46, 0x33, 0x47, 0xb3, 0xb9, 0x33, 0x17, 0xa3, 0xf2, 0x3c, 0x85, + 0xd5, 0xb1, 0x89, 0x86, 0xae, 0x0f, 0x9f, 0xe7, 0xd4, 0x01, 0x6b, 0x56, 0x67, 0x03, 0x86, 0x0d, + 0x39, 0x9c, 0x26, 0x5a, 0x43, 0x4e, 0x0c, 0x48, 0xad, 0x21, 0x27, 0xc7, 0xcf, 0xfe, 0xd3, 0xbf, + 0xef, 0x74, 0x7c, 0x76, 0xd6, 0x6f, 0xd5, 0xdb, 0x24, 0xb8, 0xab, 0x80, 0x77, 0xc5, 0x7f, 0xe8, + 0xda, 0xa4, 0x97, 0x18, 0xfe, 0xbd, 0x50, 0x7e, 0xe1, 0x9f, 0xe3, 0xe7, 0x7c, 0x0f, 0xee, 0xfa, + 0x61, 0x61, 0x45, 0xad, 0x77, 0x77, 0x85, 0xa1, 0x95, 0x17, 0x21, 0xbf, 0xff, 0x31, 0x00, 0x00, + 0xff, 0xff, 0x5b, 0x3c, 0xd6, 0x0d, 0x53, 0x14, 0x00, 0x00, } diff --git a/protobufs/livekit_internal.proto b/protobufs/livekit_internal.proto index bdfe70076..90f1da2fe 100644 --- a/protobufs/livekit_internal.proto +++ b/protobufs/livekit_internal.proto @@ -214,6 +214,9 @@ message RoomInternal { bool replay_enabled = 6; bool export_room = 7; map tags = 8; + // room-scoped webhooks, resolved from CreateRoomRequest/RoomConfiguration at + // room creation. Not exposed on the public Room proto: entries carry signing keys. + repeated WebhookConfig webhooks = 9; } enum ICECandidateType { diff --git a/protobufs/livekit_room.proto b/protobufs/livekit_room.proto index 3232438d6..8f49a9416 100644 --- a/protobufs/livekit_room.proto +++ b/protobufs/livekit_room.proto @@ -112,7 +112,11 @@ message CreateRoomRequest { // Define agents that should be dispatched to this room repeated RoomAgentDispatch agents = 14; - // NEXT-ID: 16 + // Optional additional webhook config, scoped to this room. Egress and ingress + // events are never delivered to these; use the egress request webhooks for those. + repeated WebhookConfig webhooks = 16; + + // NEXT-ID: 17 } message RoomEgress { @@ -272,7 +276,10 @@ message RoomConfiguration { // Tags to attach to the room map tags = 12; - // NEXT_ID: 13 + // Optional additional webhook config, scoped to rooms created with this preset + repeated WebhookConfig webhooks = 13; + + // NEXT_ID: 14 } message ForwardParticipantRequest { diff --git a/webhook/room_notify_options.go b/webhook/room_notify_options.go new file mode 100644 index 000000000..ab0a4f5ae --- /dev/null +++ b/webhook/room_notify_options.go @@ -0,0 +1,48 @@ +// Copyright 2026 LiveKit, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package webhook + +import "github.com/livekit/protocol/livekit" + +// roomLevelEvents are the events a room-scoped webhook may receive. Egress, ingress +// and agent events are deliberately excluded: those resources carry their own webhook +// config on the request that created them (see egress.GetEgressNotifyOptions), so +// delivering them here would both duplicate and leak beyond the room's scope. +var roomLevelEvents = map[string]struct{}{ + EventRoomStarted: {}, + EventRoomFinished: {}, + EventParticipantJoined: {}, + EventParticipantLeft: {}, + EventParticipantConnectionAborted: {}, + EventTrackPublished: {}, + EventTrackUnpublished: {}, +} + +// IsRoomLevelEvent reports whether event may be delivered to a room-scoped webhook. +func IsRoomLevelEvent(event string) bool { + _, ok := roomLevelEvents[event] + return ok +} + +// GetRoomNotifyOptions returns the notify options carrying a room's own webhooks +// (RoomInternal.GetWebhooks()), or nil when the room configured none or the event is +// not one a room-scoped webhook may receive. +func GetRoomNotifyOptions(event string, roomWebhooks []*livekit.WebhookConfig) []NotifyOption { + if len(roomWebhooks) == 0 || !IsRoomLevelEvent(event) { + return nil + } + + return []NotifyOption{WithExtraWebhooks(roomWebhooks)} +} diff --git a/webhook/room_notify_options_test.go b/webhook/room_notify_options_test.go new file mode 100644 index 000000000..7e01711ef --- /dev/null +++ b/webhook/room_notify_options_test.go @@ -0,0 +1,62 @@ +// Copyright 2026 LiveKit, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package webhook + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/livekit/protocol/livekit" +) + +func TestGetRoomNotifyOptions(t *testing.T) { + whs := []*livekit.WebhookConfig{{Url: "https://example.com/hook"}} + + roomLevel := []string{ + EventRoomStarted, + EventRoomFinished, + EventParticipantJoined, + EventParticipantLeft, + EventParticipantConnectionAborted, + EventTrackPublished, + EventTrackUnpublished, + } + for _, ev := range roomLevel { + opts := GetRoomNotifyOptions(ev, whs) + require.Len(t, opts, 1, ev) + + p := &NotifyParams{} + opts[0](p) + require.Equal(t, whs, p.ExtraWebhooks, ev) + } + + // egress, ingress and agent events never reach a room webhook + notRoomLevel := []string{ + EventEgressStarted, + EventEgressUpdated, + EventEgressEnded, + EventIngressStarted, + EventIngressEnded, + EventAgentJobStarted, + EventAgentJobEnded, + } + for _, ev := range notRoomLevel { + require.Nil(t, GetRoomNotifyOptions(ev, whs), ev) + } + + // a room with no webhooks configured adds no options + require.Nil(t, GetRoomNotifyOptions(EventRoomStarted, nil)) +}