diff options
| author | Christine Dodrill <me@christine.website> | 2018-09-23 14:26:02 -0700 |
|---|---|---|
| committer | Christine Dodrill <me@christine.website> | 2018-09-23 14:26:02 -0700 |
| commit | fe760ddbdc36008cb1747fcfb742072e5240cdd6 (patch) | |
| tree | 7b6f765ac0ceb7c1078d3219746bf681f02d1c64 /web/switchcounter | |
| parent | 73344db07bd55329f87a4176802443edb7c464ae (diff) | |
| download | x-fe760ddbdc36008cb1747fcfb742072e5240cdd6.tar.xz x-fe760ddbdc36008cb1747fcfb742072e5240cdd6.zip | |
x/discord: start on ilo Kesi
Diffstat (limited to 'web/switchcounter')
| -rw-r--r-- | web/switchcounter/switchc.go | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/web/switchcounter/switchc.go b/web/switchcounter/switchc.go new file mode 100644 index 0000000..d4bfbd3 --- /dev/null +++ b/web/switchcounter/switchc.go @@ -0,0 +1,106 @@ +// Package switchcounter is a simple interface to the https://www.switchcounter.science/ API. +package switchcounter + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io/ioutil" + "log" + "net/http" + "time" +) + +type arg struct { + Command string `json:"command"` // always "switch" + MemberName string `json:"member_name,omitempty"` +} + +// API is the switchcounter API as an abstract interface. +type API interface { + // Status returns the front of the system for this API client. + Status(ctx context.Context) (Status, error) + + // Switch changes who is in front. + Switch(ctx context.Context, front string) (Status, error) +} + +// Status is the API response. +type Status struct { + Front string `json:"member_name"` + StartedAt time.Time `json:"started_at"` +} + +type httpClient struct { + hc *http.Client + url string // webhook url +} + +func (hc httpClient) makeRequestWith(ctx context.Context, body interface{}) (*Status, error) { + env := struct { + Webhook interface{} `json:"webhook"` + }{ + Webhook: body, + } + data, err := json.Marshal(env) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", hc.url, bytes.NewBuffer(data)) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + req.Header.Add("Content-Type", "application/json") + + resp, err := hc.hc.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + log.Printf("body: %s", string(data)) + + return nil, fmt.Errorf("http response code %d", resp.StatusCode) + } + + var result Status + err = json.NewDecoder(resp.Body).Decode(&result) + if err != nil { + return nil, err + } + + return &result, nil +} + +func (hc httpClient) Status(ctx context.Context) (Status, error) { + result, err := hc.makeRequestWith(ctx, arg{Command: "switch"}) + if err != nil { + return Status{}, err + } + return *result, nil +} + +func (hc httpClient) Switch(ctx context.Context, front string) (Status, error) { + result, err := hc.makeRequestWith(ctx, arg{Command: "switch", MemberName: front}) + if err != nil { + return Status{}, err + } + return *result, nil +} + +// NewHTTPClient creates a new instance of API over HTTP. +func NewHTTPClient(hc *http.Client, webhookURL string) API { + return httpClient{ + hc: hc, + url: webhookURL, + } +} |
