binwiederhier 1 месяц назад
Родитель
Сommit
94eb121f38
1 измененных файлов с 46 добавлено и 58 удалено
  1. 46 58
      docs/publish.md

+ 46 - 58
docs/publish.md

@@ -946,19 +946,24 @@ _Supported on:_ :material-android: :material-firefox:
 You can **update, clear (mark as read and dismiss), or delete notifications** that have already been delivered. This is useful for scenarios
 You can **update, clear (mark as read and dismiss), or delete notifications** that have already been delivered. This is useful for scenarios
 like download progress updates, replacing outdated information, or dismissing notifications that are no longer relevant.
 like download progress updates, replacing outdated information, or dismissing notifications that are no longer relevant.
 
 
-* Updating notifications will alter the content of an existing notification.
-* Clearing notifications will mark them as read and dismiss them from the notification drawer.
-* Deleting notifications will remove them from the notification drawer and remove them in the clients as well (if supported).
+* [Updating notifications](#updating-notifications) will alter the content of an existing notification.
+* [Clearing notifications](#clearing-notifications) will mark them as read and dismiss them from the notification drawer.
+* [Deleting notifications](#deleting-notifications) will remove them from the notification drawer and remove them in the clients as well (if supported).
 
 
-The way this works is that when you publish a message with a specific **sequence ID**, clients that receive the
-notification will treat it as part of a sequence. When a new message with the same sequence ID is published, clients
-will update the existing notification instead of creating a new one. You can also
+Here's an example of a download progress notification being updated over time on Android:
 
 
 <div id="updating-notifications-screenshots" class="screenshots">
 <div id="updating-notifications-screenshots" class="screenshots">
     <a href="../../static/img/android-screenshot-notification-update-1.png"><img src="../../static/img/android-screenshot-notification-update-1.png"/></a>
     <a href="../../static/img/android-screenshot-notification-update-1.png"><img src="../../static/img/android-screenshot-notification-update-1.png"/></a>
     <a href="../../static/img/android-screenshot-notification-update-2.png"><img src="../../static/img/android-screenshot-notification-update-2.png"/></a>
     <a href="../../static/img/android-screenshot-notification-update-2.png"><img src="../../static/img/android-screenshot-notification-update-2.png"/></a>
 </div>
 </div>
 
 
+To facilitate updating notifications and altering existing notifications, ntfy messages are linked together in a sequence,
+using a **sequence ID**. When a notification is meant to be updated, cleared, or deleted, you publish a new message with the
+same sequence ID and the clients will perform the appropriate action on the existing notification.
+
+Existing ntfy messages will not be updated on the server or in the message cache. Instead, a new message is created that indicates
+the update, clear, or delete action. This append-only behavior ensures that message history remains intact.
+
 ### Updating notifications
 ### Updating notifications
 To update an existing notification, publish a new message with the same sequence ID. Clients will replace the previous
 To update an existing notification, publish a new message with the same sequence ID. Clients will replace the previous
 notification with the new one. You can either:
 notification with the new one. You can either:
@@ -968,7 +973,7 @@ notification with the new one. You can either:
    `X-Sequence-ID` header (or any of its aliases: `Sequence-ID` or`SID`)
    `X-Sequence-ID` header (or any of its aliases: `Sequence-ID` or`SID`)
 
 
 If you don't know the sequence ID ahead of time, you can publish a message first and then use the returned 
 If you don't know the sequence ID ahead of time, you can publish a message first and then use the returned 
-message `id` to update it. The message ID of the first message will then serve as the sequence ID for subsequent updates:
+message `id` to update it. Here's an example:
 
 
 === "Command line (curl)"
 === "Command line (curl)"
     ```bash
     ```bash
@@ -1115,8 +1120,8 @@ message `id` to update it. The message ID of the first message will then serve a
     ]));
     ]));
     ```
     ```
 
 
-You can also use a custom sequence ID (e.g., a download ID, job ID, etc.) when publishing the first message. This is
-less cumbersome, since you don't need to capture the message ID first. Just publish directly to
+You can also use a **custom sequence ID** (e.g., a download ID, job ID, etc.) when publishing the first message. 
+**This is less cumbersome**, since you don't need to capture the message ID first. Just publish directly to
 `/<topic>/<sequence_id>`:
 `/<topic>/<sequence_id>`:
 
 
 === "Command line (curl)"
 === "Command line (curl)"
