mirror of
https://github.com/multipleof4/ntfy.git
synced 2026-10-11 06:15:21 +00:00
support delete via GET
This commit is contained in:
+23
-4
@@ -2777,16 +2777,20 @@ Here's an example of a dead man's switch that sends an alert if the script stops
|
||||
### Canceling scheduled notifications
|
||||
|
||||
You can cancel a scheduled message before it is delivered by sending a DELETE request to the
|
||||
`/<topic>/<sequence_id>` endpoint, just like [deleting notifications](#deleting-notifications). This will remove the
|
||||
scheduled message from the server so it will never be delivered, and emit a `message_delete` event to any subscribers.
|
||||
`/<topic>/<sequence_id>` endpoint, just like [deleting notifications](#deleting-notifications). Alternatively, you can send a `GET`
|
||||
request to `/<topic>/<sequence_id>/delete`. This will remove the scheduled message from the server so it will never be delivered,
|
||||
and emit a `message_delete` event to any subscribers.
|
||||
|
||||
=== "Command line (curl)"
|
||||
```bash
|
||||
# Schedule a reminder for 2 hours from now
|
||||
curl -H "In: 2h" -d "Take a break!" ntfy.sh/mytopic/break-reminder
|
||||
|
||||
# Changed your mind? Cancel the scheduled message
|
||||
# Changed your mind? Cancel the scheduled message via DELETE
|
||||
curl -X DELETE ntfy.sh/mytopic/break-reminder
|
||||
|
||||
# Or cancel it via GET
|
||||
curl ntfy.sh/mytopic/break-reminder/delete
|
||||
```
|
||||
|
||||
=== "ntfy CLI"
|
||||
@@ -4154,25 +4158,40 @@ An example response from the server with the `message_clear` event may look like
|
||||
### Deleting notifications
|
||||
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
|
||||
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.
|
||||
|
||||
Alternatively, if your client has limited HTTP support (e.g. webhooks or IoT devices), you can also delete a message by sending
|
||||
a `GET` request to `/<topic>/<sequence_id>/delete`.
|
||||
|
||||
=== "Command line (curl)"
|
||||
```bash
|
||||
# Via DELETE method
|
||||
curl -X DELETE ntfy.sh/mytopic/my-download-123
|
||||
|
||||
# Via GET method
|
||||
curl ntfy.sh/mytopic/my-download-123/delete
|
||||
```
|
||||
|
||||
=== "HTTP"
|
||||
``` http
|
||||
DELETE /mytopic/my-download-123 HTTP/1.1
|
||||
Host: ntfy.sh
|
||||
|
||||
# Or using GET
|
||||
GET /mytopic/my-download-123/delete HTTP/1.1
|
||||
Host: ntfy.sh
|
||||
```
|
||||
|
||||
=== "JavaScript"
|
||||
``` javascript
|
||||
// Via DELETE method
|
||||
await fetch('https://ntfy.sh/mytopic/my-download-123', {
|
||||
method: 'DELETE'
|
||||
});
|
||||
|
||||
// Via GET method
|
||||
await fetch('https://ntfy.sh/mytopic/my-download-123/delete');
|
||||
```
|
||||
|
||||
=== "Go"
|
||||
|
||||
@@ -91,6 +91,7 @@ var (
|
||||
publishPathRegex = regexp.MustCompile(`^/[-_A-Za-z0-9]{1,64}/(publish|send|trigger)$`)
|
||||
updatePathRegex = regexp.MustCompile(`^/[-_A-Za-z0-9]{1,64}/[-_A-Za-z0-9]{1,64}$`)
|
||||
clearPathRegex = regexp.MustCompile(`^/[-_A-Za-z0-9]{1,64}/[-_A-Za-z0-9]{1,64}/(read|clear)$`)
|
||||
deletePathRegex = regexp.MustCompile(`^/[-_A-Za-z0-9]{1,64}/[-_A-Za-z0-9]{1,64}/delete$`)
|
||||
sequenceIDRegex = topicRegex
|
||||
|
||||
webConfigPath = "/config.js"
|
||||
@@ -645,6 +646,8 @@ func (s *Server) handleInternal(w http.ResponseWriter, r *http.Request, v *visit
|
||||
return s.limitRequestsWithTopic(s.authorizeTopicWrite(s.handlePublish))(w, r, v)
|
||||
} else if r.Method == http.MethodDelete && updatePathRegex.MatchString(r.URL.Path) {
|
||||
return s.limitRequestsWithTopic(s.authorizeTopicWrite(s.handleDelete))(w, r, v)
|
||||
} else if r.Method == http.MethodGet && deletePathRegex.MatchString(r.URL.Path) {
|
||||
return s.limitRequestsWithTopic(s.authorizeTopicWrite(s.handleDelete))(w, r, v)
|
||||
} else if r.Method == http.MethodPut && clearPathRegex.MatchString(r.URL.Path) {
|
||||
return s.limitRequestsWithTopic(s.authorizeTopicWrite(s.handleClear))(w, r, v)
|
||||
} else if r.Method == http.MethodGet && publishPathRegex.MatchString(r.URL.Path) {
|
||||
|
||||
@@ -4026,6 +4026,40 @@ func TestServer_DeleteMessage(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestServer_DeleteMessage_GET(t *testing.T) {
|
||||
forEachBackend(t, func(t *testing.T, databaseURL string) {
|
||||
t.Parallel()
|
||||
s := newTestServer(t, newTestConfig(t, databaseURL))
|
||||
|
||||
// Publish a message with a sequence ID
|
||||
response := request(t, s, "PUT", "/mytopic/seq123", "original message", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
msg := toMessage(t, response.Body.String())
|
||||
require.Equal(t, "seq123", msg.SequenceID)
|
||||
require.Equal(t, "message", msg.Event)
|
||||
|
||||
// Delete the message using GET method (/topic/seq/delete)
|
||||
response = request(t, s, "GET", "/mytopic/seq123/delete", "", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
deleteMsg := toMessage(t, response.Body.String())
|
||||
require.Equal(t, "seq123", deleteMsg.SequenceID)
|
||||
require.Equal(t, "message_delete", deleteMsg.Event)
|
||||
|
||||
// Poll and verify both messages are returned
|
||||
response = request(t, s, "GET", "/mytopic/json?poll=1", "", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
lines := strings.Split(strings.TrimSpace(response.Body.String()), "\n")
|
||||
require.Equal(t, 2, len(lines))
|
||||
|
||||
msg1 := toMessage(t, lines[0])
|
||||
msg2 := toMessage(t, lines[1])
|
||||
require.Equal(t, "message", msg1.Event)
|
||||
require.Equal(t, "message_delete", msg2.Event)
|
||||
require.Equal(t, "seq123", msg1.SequenceID)
|
||||
require.Equal(t, "seq123", msg2.SequenceID)
|
||||
})
|
||||
}
|
||||
|
||||
func TestServer_ClearMessage(t *testing.T) {
|
||||
forEachBackend(t, func(t *testing.T, databaseURL string) {
|
||||
t.Parallel()
|
||||
@@ -4286,6 +4320,41 @@ func TestServer_DeleteScheduledMessage(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestServer_DeleteScheduledMessage_GET(t *testing.T) {
|
||||
forEachBackend(t, func(t *testing.T, databaseURL string) {
|
||||
t.Parallel()
|
||||
s := newTestServer(t, newTestConfig(t, databaseURL))
|
||||
|
||||
// Publish a scheduled message (future delivery)
|
||||
response := request(t, s, "PUT", "/mytopic/delete-sched-seq?delay=1h", "scheduled message to delete", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
msg := toMessage(t, response.Body.String())
|
||||
require.Equal(t, "delete-sched-seq", msg.SequenceID)
|
||||
|
||||
// Verify scheduled message exists
|
||||
response = request(t, s, "GET", "/mytopic/json?poll=1&scheduled=1", "", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
messages := toMessages(t, response.Body.String())
|
||||
require.Equal(t, 1, len(messages))
|
||||
require.Equal(t, "scheduled message to delete", messages[0].Message)
|
||||
|
||||
// Delete the scheduled message using GET method (/topic/seq/delete)
|
||||
response = request(t, s, "GET", "/mytopic/delete-sched-seq/delete", "", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
deleteMsg := toMessage(t, response.Body.String())
|
||||
require.Equal(t, "delete-sched-seq", deleteMsg.SequenceID)
|
||||
require.Equal(t, "message_delete", deleteMsg.Event)
|
||||
|
||||
// Verify scheduled message was deleted, only delete event remains
|
||||
response = request(t, s, "GET", "/mytopic/json?poll=1&scheduled=1", "", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
messages = toMessages(t, response.Body.String())
|
||||
require.Equal(t, 1, len(messages))
|
||||
require.Equal(t, "message_delete", messages[0].Event)
|
||||
require.Equal(t, "delete-sched-seq", messages[0].SequenceID)
|
||||
})
|
||||
}
|
||||
|
||||
func TestServer_UpdateScheduledMessage_TopicScoped(t *testing.T) {
|
||||
forEachBackend(t, func(t *testing.T, databaseURL string) {
|
||||
t.Parallel()
|
||||
|
||||
Reference in New Issue
Block a user