diff --git a/docs/publish.md b/docs/publish.md index fb0b38fb..6d5dca26 100644 --- a/docs/publish.md +++ b/docs/publish.md @@ -937,6 +937,142 @@ Here's an example with a custom message, tags and a priority: file_get_contents('https://ntfy.sh/mywebhook/publish?message=Webhook+triggered&priority=high&tags=warning,skull'); ``` +## Updating + deleting notifications +_Supported on:_ :material-android: :material-firefox: + +!!! info + **This feature is not yet released.** It will be available in ntfy v2.16.x and later and ntfy Android v1.22.x and later. + +You can **update, clear, 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. + +The key concept is the **sequence ID** (`sequence_id` or `sid`): notifications with the same sequence ID are treated as +belonging to the same sequence, and clients will update/replace the notification accordingly. + +
+ + +
+ +### Updating notifications +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: + +1. **Use the message ID**: First publish without a sequence ID, then use the returned message `id` as the sequence ID for updates +2. **Use a custom sequence ID**: Publish directly to `//` with your own identifier + +=== "Using the message ID" + ```bash + # First, publish a message and capture the message ID + $ curl -d "Downloading file..." ntfy.sh/mytopic + {"id":"xE73Iyuabi","time":1673542291,...} + + # Then use the message ID to update it + $ curl -d "Download complete!" ntfy.sh/mytopic/xE73Iyuabi + ``` + +=== "Using a custom sequence ID" + ```bash + # Publish with a custom sequence ID + $ curl -d "Downloading file..." ntfy.sh/mytopic/my-download-123 + + # Update using the same sequence ID + $ curl -d "Download complete!" ntfy.sh/mytopic/my-download-123 + ``` + +=== "Using the X-Sequence-ID header" + ```bash + # Publish with a sequence ID via header + $ curl -H "X-Sequence-ID: my-download-123" -d "Downloading..." ntfy.sh/mytopic + + # Update using the same sequence ID + $ curl -H "X-Sequence-ID: my-download-123" -d "Done!" ntfy.sh/mytopic + ``` + +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. + +### Clearing notifications +To clear a notification (mark it as read and dismiss it from the notification drawer), send a PUT request to +`///clear` (or `///read` as an alias): + +=== "Command line (curl)" + ```bash + curl -X PUT ntfy.sh/mytopic/my-download-123/clear + ``` + +=== "HTTP" + ```http + PUT /mytopic/my-download-123/clear HTTP/1.1 + Host: ntfy.sh + ``` + +This publishes a `message_clear` event, which tells clients to: + +- Mark the notification as read in the app +- Dismiss the browser/Android notification + +### Deleting notifications +To delete a notification entirely, send a DELETE request to `//`: + +=== "Command line (curl)" + ```bash + curl -X DELETE ntfy.sh/mytopic/my-download-123 + ``` + +=== "HTTP" + ```http + DELETE /mytopic/my-download-123 HTTP/1.1 + Host: ntfy.sh + ``` + +This publishes a `message_delete` event, which tells clients to: + +- Delete the notification from the database +- Dismiss the browser/Android notification + +!!! info + Deleted sequences can be revived by publishing a new message with the same sequence ID. The notification will + 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 _Supported on:_ :material-android: :material-apple: :material-firefox: @@ -2695,134 +2831,6 @@ Here's an example that will open Reddit when the notification is clicked: ])); ``` -## Updating + deleting notifications -_Supported on:_ :material-android: :material-firefox: - -You can update, clear (mark as read), 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. - -The key concept is the **sequence ID** (`sequence_id` or `sid`): notifications with the same sequence ID are treated as -belonging to the same sequence, and clients will update/replace the notification accordingly. - -### Updating notifications -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: - -1. **Use the message ID**: First publish without a sequence ID, then use the returned message `id` as the sequence ID for updates -2. **Use a custom sequence ID**: Publish directly to `//` with your own identifier - -=== "Using the message ID" - ```bash - # First, publish a message and capture the message ID - $ curl -d "Downloading file..." ntfy.sh/mytopic - {"id":"xE73Iyuabi","time":1673542291,...} - - # Then use the message ID to update it - $ curl -d "Download complete!" ntfy.sh/mytopic/xE73Iyuabi - ``` - -=== "Using a custom sequence ID" - ```bash - # Publish with a custom sequence ID - $ curl -d "Downloading file..." ntfy.sh/mytopic/my-download-123 - - # Update using the same sequence ID - $ curl -d "Download complete!" ntfy.sh/mytopic/my-download-123 - ``` - -=== "Using the X-Sequence-ID header" - ```bash - # Publish with a sequence ID via header - $ curl -H "X-Sequence-ID: my-download-123" -d "Downloading..." ntfy.sh/mytopic - - # Update using the same sequence ID - $ curl -H "X-Sequence-ID: my-download-123" -d "Done!" ntfy.sh/mytopic - ``` - -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. - -### Clearing notifications -To clear a notification (mark it as read and dismiss it from the notification drawer), send a PUT request to -`///clear` (or `///read` as an alias): - -=== "Command line (curl)" - ```bash - curl -X PUT ntfy.sh/mytopic/my-download-123/clear - ``` - -=== "HTTP" - ```http - PUT /mytopic/my-download-123/clear HTTP/1.1 - Host: ntfy.sh - ``` - -This publishes a `message_clear` event, which tells clients to: - -- Mark the notification as read in the app -- Dismiss the browser/Android notification - -### Deleting notifications -To delete a notification entirely, send a DELETE request to `//`: - -=== "Command line (curl)" - ```bash - curl -X DELETE ntfy.sh/mytopic/my-download-123 - ``` - -=== "HTTP" - ```http - DELETE /mytopic/my-download-123 HTTP/1.1 - Host: ntfy.sh - ``` - -This publishes a `message_delete` event, which tells clients to: - -- Delete the notification from the database -- Dismiss the browser/Android notification - -!!! info - Deleted sequences can be revived by publishing a new message with the same sequence ID. The notification will - 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. - ## Attachments _Supported on:_ :material-android: :material-firefox: diff --git a/docs/static/css/extra.css b/docs/static/css/extra.css index 3c53aed6..4577ccce 100644 --- a/docs/static/css/extra.css +++ b/docs/static/css/extra.css @@ -1,10 +1,10 @@ :root > * { - --md-primary-fg-color: #338574; + --md-primary-fg-color: #338574; --md-primary-fg-color--light: #338574; - --md-primary-fg-color--dark: #338574; - --md-footer-bg-color: #353744; - --md-text-font: "Roboto"; - --md-code-font: "Roboto Mono"; + --md-primary-fg-color--dark: #338574; + --md-footer-bg-color: #353744; + --md-text-font: "Roboto"; + --md-code-font: "Roboto Mono"; } .md-header__button.md-logo :is(img, svg) { @@ -34,7 +34,7 @@ figure img, figure video { } header { - background: linear-gradient(150deg, rgba(51,133,116,1) 0%, rgba(86,189,168,1) 100%); + background: linear-gradient(150deg, rgba(51, 133, 116, 1) 0%, rgba(86, 189, 168, 1) 100%); } body[data-md-color-scheme="default"] header { @@ -93,7 +93,7 @@ figure video { .screenshots img { max-height: 230px; - max-width: 300px; + max-width: 350px; margin: 3px; border-radius: 5px; filter: drop-shadow(2px 2px 2px #ddd); @@ -107,7 +107,7 @@ figure video { opacity: 0; visibility: hidden; position: fixed; - left:0; + left: 0; right: 0; top: 0; bottom: 0; @@ -119,7 +119,7 @@ figure video { } .lightbox.show { - background-color: rgba(0,0,0, 0.75); + background-color: rgba(0, 0, 0, 0.75); opacity: 1; visibility: visible; z-index: 1000; diff --git a/docs/static/img/android-screenshot-notification-update-1.png b/docs/static/img/android-screenshot-notification-update-1.png new file mode 100644 index 00000000..16320de4 Binary files /dev/null and b/docs/static/img/android-screenshot-notification-update-1.png differ diff --git a/docs/static/img/android-screenshot-notification-update-2.png b/docs/static/img/android-screenshot-notification-update-2.png new file mode 100644 index 00000000..e94c4f21 Binary files /dev/null and b/docs/static/img/android-screenshot-notification-update-2.png differ