diff options
author | Elizabeth Hunt <elizabeth.hunt@simponic.xyz> | 2025-01-05 16:36:51 -0800 |
---|---|---|
committer | Elizabeth Hunt <elizabeth.hunt@simponic.xyz> | 2025-01-11 11:58:34 -0800 |
commit | 040994898b109b3f344b37d1d449eb3b8f58ec53 (patch) | |
tree | 04758f61df0034a398ba133a3b29e7feecf23b85 | |
parent | 687caaa787f9114e390ef34cd06b0c0658cdeae2 (diff) | |
download | oldinfra-040994898b109b3f344b37d1d449eb3b8f58ec53.tar.gz oldinfra-040994898b109b3f344b37d1d449eb3b8f58ec53.zip |
add ntfy integration
-rwxr-xr-x | create_service.sh | 6 | ||||
-rw-r--r-- | template/Dockerfile | 2 | ||||
-rw-r--r-- | template/args/args.go | 12 | ||||
-rw-r--r-- | template/main.go | 15 | ||||
-rw-r--r-- | template/ntfy/publisher.go | 16 | ||||
-rw-r--r-- | template/ntfy/watcher.go | 96 |
6 files changed, 142 insertions, 5 deletions
diff --git a/create_service.sh b/create_service.sh index ee01e7d..7f6766c 100755 --- a/create_service.sh +++ b/create_service.sh @@ -12,9 +12,9 @@ prompt_with_default() { DNS_ENDPOINT=$(prompt_with_default "Enter DNS endpoint" "https://hatecomputers.club/dns") BIND_FILE=$(prompt_with_default "Enter bind file path" "roles/nameservers/templates/db.simponic.xyz.j2") -SERVICE_TITLE=$(prompt_with_default "Enter service title" "phoneof simponic.") -SERVICE=$(prompt_with_default "Enter service name" "phoneof") -SERVICE_PORT=$(prompt_with_default "Enter service port" "6363") +SERVICE_TITLE=$(prompt_with_default "Enter service title" "whois simponic.") +SERVICE=$(prompt_with_default "Enter service name" "whois") +SERVICE_PORT=$(prompt_with_default "Enter service port" "8466") SERVICE_REPO=$(prompt_with_default "Enter service repository URL" "git.simponic.xyz/simponic/$SERVICE") SERVICE_ORIGIN=$(prompt_with_default "Enter service origin URL" "git@git.simponic.xyz:simponic/$SERVICE") INTERNAL=$(prompt_with_default "Is the service internal? (yes/no)" "no") diff --git a/template/Dockerfile b/template/Dockerfile index 87a2422..ff39f7c 100644 --- a/template/Dockerfile +++ b/template/Dockerfile @@ -10,4 +10,4 @@ RUN go build -o /app/{{ service }} EXPOSE 8080 -CMD ["/app/{{ service }}", "--server", "--migrate", "--port", "8080", "--template-path", "/app/templates", "--database-path", "/app/db/{{ service }}.db", "--static-path", "/app/static", "--scheduler"] +CMD ["/app/{{ service }}", "--server", "--migrate", "--port", "8080", "--template-path", "/app/templates", "--database-path", "/app/db/{{ service }}.db", "--static-path", "/app/static", "--scheduler", "--ntfy-topics", "whois", "--ntfy-endpoint", "https://ntfy.simponic.hatecomputers.club"] diff --git a/template/args/args.go b/template/args/args.go index 6e4aff1..dcba9f7 100644 --- a/template/args/args.go +++ b/template/args/args.go @@ -4,6 +4,7 @@ import ( "flag" "fmt" "os" + "strings" "sync" ) @@ -15,6 +16,10 @@ type Arguments struct { Migrate bool Scheduler bool + NtfyEndpoint string + NtfyTopics []string + NtfyListener bool + Port int Server bool } @@ -56,6 +61,10 @@ func GetArgs() (*Arguments, error) { templatePath := flag.String("template-path", "./templates", "Path to the template directory") staticPath := flag.String("static-path", "./static", "Path to the static directory") + ntfyEndpoint := flag.String("ntfy-endpoint", "https://ntfy.simponic.hatecomputers.club", "NTFY Endpoint") + ntfyTopics := flag.String("ntfy-topics", "testtopic", "Comma-separated NTFY Topics") + ntfyListener := flag.Bool("ntfy-listener", false, "Listen to NTFY Topic and propagate messages") + scheduler := flag.Bool("scheduler", false, "Run scheduled jobs via cron") migrate := flag.Bool("migrate", false, "Run the migrations") @@ -72,6 +81,9 @@ func GetArgs() (*Arguments, error) { Server: *server, Migrate: *migrate, Scheduler: *scheduler, + NtfyEndpoint: *ntfyEndpoint, + NtfyTopics: strings.Split(*ntfyTopics, ","), + NtfyListener: *ntfyListener, } err := validateArgs(args) if err != nil { diff --git a/template/main.go b/template/main.go index 6d2b657..3ddb39c 100644 --- a/template/main.go +++ b/template/main.go @@ -9,6 +9,7 @@ import ( "{{ service_repo }}/args" "{{ service_repo }}/database" "{{ service_repo }}/scheduler" + "{{ service_repo }}/ntfy" "github.com/joho/godotenv" ) @@ -36,6 +37,18 @@ func main() { log.Println("database migrated successfully") } + if argv.NtfyListener { + ntfy := ntfy.MakeNtfyWatcher(argv.NtfyEndpoint, argv.NtfyTopics) + notifications := ntfy.Watch() + + go func() { + for notification := range notifications { + message := notification.Message + log.Println("got message", message) + } + }() + } + if argv.Scheduler { go func() { scheduler.StartScheduler(dbConn, argv) @@ -57,7 +70,7 @@ func main() { }() } - if argv.Server || argv.Scheduler { + if argv.Server || argv.Scheduler || argv.NtfyListener { select {} // block forever } } diff --git a/template/ntfy/publisher.go b/template/ntfy/publisher.go new file mode 100644 index 0000000..68f8e49 --- /dev/null +++ b/template/ntfy/publisher.go @@ -0,0 +1,16 @@ +package ntfy + +import ( + "net/http" + "strings" +) + +func SendMessage(message string, endpoint string, topics []string) error { + for _, topic := range topics { + _, err := http.Post(endpoint+"/"+topic, "text/plain", strings.NewReader(message)) + if err != nil { + return err + } + } + return nil +} diff --git a/template/ntfy/watcher.go b/template/ntfy/watcher.go new file mode 100644 index 0000000..d8959cd --- /dev/null +++ b/template/ntfy/watcher.go @@ -0,0 +1,96 @@ +package ntfy + +import ( + "bufio" + "encoding/json" + "log" + "net/http" + "net/url" + "path" + "time" +) + +type Message struct { + Id string `json:"id"` + Time int `json:"time"` + Message string `json:"message"` + Event string `json:"event"` +} + +type NtfyWatcher struct { + Endpoint string + Topics []string +} + +func (w *NtfyWatcher) Watch() chan Message { + notifications := make(chan Message) + + for _, topic := range w.Topics { + log.Println("subscribing to topic:", topic) + + go func() { + retryCount := 5 + retryTime := 5 * time.Second + retries := retryCount + + sleepAndDecrementRetry := func() { + log.Println("waiting 5 seconds before reconnecting. retries left:", retries, "topic:", topic, "endpoint:", w.Endpoint) + time.Sleep(retryTime) + retries-- + } + + for true { + if retries == 0 { + log.Fatal("too many retries, exiting") + } + + endpoint, _ := url.JoinPath(w.Endpoint, path.Join(topic, "json")) + resp, err := http.Get(endpoint) + if err != nil { + log.Println("error connecting to endpoint:", err) + sleepAndDecrementRetry() + continue + } + + defer resp.Body.Close() + scanner := bufio.NewScanner(resp.Body) + for scanner.Scan() { + bytes := scanner.Bytes() + var msg Message + err := json.Unmarshal(bytes, &msg) + if err != nil { + log.Println("could not unmarshal message:", err) + continue + } + + if msg.Event == "keepalive" { + log.Println("received keepalive message") + continue + } + if msg.Event != "message" { + log.Println("received unknown event:", msg.Event) + continue + } + + log.Println("received notification:", msg) + notifications <- msg + retries = retryCount // reset retries + } + + if err := scanner.Err(); err != nil { + log.Println("error reading response body:", err) + sleepAndDecrementRetry() + } + } + }() + } + + return notifications +} + +func MakeNtfyWatcher(endpoint string, topics []string) *NtfyWatcher { + return &NtfyWatcher{ + Endpoint: endpoint, + Topics: topics, + } +} |