impl GET /api/v1/messages

main
bel 2024-04-13 09:19:53 -06:00
parent d5b09db0c6
commit ab933e3c53
2 changed files with 77 additions and 1 deletions

51
main.go
View File

@ -64,6 +64,7 @@ func newHandler(cfg Config) http.HandlerFunc {
mux := http.NewServeMux() mux := http.NewServeMux()
mux.Handle("POST /api/v1/events/slack", http.HandlerFunc(newHandlerPostAPIV1EventsSlack(cfg))) 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", http.HandlerFunc(newHandlerGetAPIV1Threads(cfg)))
mux.Handle("GET /api/v1/threads/{thread}", http.HandlerFunc(newHandlerGetAPIV1ThreadsThread(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 { func newHandlerGetAPIV1Threads(cfg Config) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
if !basicAuth(cfg, w, r) { if !basicAuth(cfg, w, r) {
@ -195,3 +218,31 @@ func _newHandlerPostAPIV1EventsSlack(cfg Config) http.HandlerFunc {
log.Printf("ingested %v", m.ID) 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)
}

View File

@ -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) { t.Run("GET /api/v1/threads", func(t *testing.T) {
resp, err := http.Get(fmt.Sprintf("%s/api/v1/threads", u)) resp, err := http.Get(fmt.Sprintf("%s/api/v1/threads", u))
if err != nil { if err != nil {
@ -98,6 +121,8 @@ func TestRun(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} else if result.Threads[0] != "1712911957.023359" { } else if result.Threads[0] != "1712911957.023359" {
t.Fatal(result.Threads) 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 { } else if len(result.Thread.Messages) != 1 {
t.Fatal(result.Thread) t.Fatal(result.Thread)
} else { } else {
t.Logf("%+v", result.Thread.Messages[0]) t.Logf("%+v", result)
} }
}) })
} }