From ab933e3c532d89d15821ca4724ba52486186ddb3 Mon Sep 17 00:00:00 2001 From: bel Date: Sat, 13 Apr 2024 09:19:53 -0600 Subject: [PATCH] impl GET /api/v1/messages --- main.go | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ main_test.go | 27 ++++++++++++++++++++++++++- 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index 4b218e9..d97488a 100644 --- a/main.go +++ b/main.go @@ -64,6 +64,7 @@ func newHandler(cfg Config) http.HandlerFunc { mux := http.NewServeMux() mux.Handle("POST /api/v1/events/slack", http.HandlerFunc(newHandlerPostAPIV1EventsSlack(cfg))) + mux.Handle("GET /api/v1/messages", http.HandlerFunc(newHandlerGetAPIV1Messages(cfg))) mux.Handle("GET /api/v1/threads", http.HandlerFunc(newHandlerGetAPIV1Threads(cfg))) mux.Handle("GET /api/v1/threads/{thread}", http.HandlerFunc(newHandlerGetAPIV1ThreadsThread(cfg))) @@ -78,6 +79,28 @@ func newHandler(cfg Config) http.HandlerFunc { } } +func newHandlerGetAPIV1Messages(cfg Config) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + if !basicAuth(cfg, w, r) { + return + } + + since, err := parseSince(r.URL.Query().Get("since")) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + messages, err := cfg.storage.MessagesSince(r.Context(), since) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + json.NewEncoder(w).Encode(map[string]any{"messages": messages}) + } +} + func newHandlerGetAPIV1Threads(cfg Config) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if !basicAuth(cfg, w, r) { @@ -195,3 +218,31 @@ func _newHandlerPostAPIV1EventsSlack(cfg Config) http.HandlerFunc { log.Printf("ingested %v", m.ID) } } + +func parseSince(s string) (time.Time, error) { + if s == "" { + return time.Unix(0, 0), nil + } + + if n, err := strconv.ParseInt(s, 10, 64); err != nil { + } else { + return time.Unix(n, 0), nil + } + + if t, err := time.Parse(time.RFC3339, s); err != nil { + } else { + return t, nil + } + + if t, err := time.Parse(time.RFC3339Nano, s); err != nil { + } else { + return t, nil + } + + if t, err := time.ParseInLocation(time.DateOnly, s, time.Local); err != nil { + } else { + return t, nil + } + + return time.Time{}, fmt.Errorf("failed to parse since=%q", s) +} diff --git a/main_test.go b/main_test.go index 79fcdde..27c8bc8 100644 --- a/main_test.go +++ b/main_test.go @@ -80,6 +80,29 @@ func TestRun(t *testing.T) { } }) + t.Run("GET /api/v1/messages", func(t *testing.T) { + resp, err := http.Get(fmt.Sprintf("%s/api/v1/messages", u)) + if err != nil { + t.Fatal(err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + b, _ := io.ReadAll(resp.Body) + t.Fatalf("(%d) %s", resp.StatusCode, b) + } + var result struct { + Messages []Message + } + if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { + t.Fatal(err) + } else if len(result.Messages) != 1 { + t.Fatal(result.Messages) + } else { + t.Logf("%+v", result) + } + }) + t.Run("GET /api/v1/threads", func(t *testing.T) { resp, err := http.Get(fmt.Sprintf("%s/api/v1/threads", u)) if err != nil { @@ -98,6 +121,8 @@ func TestRun(t *testing.T) { t.Fatal(err) } else if result.Threads[0] != "1712911957.023359" { t.Fatal(result.Threads) + } else { + t.Logf("%+v", result) } }) @@ -123,7 +148,7 @@ func TestRun(t *testing.T) { } else if len(result.Thread.Messages) != 1 { t.Fatal(result.Thread) } else { - t.Logf("%+v", result.Thread.Messages[0]) + t.Logf("%+v", result) } }) }