EXPERIMENTAL: this endpoint is experimental and is subject to change. @Summary List chat messages @ID list-chat-messages @Security CoderSessionToken @Tags Chats @Produce json @Param chat path string true "Chat ID" format(uuid) @Param before_id query int false "Return messages with id < before_id" @
(rw http.ResponseWriter, r *http.Request)
| 2081 | // |
| 2082 | //nolint:revive // HTTP handler writes to ResponseWriter. |
| 2083 | func (api *API) getChatMessages(rw http.ResponseWriter, r *http.Request) { |
| 2084 | ctx := r.Context() |
| 2085 | chat := httpmw.ChatParam(r) |
| 2086 | chatID := chat.ID |
| 2087 | |
| 2088 | // Parse optional cursor-based pagination parameters. |
| 2089 | queryParams := r.URL.Query() |
| 2090 | parser := httpapi.NewQueryParamParser() |
| 2091 | beforeID := parser.PositiveInt64(queryParams, 0, "before_id") |
| 2092 | afterID := parser.PositiveInt64(queryParams, 0, "after_id") |
| 2093 | limit := parser.PositiveInt32(queryParams, 50, "limit") |
| 2094 | if len(parser.Errors) > 0 { |
| 2095 | httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ |
| 2096 | Message: "Query parameters have invalid values.", |
| 2097 | Validations: parser.Errors, |
| 2098 | }) |
| 2099 | return |
| 2100 | } |
| 2101 | if limit < 1 || limit > 200 { |
| 2102 | httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ |
| 2103 | Message: "Invalid limit parameter (1-200).", |
| 2104 | }) |
| 2105 | return |
| 2106 | } |
| 2107 | // Reject transposed or equal cursors so an empty open range is loud, |
| 2108 | // not silently indistinguishable from "no messages in this range." |
| 2109 | if beforeID > 0 && afterID > 0 && afterID >= beforeID { |
| 2110 | httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ |
| 2111 | Message: "after_id must be less than before_id.", |
| 2112 | }) |
| 2113 | return |
| 2114 | } |
| 2115 | |
| 2116 | // Polling with only after_id uses ASC so the cursor advances |
| 2117 | // monotonically; a DESC limit would drop rows when a burst larger |
| 2118 | // than `limit` lands between polls. Fetch limit+1 in both paths to |
| 2119 | // detect whether more pages exist. |
| 2120 | var messages []database.ChatMessage |
| 2121 | var err error |
| 2122 | switch { |
| 2123 | case afterID > 0 && beforeID == 0: |
| 2124 | messages, err = api.Database.GetChatMessagesByChatIDAscPaginated(ctx, database.GetChatMessagesByChatIDAscPaginatedParams{ |
| 2125 | ChatID: chatID, |
| 2126 | AfterID: afterID, |
| 2127 | LimitVal: limit + 1, |
| 2128 | }) |
| 2129 | default: |
| 2130 | messages, err = api.Database.GetChatMessagesByChatIDDescPaginated(ctx, database.GetChatMessagesByChatIDDescPaginatedParams{ |
| 2131 | ChatID: chatID, |
| 2132 | BeforeID: beforeID, |
| 2133 | AfterID: afterID, |
| 2134 | LimitVal: limit + 1, |
| 2135 | }) |
| 2136 | } |
| 2137 | if err != nil { |
| 2138 | httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ |
| 2139 | Message: "Failed to get chat messages.", |
| 2140 | Detail: err.Error(), |
no test coverage detected