From 3d76da368e157934e056d95b3b3d8d6eaa105b09 Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Tue, 29 Jul 2025 08:41:38 -0300 Subject: [PATCH] nip17: "seen" event. --- 17.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/17.md b/17.md index e9e97ba5..f1f003ba 100644 --- a/17.md +++ b/17.md @@ -8,7 +8,11 @@ Private Direct Messages This NIP defines an encrypted direct messaging scheme using [NIP-44](44.md) encryption and [NIP-59](59.md) seals and gift wraps. -## Direct Message Kind +## Message kinds + +Each of these message kinds can be gift-wrapped as described afterwards. Clients have to first unwrap them to then see their kinds. + +### Direct Message Kind Kind `14` is a chat message. `p` tags identify one or more receivers of the message. @@ -31,7 +35,7 @@ Kind `14` is a chat message. `p` tags identify one or more receivers of the mess `.content` MUST be plain text. Fields `id` and `created_at` are required. -An `e` tag denotes the direct parent message this post is replying to. +An `e` tag denotes the direct parent message this post is replying to. `q` tags MAY be used when citing events in the `.content` with [NIP-21](21.md). @@ -41,7 +45,7 @@ An `e` tag denotes the direct parent message this post is replying to. Kind `14`s MUST never be signed. If it is signed, the message might leak to relays and become **fully public**. -## File Message Kind +### File Message Kind ```jsonc { @@ -59,7 +63,6 @@ Kind `14`s MUST never be signed. If it is signed, the message might leak to rela ["decryption-key", ""], ["decryption-nonce", ""], ["x", ""], - // rest of tags... ], "content": "" } @@ -82,6 +85,46 @@ Kind `15` is used for sending encrypted file event messages: Just like kind `14`, kind `15`s MUST never be signed. +### "Seen" event + +An event of kind `30016` that CAN be emitted automatically by a client whenever a chat window is displayed to the user, even if the user hasn't acted on it. + +```jsonc +{ + "id": "", + "pubkey": "", + "created_at": "", + "kind": 30016, + "tags": [ + ["d", ""], + ["seen", "", "", "<...>"] + ], + "content": "" +} +``` + +- `d` must be set to the conversation subject, or it can be empty or omitted in the most common case of a `` not existing. +- `seen` must be set to the id of the last messages seen. It can contain any number of ids, ordered from the newest to the oldest. + +This event SHOULD be discarded whenever a new event is received for the same conversation. + +Any messages with timestamp before the last item in the `seen` array are assumed to have been seen. + +If there is a gap in the `seen` array that indicates a message may have been missed for whatever reason. + +For example: + +- `alice` sends message `aaaa` +- `alice` sends message `bbbb` +- `alice` sends message `cccc` +- `bob` sends event with `["seen", "bbbb", "aaaa"]` +- at this point `alice`'s client should display `aaaa` and `bbbb` as seen, `cccc` as unseen +- `alice` sends message `dddd` +- `alice` sends message `eeee`, which is lost due to relay malfunction +- `alice` sends message `ffff` +- `bob` sends event with `["seen", "ffff", "dddd", "cccc"]` +- at this point `alice`'s client should display all messages as seen, except for `eeee` which should be displayed with an error indicator + ## Chat Rooms The set of `pubkey` + `p` tags defines a chat room. If a new `p` tag is added or a current one is removed, a new room is created with a clean message history.