]> git.giacomolli.uk - onechat/blobdiff - notify.go
Bind external events to permanent agent IDs
[onechat] / notify.go
index 1036312c176d2983a7f1b5e8d15284f2be8b9089..2071ce6a980c7ebffabbc79c55e67beba441a2ee 100644 (file)
--- a/notify.go
+++ b/notify.go
@@ -3,6 +3,7 @@ package main
 import (
        "context"
        "crypto/sha256"
+       "encoding/hex"
        "encoding/json"
        "errors"
        "fmt"
@@ -49,20 +50,24 @@ Child targets, receipt expiry, and processing status are not supported.
 )
 
 // NotifyInput is caller-supplied data. Its source label proves no identity or
-// authority. Source and ID together identify a retry of the same text.
+// authority. Source and ID together identify a retry of the same text. AgentID
+// selects a permanent agent. An empty AgentID selects the root.
 type NotifyInput struct {
-       Source string `json:"source"`
-       ID     string `json:"id"`
-       Text   string `json:"text"`
+       AgentID string `json:"agent_id,omitempty"`
+       Source  string `json:"source"`
+       ID      string `json:"id"`
+       Text    string `json:"text"`
 }
 
 // NotifyReceipt keeps a retry key after its queued delivery finishes. Digest
-// binds the original text without retaining another copy of that text.
+// binds the original text without retaining another copy of that text. TargetID
+// binds the permanent agent identity. An empty TargetID selects the root.
 type NotifyReceipt struct {
-       Source string `json:"source"`
-       ID     string `json:"id"`
-       Digest string `json:"digest"`
-       Number int    `json:"number"`
+       TargetID string `json:"target_id,omitempty"`
+       Source   string `json:"source"`
+       ID       string `json:"id"`
+       Digest   string `json:"digest"`
+       Number   int    `json:"number"`
 }
 
 // notify submits a local event and prints only its acceptance receipt. The
@@ -202,6 +207,13 @@ func notifyParse(args []string) (NotifyInput, error) {
 
 // notifyValidate checks both CLI and direct socket inputs without echoing data.
 func notifyValidate(input NotifyInput) error {
+       if input.AgentID != "" {
+               id, err := hex.DecodeString(input.AgentID)
+               if err != nil || len(id) != agentIDBytes {
+                       return errors.New("notification agent ID is invalid")
+               }
+       }
+
        if !notifyIdentifier(input.Source) || !notifyIdentifier(input.ID) {
                return errors.New("notification source and ID must be 1 to 128 ASCII letters, digits, dots, underscores, or hyphens")
        }