@@ -1145,12 +1150,13 @@ less cumbersome, since you don't need to capture the message ID first. Just publ
 
 
 === "HTTP"
 === "HTTP"
     ``` http
     ``` http
+    # Publish a message with a custom sequence ID
     POST /mytopic/my-download-123 HTTP/1.1
     POST /mytopic/my-download-123 HTTP/1.1
     Host: ntfy.sh
     Host: ntfy.sh
 
 
     Downloading file...
     Downloading file...
-    ```
-    ``` http
+
+    # Update again using the X-Sequence-ID header
     POST /mytopic HTTP/1.1
     POST /mytopic HTTP/1.1
     Host: ntfy.sh
     Host: ntfy.sh
     X-Sequence-ID: my-download-123
     X-Sequence-ID: my-download-123
@@ -1247,12 +1253,24 @@ less cumbersome, since you don't need to capture the message ID first. Just publ
     ]));
     ]));
     ```
     ```
 
 
-You can also set the sequence ID via the `sid` query parameter, or when [publishing as JSON](#publish-as-json) 
-using the `sequence_id` field.
+You can also set the sequence ID via the `sequence-id` [query parameter](#list-of-all-parameters), or when
+[publishing as JSON](#publish-as-json) using the `sequence_id` field.
+
+If the message ID (`id`) and the sequence ID (`sequence_id`) are different, the ntfy server will include the `sequence_id`
+field the response. A sequence of updates may look like this (first example from above):
+
+```json
+{"id":"xE73Iyuabi","time":1673542291,"event":"message","topic":"mytopic","message":"Downloading file..."}
+{"id":"yF84Jzvbcj","time":1673542295,"event":"message","topic":"mytopic","sequence_id":"xE73Iyuabi","message":"Download 50% ..."}
+{"id":"zG95Kawdde","time":1673542300,"event":"message","topic":"mytopic","sequence_id":"xE73Iyuabi","message":"Download complete"}
+```
 
 
 ### Clearing notifications
 ### Clearing notifications
-To clear a notification (mark it as read and dismiss it from the notification drawer), send a PUT request to
-`/<topic>/<sequence_id>/clear` (or `/<topic>/<sequence_id>/read` as an alias):
+Clearing a notification means **marking it as read and dismissing it from the notification drawer**. 
+
+To do this, send a PUT request to the `/<topic>/<sequence_id>/clear` endpoint (or `/<topic>/<sequence_id>/read` as an alias). 
+This will then emit a `message_clear` event that is used by the clients (web app and Android app) to update the read status
+and dismiss the notification.
 
 
 === "Command line (curl)"
 === "Command line (curl)"
     ```bash
     ```bash
@@ -1295,13 +1313,17 @@ To clear a notification (mark it as read and dismiss it from the notification dr
     ]));
     ]));
     ```
     ```
 
 
-This publishes a `message_clear` event, which tells clients to:
+An example response from the server with the `message_clear` event may look like this:
 
 
-- Mark the notification as read in the app
-- Dismiss the browser/Android notification
+```json
+{"id":"jkl012","time":1673542305,"event":"message_clear","topic":"mytopic","sequence_id":"my-download-123"}
+```
 
 
 ### Deleting notifications
 ### Deleting notifications
-To delete a notification entirely, send a DELETE request to `/<topic>/<sequence_id>`:
+Deleting a notification means **removing it from the notification drawer and from the client's database**.
+
+To do this, send a DELETE request to the `/<topic>/<sequence_id>` endpoint. This will emit a `message_delete` event
+that is used by the clients (web app and Android app) to remove the notification entirely.
 
 
 === "Command line (curl)"
 === "Command line (curl)"
     ```bash
     ```bash
