diff --git a/53.md b/53.md index 69d1c9f0..d64f3ef3 100644 --- a/53.md +++ b/53.md @@ -129,3 +129,146 @@ Common use cases include meeting rooms/workshops, watch-together activities, or "sig": "997f62ddfc0827c121043074d50cfce7a528e978c575722748629a4137c45b75bdbc84170bedc723ef0a5a4c3daebf1fef2e93f5e2ddb98e5d685d022c30b622" } ``` + +## Interactive Rooms and Meetings +----- + +`draft` `optional` + +Service providers want to offer Interactive Rooms to the Nostr network in such a way that participants can easily log and query by clients. This NIP describes a general framework to advertise rooms and their associated events. + +## Concepts + +### Interactive Room (kind:30312) + +A special event with `kind:30312` "Interactive Room" defines the configuration and properties of a virtual interactive space. Each room has a unique identifier and can host multiple events/meetings. + +```jsonc +{ + "kind": 30312, + "tags": [ + ["d", ""], // Required: Room identifier + ["room", ""], // Required: Display name + ["summary", ""], // Optional: Room description + ["image", ""], // Optional: Room image + ["status", ""], // Required: Room accessibility + ["service", ""], // Required: URL to access the room + ["endpoint", ""], // Optional: API endpoint for status/info + ["t", ""], // Optional: Multiple hashtags allowed + ["p", "", "", "", ""], // Required: At least one provider + ["relays", "", "", /*...*/] // Optional: Preferred relays + ], + "content": "" // Usually empty, may contain additional metadata +} +``` + +Room properties: +* MUST be either open, private or closed. Closed means the room is not in operation. +* MAY specify access control policy for private rooms (e.g. invite-only, payment required) +* MAY persist when not in use +* MUST have at least one provider with "Host" role +* MAY have multiple providers with different roles +Provider roles (p tags): +* Host: Full room management capabilities +* Moderator: Room moderation capabilities +* Speaker: Allowed to present/speak +* Optional proof field for role verification + +### Room Meeting (kind:30313) + +A special event with kind:30313 represents a scheduled or ongoing meeting within a room. It MUST reference its parent room using the d tag. + +```jsonc +{ + "kind": 30313, + "tags": [ + ["d", ""], // Required: Event identifier + ["a", "30312::", "wss://nostr.example.com"], // Required: Reference to parent room, 'd' from 30312 + ["title", ""], // Required: Meeting title + ["summary", ""], // Optional: Meeting description + ["image", ""], // Optional: Meeting image + ["starts", ""], // Required: Start time + ["ends", ""], // Optional: End time + ["status", ""], // Required: Meeting status + ["total_participants", ""], // Optional: Total registered + ["current_participants", ""], // Optional: Currently active + ["p", "", "", ""], // Optional: Participant with role + ], + "content": "" // Usually empty, may contain additional metadata +} +``` + +Event properties: +* MUST reference parent room via d tag +* MUST have a status (planned/live/ended) +* MUST have a start time +* MAY track participant counts +* MAY include participant roles specific to the event +Event management: +* Clients SHOULD update event status regularly when live +* Events without updates for 1 hour MAY be considered ended +* starts and ends timestamps SHOULD be updated when status changes + +Examples + +Interactive Room (kind:30312) + +```jsonc +{ + "kind": 30312, + "tags": [ + ["d", "main-conference-room"], + ["room", "Main Conference Hall"], + ["summary", "Our primary conference space"], + ["image", "https://example.com/room.jpg"], + ["status", "open"], + ["service", "https://meet.example.com/room"], + ["endpoint", "https://api.example.com/room"], + ["t", "conference"], + ["p", "f7234bd4c1394dda46d09f35bd384dd30cc552ad5541990f98844fb06676e9ca", "wss://nostr.example.com/", "Owner"], + ["p", "14aeb..8dad4", "wss://provider2.com/", "Moderator"], + ["relays", "wss://relay1.com", "wss://relay2.com"] + ], + "content": "" +} +``` + +Conference Event (kind:30313) + +```jsonc +{ + "kind": 30313, + "tags": [ + ["d", "annual-meeting-2025"], + ["a", "30312:f7234bd4c1394dda46d09f35bd384dd30cc552ad5541990f98844fb06676e9ca:main-conference-room", "wss://nostr.example.com"] + ["title", "Annual Company Meeting 2025"], + ["summary", "Yearly company-wide meeting"], + ["image", "https://example.com/meeting.jpg"], + ["starts", "1676262123"], + ["ends", "1676269323"], + ["status", "live"], + ["total_participants", "180"], + ["current_participants", "175"], + ["p", "91cf9..4e5ca", "wss://provider1.com/", "Speaker"], + ], + "content": "" +} +``` +## Room Presence + +New `kind: 10312` provides an event which signals presence of a listener. + +The presence event SHOULD be updated at regular intervals and clients SHOULD filter presence events older than +a given time window. + +**This kind `10312` is a regular replaceable event, as such presence can only be indicated in one room at a time.** + +```json +{ + "kind": 10312, + "tags": [ + ["a" , "", "", "root"], + ["hand", "1"] // hand raised flag + ] +} +```