Skip to content

Commit

Permalink
http_notif: implement HTTP notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
guggero committed Jun 17, 2024
1 parent 620ee96 commit c909592
Showing 1 changed file with 105 additions and 3 deletions.
108 changes: 105 additions & 3 deletions http_notif.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,119 @@
package main

import (
"bytes"
"fmt"
"io"
"net/http"
"text/template"
)

type encoding string

func (e encoding) AddHeader(header http.Header) {
header.Add("Content-Type", string(e))
}

func (e encoding) EscapeValue(value string) string {
switch e {
case EncodingForm:
return template.URLQueryEscaper(value)

case EncodingJson:
return template.JSEscapeString(value)

default:
return value
}
}

const (
EncodingForm encoding = "application/x-www-form-urlencoded"
EncodingJson encoding = "application/json"
)

type httpNotificator struct {
URL string
URL string
Method string
Encoding encoding
BodyTemplate string
}

var _ notificator = (*httpNotificator)(nil)

func NewHttpNotificator(cfg notificatorConfig) *httpNotificator {
return &httpNotificator{URL: cfg.Params["Target"]}
return &httpNotificator{
URL: cfg.Params["Target"],
Method: cfg.Params["Method"],
Encoding: encoding(cfg.Params["Encoding"]),
BodyTemplate: cfg.Params["BodyTemplate"],
}
}

func (h *httpNotificator) Notify(amount uint64, comment string) error {
return nil // currently not implemented
bodyData := &struct {
Amount uint64
Message string
}{
Amount: amount,
Message: h.Encoding.EscapeValue(comment),
}

urlTemplate, err := template.New("url").Parse(h.URL)
if err != nil {
return fmt.Errorf("error building URL template: %w", err)
}

bodyTemplate, err := template.New("body").Parse(h.BodyTemplate)
if err != nil {
return fmt.Errorf("error building body template: %w", err)
}

var buf bytes.Buffer
err = urlTemplate.Execute(&buf, bodyData)
if err != nil {
return fmt.Errorf("error executing URL template: %w", err)
}
url := buf.String()

buf.Reset()
err = bodyTemplate.Execute(&buf, bodyData)
if err != nil {
return fmt.Errorf("error executing body template: %w", err)
}

var bodyReader io.Reader
if h.Method == http.MethodPost {
bodyReader = &buf
}

req, err := http.NewRequest(h.Method, url, bodyReader)
if err != nil {
return fmt.Errorf("error creating request: %w", err)
}

h.Encoding.AddHeader(req.Header)

resp, err := http.DefaultClient.Do(req)
if err != nil {
return fmt.Errorf("error sending request: %w", err)
}

defer func() {
_ = resp.Body.Close()
}()

body, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("error reading response body: %w", err)
}

if resp.StatusCode != http.StatusOK {
return fmt.Errorf("unexpected status code: %d (%s)",
resp.StatusCode, body)
}

return nil
}

func (h *httpNotificator) Target() string {
Expand Down

0 comments on commit c909592

Please sign in to comment.