github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/internal/scrape/notify.go (about) 1 package scrapePkg 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "errors" 7 "fmt" 8 "io" 9 "net/http" 10 "strings" 11 "syscall" 12 13 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/config" 14 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/notify" 15 ) 16 17 var ErrConfiguredButNotRunning = fmt.Errorf("listener is configured but not running") 18 19 // GetNotifyEndpoint returns the notification endpoint 20 func GetNotifyEndpoint() string { 21 endpoint := config.GetSettings().Notify.Url 22 // If protocol is not specified, use http by default 23 if endpoint != "" && !strings.HasPrefix(endpoint, "http") { 24 endpoint = "http://" + endpoint 25 } 26 return endpoint 27 } 28 29 // NotifyConfigured returns true if notification feature is configured 30 func NotifyConfigured() bool { 31 return GetNotifyEndpoint() != "" 32 } 33 34 // Notify may be used to tell other processes about progress. 35 func Notify[T notify.NotificationPayload](notification notify.Notification[T]) error { 36 endpoint := GetNotifyEndpoint() 37 if endpoint == "" { 38 return nil 39 } 40 return notifyEndpoint(endpoint, notification) 41 } 42 43 func notifyEndpoint(endpoint string, notification any) error { 44 encoded, err := json.Marshal(notification) 45 if err != nil { 46 return fmt.Errorf("marshalling message: %w", err) 47 } 48 49 resp, err := http.Post( 50 endpoint, 51 "application/json", 52 bytes.NewReader(encoded), 53 ) 54 55 if err != nil { 56 if errors.Is(err, syscall.ECONNREFUSED) { 57 return ErrConfiguredButNotRunning 58 } 59 return fmt.Errorf("sending notification: %w", err) 60 } 61 if resp.StatusCode < 200 || resp.StatusCode > 299 { 62 respBody, _ := io.ReadAll(resp.Body) 63 resp.Body.Close() 64 return fmt.Errorf("listener responded with %d: %s", resp.StatusCode, respBody) 65 } 66 return nil 67 }