binwiederhier vor 1 Monat
Ursprung
Commit
3d54260f79
3 geänderte Dateien mit 150 neuen und 20 gelöschten Zeilen
  1. 5 0
      client/options.go
  2. 6 0
      cmd/publish.go
  3. 139 20
      docs/publish.md

+ 5 - 0
client/options.go

@@ -88,6 +88,11 @@ func WithFilename(filename string) PublishOption {
 	return WithHeader("X-Filename", filename)
 }
 
+// WithSequenceID sets a sequence ID for the message, allowing updates to existing notifications
+func WithSequenceID(sequenceID string) PublishOption {
+	return WithHeader("X-Sequence-ID", sequenceID)
+}
+
 // WithEmail instructs the server to also send the message to the given e-mail address
 func WithEmail(email string) PublishOption {
 	return WithHeader("X-Email", email)

+ 6 - 0
cmd/publish.go

@@ -34,6 +34,7 @@ var flagsPublish = append(
 	&cli.BoolFlag{Name: "markdown", Aliases: []string{"md"}, EnvVars: []string{"NTFY_MARKDOWN"}, Usage: "Message is formatted as Markdown"},
 	&cli.StringFlag{Name: "template", Aliases: []string{"tpl"}, EnvVars: []string{"NTFY_TEMPLATE"}, Usage: "use templates to transform JSON message body"},
 	&cli.StringFlag{Name: "filename", Aliases: []string{"name", "n"}, EnvVars: []string{"NTFY_FILENAME"}, Usage: "filename for the attachment"},
+	&cli.StringFlag{Name: "sequence-id", Aliases: []string{"sequence_id", "sid", "S"}, EnvVars: []string{"NTFY_SEQUENCE_ID"}, Usage: "sequence ID for updating notifications"},
 	&cli.StringFlag{Name: "file", Aliases: []string{"f"}, EnvVars: []string{"NTFY_FILE"}, Usage: "file to upload as an attachment"},
 	&cli.StringFlag{Name: "email", Aliases: []string{"mail", "e"}, EnvVars: []string{"NTFY_EMAIL"}, Usage: "also send to e-mail address"},
 	&cli.StringFlag{Name: "user", Aliases: []string{"u"}, EnvVars: []string{"NTFY_USER"}, Usage: "username[:password] used to auth against the server"},
@@ -70,6 +71,7 @@ Examples:
   ntfy pub --icon="http://some.tld/icon.png" 'Icon!'      # Send notification with custom icon
   ntfy pub --attach="http://some.tld/file.zip" files      # Send ZIP archive from URL as attachment
   ntfy pub --file=flower.jpg flowers 'Nice!'              # Send image.jpg as attachment
+  ntfy pub -S my-id mytopic 'Update me'                   # Send with sequence ID for updates
   echo 'message' | ntfy publish mytopic                   # Send message from stdin
   ntfy pub -u phil:mypass secret Psst                     # Publish with username/password
   ntfy pub --wait-pid 1234 mytopic                        # Wait for process 1234 to exit before publishing
@@ -101,6 +103,7 @@ func execPublish(c *cli.Context) error {
 	markdown := c.Bool("markdown")
 	template := c.String("template")
 	filename := c.String("filename")
+	sequenceID := c.String("sequence-id")
 	file := c.String("file")
 	email := c.String("email")
 	user := c.String("user")
@@ -154,6 +157,9 @@ func execPublish(c *cli.Context) error {
 	if filename != "" {
 		options = append(options, client.WithFilename(filename))
 	}
+	if sequenceID != "" {
+		options = append(options, client.WithSequenceID(sequenceID))
+	}
 	if email != "" {
 		options = append(options, client.WithEmail(email))
 	}

+ 139 - 20
docs/publish.md

@@ -963,36 +963,95 @@ 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 `/<topic>/<sequence_id>` 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
-    ```
+Here's an example using a custom sequence ID to update a notification:
 
-=== "Using a custom sequence ID"
+=== "Command line (curl)"
     ```bash
     # Publish with a custom sequence ID
-    $ curl -d "Downloading file..." ntfy.sh/mytopic/my-download-123
+    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
+    curl -d "Download complete!" ntfy.sh/mytopic/my-download-123
     ```
 
-=== "Using the X-Sequence-ID header"
+=== "ntfy CLI"
     ```bash
-    # Publish with a sequence ID via header
-    $ curl -H "X-Sequence-ID: my-download-123" -d "Downloading..." ntfy.sh/mytopic
+    # Publish with a sequence ID
+    ntfy pub --sequence-id=my-download-123 mytopic "Downloading file..."
 
     # Update using the same sequence ID
-    $ curl -H "X-Sequence-ID: my-download-123" -d "Done!" ntfy.sh/mytopic
+    ntfy pub --sequence-id=my-download-123 mytopic "Download complete!"
+    ```
+
+=== "HTTP"
+    ``` http
+    POST /mytopic/my-download-123 HTTP/1.1
+    Host: ntfy.sh
+
+    Downloading file...
     ```
 
-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.
+=== "JavaScript"
+    ``` javascript
+    // First message
+    await fetch('https://ntfy.sh/mytopic/my-download-123', {
+      method: 'POST',
+      body: 'Downloading file...'
+    });
+
+    // Update with same sequence ID
+    await fetch('https://ntfy.sh/mytopic/my-download-123', {
+      method: 'POST',
+      body: 'Download complete!'
+    });
+    ```
+
+=== "Go"
+    ``` go
+    // Publish with sequence ID in URL path
+    http.Post("https://ntfy.sh/mytopic/my-download-123", "text/plain",
+        strings.NewReader("Downloading file..."))
+    
+    // Update with same sequence ID
+    http.Post("https://ntfy.sh/mytopic/my-download-123", "text/plain",
+        strings.NewReader("Download complete!"))
+    ```
+
+=== "PowerShell"
+    ``` powershell
+    # Publish with sequence ID
+    Invoke-RestMethod -Method POST -Uri "https://ntfy.sh/mytopic/my-download-123" -Body "Downloading file..."
+    
+    # Update with same sequence ID
+    Invoke-RestMethod -Method POST -Uri "https://ntfy.sh/mytopic/my-download-123" -Body "Download complete!"
+    ```
+
+=== "Python"
+    ``` python
+    import requests
+    
+    # Publish with sequence ID
+    requests.post("https://ntfy.sh/mytopic/my-download-123", data="Downloading file...")
+    
+    # Update with same sequence ID
+    requests.post("https://ntfy.sh/mytopic/my-download-123", data="Download complete!")
+    ```
+
+=== "PHP"
+    ``` php-inline
+    // Publish with sequence ID
+    file_get_contents('https://ntfy.sh/mytopic/my-download-123', false, stream_context_create([
+        'http' => ['method' => 'POST', 'content' => 'Downloading file...']
+    ]));
+    
+    // Update with same sequence ID
+    file_get_contents('https://ntfy.sh/mytopic/my-download-123', false, stream_context_create([
+        'http' => ['method' => 'POST', 'content' => 'Download complete!']
+    ]));
+    ```
+
+You can also set the sequence ID via the `X-Sequence-ID` header, 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
@@ -1004,11 +1063,41 @@ To clear a notification (mark it as read and dismiss it from the notification dr
     ```
 
 === "HTTP"
-    ```http
+    ``` http
     PUT /mytopic/my-download-123/clear HTTP/1.1
     Host: ntfy.sh
     ```
 
+=== "JavaScript"
+    ``` javascript
+    await fetch('https://ntfy.sh/mytopic/my-download-123/clear', {
+      method: 'PUT'
+    });
+    ```
+
+=== "Go"
+    ``` go
+    req, _ := http.NewRequest("PUT", "https://ntfy.sh/mytopic/my-download-123/clear", nil)
+    http.DefaultClient.Do(req)
+    ```
+
+=== "PowerShell"
+    ``` powershell
+    Invoke-RestMethod -Method PUT -Uri "https://ntfy.sh/mytopic/my-download-123/clear"
+    ```
+
+=== "Python"
+    ``` python
+    requests.put("https://ntfy.sh/mytopic/my-download-123/clear")
+    ```
+
+=== "PHP"
+    ``` php-inline
+    file_get_contents('https://ntfy.sh/mytopic/my-download-123/clear', false, stream_context_create([
+        'http' => ['method' => 'PUT']
+    ]));
+    ```
+
 This publishes a `message_clear` event, which tells clients to:
 
 - Mark the notification as read in the app
@@ -1023,11 +1112,41 @@ To delete a notification entirely, send a DELETE request to `/<topic>/<sequence_
     ```
 
 === "HTTP"
-    ```http
+    ``` http
     DELETE /mytopic/my-download-123 HTTP/1.1
     Host: ntfy.sh
     ```
 
+=== "JavaScript"
+    ``` javascript
+    await fetch('https://ntfy.sh/mytopic/my-download-123', {
+      method: 'DELETE'
+    });
+    ```
+
+=== "Go"
+    ``` go
+    req, _ := http.NewRequest("DELETE", "https://ntfy.sh/mytopic/my-download-123", nil)
+    http.DefaultClient.Do(req)
+    ```
+
+=== "PowerShell"
+    ``` powershell
+    Invoke-RestMethod -Method DELETE -Uri "https://ntfy.sh/mytopic/my-download-123"
+    ```
+
+=== "Python"
+    ``` python
+    requests.delete("https://ntfy.sh/mytopic/my-download-123")
+    ```
+
+=== "PHP"
+    ``` php-inline
+    file_get_contents('https://ntfy.sh/mytopic/my-download-123', false, stream_context_create([
+        'http' => ['method' => 'DELETE']
+    ]));
+    ```
+
 This publishes a `message_delete` event, which tells clients to:
 
 - Delete the notification from the database