http_notifier.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. package http
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "log/slog"
  6. "net/http"
  7. "net/url"
  8. "strconv"
  9. "strings"
  10. "github.com/ncarlier/webhookd/pkg/helper"
  11. "github.com/ncarlier/webhookd/pkg/notification"
  12. )
  13. type notifPayload struct {
  14. ID string `json:"id"`
  15. Name string `json:"name"`
  16. Text string `json:"text"`
  17. Error error `json:"error,omitempty"`
  18. }
  19. // httpNotifier is able to send a notification to a HTTP endpoint.
  20. type httpNotifier struct {
  21. URL *url.URL
  22. PrefixFilter string
  23. }
  24. func newHTTPNotifier(uri *url.URL) (notification.Notifier, error) {
  25. slog.Info("using HTTP notification system", "uri", uri.Redacted())
  26. return &httpNotifier{
  27. URL: uri,
  28. PrefixFilter: helper.GetValueOrAlt(uri.Query(), "prefix", "notify:"),
  29. }, nil
  30. }
  31. // Notify send a notification to a HTTP endpoint.
  32. func (n *httpNotifier) Notify(result notification.HookResult) error {
  33. payload := result.Logs(n.PrefixFilter)
  34. if strings.TrimSpace(payload) == "" {
  35. // Nothing to notify, abort
  36. return nil
  37. }
  38. notif := &notifPayload{
  39. ID: strconv.FormatUint(result.ID(), 10),
  40. Name: result.Name(),
  41. Text: payload,
  42. Error: result.Err(),
  43. }
  44. notifJSON, err := json.Marshal(notif)
  45. if err != nil {
  46. return err
  47. }
  48. req, err := http.NewRequest("POST", n.URL.String(), bytes.NewBuffer(notifJSON))
  49. if err != nil {
  50. return err
  51. }
  52. req.Header.Set("Content-Type", "application/json")
  53. client := &http.Client{}
  54. resp, err := client.Do(req)
  55. if err != nil {
  56. return err
  57. }
  58. resp.Body.Close()
  59. slog.Info("notification sent", "hook", result.Name(), "id", result.ID(), "to", n.URL.Opaque)
  60. return nil
  61. }
  62. func init() {
  63. notification.Register("http", newHTTPNotifier)
  64. notification.Register("https", newHTTPNotifier)
  65. }