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:
parent
ca4c3c09df
commit
05c37122fc
25
docs/API.md
25
docs/API.md
@ -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`
|
||||
-------------
|
||||
|
||||
|
||||
56
irc/api.go
56
irc/api.go
@ -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)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user