package ifttt import ( "bytes" "context" "encoding/json" "fmt" "io" "net/http" "net/url" goahttp "goa.design/goa/v3/http" ) type ( Client interface { Trigger(ctx context.Context, present bool) (event string, values *Values, err error) } client struct { c *http.Client presentEvent, presentURL, absentEvent, absentURL string presentValues, absentValues *Values debug bool } Values struct { Value1 string `json:"value1,omitempty"` Value2 string `json:"value2,omitempty"` Value3 string `json:"value3,omitempty"` } ) func NewClient(c *http.Client, baseURL, key, presentEvent, absentEvent string, presentValues, absentValues Values, debug bool) (Client, error) { presentURL, err := url.JoinPath(baseURL, "trigger", presentEvent, "with/key", key) if err != nil { return nil, err } absentURL, err := url.JoinPath(baseURL, "trigger", absentEvent, "with/key", key) if err != nil { return nil, err } return &client{ c: c, presentEvent: presentEvent, presentURL: presentURL, presentValues: &presentValues, absentEvent: absentEvent, absentURL: absentURL, absentValues: &absentValues, debug: debug, }, nil } func (c *client) Trigger(ctx context.Context, present bool) (string, *Values, error) { var ( event, u string values *Values ) if present { event = c.presentEvent u = c.presentURL values = c.presentValues } else { event = c.absentEvent u = c.absentURL values = c.absentValues } var ( b = &bytes.Buffer{} e = json.NewEncoder(b) ) e.SetEscapeHTML(false) if err := e.Encode(values); err != nil { return "", nil, err } req, err := http.NewRequestWithContext(ctx, http.MethodPost, u, b) if err != nil { return "", nil, err } doer := goahttp.Doer(c.c) if c.debug { doer = goahttp.NewDebugDoer(doer) } resp, err := doer.Do(req) if err != nil { return "", nil, err } defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { var b []byte b, err = io.ReadAll(resp.Body) if err != nil { return "", nil, fmt.Errorf("%v: <failed to read body: %w>", resp.Status, err) } else if len(b) == 0 { b = []byte("<empty body>") } return "", nil, fmt.Errorf("%v: %s", resp.Status, b) } return event, values, nil }