@@ -1344,51 +1366,16 @@ To delete a notification entirely, send a DELETE request to `/<topic>/<sequence_
     ]));
     ]));
     ```
     ```
 
 
-This publishes a `message_delete` event, which tells clients to:
+An example response from the server with the `message_delete` event may look like this:
 
 
-- Delete the notification from the database
-- Dismiss the browser/Android notification
+```json
+{"id":"mno345","time":1673542400,"event":"message_delete","topic":"mytopic","sequence_id":"my-download-123"}
+```
 
 
 !!! info
 !!! info
     Deleted sequences can be revived by publishing a new message with the same sequence ID. The notification will
     Deleted sequences can be revived by publishing a new message with the same sequence ID. The notification will
     reappear as a new message.
     reappear as a new message.
 
 
-### Full example
-Here's a complete example showing the lifecycle of a notification with updates, clearing, and deletion:
-
-```bash
-# 1. Create a notification with a custom sequence ID
-$ curl -d "Starting backup..." ntfy.sh/mytopic/backup-2024
-
-# 2. Update the notification with progress
-$ curl -d "Backup 50% complete..." ntfy.sh/mytopic/backup-2024
-
-# 3. Update again when complete
-$ curl -d "Backup finished successfully!" ntfy.sh/mytopic/backup-2024
-
-# 4. Clear the notification (dismiss from notification drawer)
-$ curl -X PUT ntfy.sh/mytopic/backup-2024/clear
-
-# 5. Later, delete the notification entirely
-$ curl -X DELETE ntfy.sh/mytopic/backup-2024
-```
-
-When polling the topic, you'll see the complete sequence of events:
-
-```bash
-$ curl -s "ntfy.sh/mytopic/json?poll=1&since=all" | jq .
-```
-
-```json
-{"id":"abc123","time":1673542291,"event":"message","topic":"mytopic","sequence_id":"backup-2024","message":"Starting backup..."}
-{"id":"def456","time":1673542295,"event":"message","topic":"mytopic","sequence_id":"backup-2024","message":"Backup 50% complete..."}
-{"id":"ghi789","time":1673542300,"event":"message","topic":"mytopic","sequence_id":"backup-2024","message":"Backup finished successfully!"}
-{"id":"jkl012","time":1673542305,"event":"message_clear","topic":"mytopic","sequence_id":"backup-2024"}
-{"id":"mno345","time":1673542400,"event":"message_delete","topic":"mytopic","sequence_id":"backup-2024"}
-```
-
-Clients process these events in order, keeping only the latest state for each sequence ID.
-
 ## Message templating
 ## Message templating
 _Supported on:_ :material-android: :material-apple: :material-firefox:
 _Supported on:_ :material-android: :material-apple: :material-firefox:
 
 
@@ -4384,6 +4371,7 @@ table in their canonical form.
 |-----------------|--------------------------------------------|-----------------------------------------------------------------------------------------------|
 |-----------------|--------------------------------------------|-----------------------------------------------------------------------------------------------|
 | `X-Message`     | `Message`, `m`                             | Main body of the message as shown in the notification                                         |
 | `X-Message`     | `Message`, `m`                             | Main body of the message as shown in the notification                                         |
 | `X-Title`       | `Title`, `t`                               | [Message title](#message-title)                                                               |
 | `X-Title`       | `Title`, `t`                               | [Message title](#message-title)                                                               |
+| `X-Sequence-ID` | `Sequence-ID`, `SID`                       | [Sequence ID](#updating-deleting-notifications) for updating/clearing/deleting notifications  |
 | `X-Priority`    | `Priority`, `prio`, `p`                    | [Message priority](#message-priority)                                                         |
 | `X-Priority`    | `Priority`, `prio`, `p`                    | [Message priority](#message-priority)                                                         |
 | `X-Tags`        | `Tags`, `Tag`, `ta`                        | [Tags and emojis](#tags-emojis)                                                               |
 | `X-Tags`        | `Tags`, `Tag`, `ta`                        | [Tags and emojis](#tags-emojis)                                                               |
 | `X-Delay`       | `Delay`, `X-At`, `At`, `X-In`, `In`        | Timestamp or duration for [delayed delivery](#scheduled-delivery)                             |
 | `X-Delay`       | `Delay`, `X-At`, `At`, `X-In`, `In`        | Timestamp or duration for [delayed delivery](#scheduled-delivery)                             |