3
0
mirror of https://github.com/ergochat/ergo.git synced 2026-03-14 11:18:04 +01:00

api: add /v1/list to list channels (#2358)

This commit is contained in:
Shivaram Lingamneni 2026-03-12 22:53:17 -07:00 committed by GitHub
parent ca4c3c09df
commit 05c37122fc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 81 additions and 0 deletions

View File

@ -55,6 +55,31 @@ The response is a JSON object with fields:
* `success`: whether the credentials provided were valid
* `accountName`: canonical, case-unfolded version of the account name
`/v1/list`
----------
This endpoint returns a list of channels that exist on the network. The request body is ignored and can be empty.
The response is a JSON object with fields:
* `success`: whether the request was successful
* `channels`: a list of channel objects, as described below
Each channel object has fields:
* `name`: canonical name of the channel without case-normalization
* `hasKey`: boolean, whether the channel has a key set with the `+k` mode
* `inviteOnly`: boolean, whether the channel has the `+i` invite-only mode set
* `secret`: boolean, whether the channel has the `+s` secret mode set (and would be hidden from an unprivileged `LIST` command)
* `userCount`: int, number of users in the channel
* `topic`: string, channel topic
* `topicSetAt`: string, time the topic was last updated (in ISO8601 format)
* `createdAt`: string, time the channel was created (in ISO8601 format)
* `registered`: boolean, whether the channel is registered
* `owner`: string, account name of the registered owner if the channel is registered
* `registeredAt`: string, registration date/time of the channel (in ISO8601 format) if it is registered
`/v1/ns/info`
-------------

View File

@ -8,6 +8,7 @@ import (
"runtime"
"strings"
"github.com/ergochat/ergo/irc/modes"
"github.com/ergochat/ergo/irc/utils"
)
@ -20,6 +21,7 @@ func newAPIHandler(server *Server) http.Handler {
// server-level functionality:
api.mux.HandleFunc("POST /v1/rehash", api.handleRehash)
api.mux.HandleFunc("POST /v1/status", api.handleStatus)
api.mux.HandleFunc("POST /v1/list", api.handleList)
// use Ergo as a source of truth for authentication in other services:
api.mux.HandleFunc("POST /v1/check_auth", api.handleCheckAuth)
@ -347,3 +349,57 @@ func (a *ergoAPI) handleStatus(w http.ResponseWriter, r *http.Request) {
a.writeJSONResponse(response, w, r)
}
type apiChannelData struct {
Name string `json:"name"`
HasKey bool `json:"hasKey"`
InviteOnly bool `json:"inviteOnly"`
Secret bool `json:"secret"`
UserCount int `json:"userCount"`
Topic string `json:"topic"`
TopicSetAt string `json:"topicSetAt,omitempty"`
CreatedAt string `json:"createdAt"`
Registered bool `json:"registered"`
Owner string `json:"owner,omitempty"`
RegisteredAt string `json:"registeredAt,omitempty"`
}
func (channel *Channel) apiData() (result apiChannelData) {
channel.stateMutex.RLock()
defer channel.stateMutex.RUnlock()
result.Name = channel.name
result.HasKey = channel.key != ""
result.InviteOnly = channel.flags.HasMode(modes.InviteOnly)
result.Secret = channel.flags.HasMode(modes.Secret)
result.UserCount = len(channel.members)
result.Topic = channel.topic
if !channel.topicSetTime.IsZero() {
result.TopicSetAt = channel.topicSetTime.UTC().Format(utils.IRCv3TimestampFormat)
}
result.CreatedAt = channel.createdTime.UTC().Format(utils.IRCv3TimestampFormat)
result.Registered = channel.registeredFounder != ""
if result.Registered {
result.Owner = channel.registeredFounder
if !channel.registeredTime.IsZero() {
result.RegisteredAt = channel.registeredTime.UTC().Format(utils.IRCv3TimestampFormat)
}
}
return
}
type apiListResponse struct {
apiGenericResponse
Channels []apiChannelData `json:"channels"`
}
func (a *ergoAPI) handleList(w http.ResponseWriter, r *http.Request) {
channels := a.server.channels.ListableChannels()
response := apiListResponse{
apiGenericResponse: apiGenericResponse{Success: true},
Channels: make([]apiChannelData, 0, len(channels)),
}
for _, channel := range channels {
response.Channels = append(response.Channels, channel.apiData())
}
a.writeJSONResponse(response, w, r)
}