Add method to get full room state

pull/44/head
Tulir Asokan 2021-09-30 16:05:56 +03:00
parent b5e587dd06
commit b8efcf99cc
3 changed files with 61 additions and 3 deletions

View File

@ -121,13 +121,20 @@ func (intent *IntentAPI) SendMassagedStateEvent(roomID id.RoomID, eventType even
return intent.Client.SendMassagedStateEvent(roomID, eventType, stateKey, contentJSON, ts)
}
func (intent *IntentAPI) StateEvent(roomID id.RoomID, eventType event.Type, stateKey string, outContent interface{}) (err error) {
func (intent *IntentAPI) StateEvent(roomID id.RoomID, eventType event.Type, stateKey string, outContent interface{}) error {
if err := intent.EnsureJoined(roomID); err != nil {
return err
}
return intent.Client.StateEvent(roomID, eventType, stateKey, outContent)
}
func (intent *IntentAPI) State(roomID id.RoomID) (mautrix.RoomStateMap, error) {
if err := intent.EnsureJoined(roomID); err != nil {
return nil, err
}
return intent.Client.State(roomID)
}
func (intent *IntentAPI) Member(roomID id.RoomID, userID id.UserID) *event.MemberEventContent {
member, ok := intent.as.StateStore.TryGetMember(roomID, userID)
if !ok {

View File

@ -1078,6 +1078,55 @@ func (cli *Client) StateEvent(roomID id.RoomID, eventType event.Type, stateKey s
return
}
// parseRoomStateArray parses a JSON array as a stream and stores the events inside it in a room state map.
func parseRoomStateArray(_ *http.Request, res *http.Response, responseJSON interface{}) ([]byte, error) {
response := make(RoomStateMap)
responsePtr := responseJSON.(*interface{})
*responsePtr = response
dec := json.NewDecoder(res.Body)
arrayStart, err := dec.Token()
if err != nil {
return nil, err
} else if arrayStart != json.Delim('[') {
return nil, fmt.Errorf("expected array start, got %+v", arrayStart)
}
for i := 1; dec.More(); i++ {
var evt *event.Event
err = dec.Decode(&evt)
if err != nil {
return nil, fmt.Errorf("failed to parse state array item #%d: %v", i, err)
}
subMap, ok := response[evt.Type]
if !ok {
subMap = make(map[string]*event.Event)
response[evt.Type] = subMap
}
subMap[*evt.StateKey] = evt
}
arrayEnd, err := dec.Token()
if err != nil {
return nil, err
} else if arrayEnd != json.Delim(']') {
return nil, fmt.Errorf("expected array end, got %+v", arrayStart)
}
return nil, nil
}
// State gets all state in a room.
// See https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-rooms-roomid-state
func (cli *Client) State(roomID id.RoomID) (stateMap RoomStateMap, err error) {
_, err = cli.MakeFullRequest(FullRequest{
Method: http.MethodGet,
URL: cli.BuildURL("rooms", roomID, "state"),
ResponseJSON: &stateMap,
Handler: parseRoomStateArray,
})
return
}
// UploadLink uploads an HTTP URL and then returns an MXC URI.
func (cli *Client) UploadLink(link string) (*RespMediaUpload, error) {
res, err := cli.Client.Get(link)

View File

@ -5,10 +5,12 @@ import (
"maunium.net/go/mautrix/id"
)
type RoomStateMap = map[event.Type]map[string]*event.Event
// Room represents a single Matrix room.
type Room struct {
ID id.RoomID
State map[event.Type]map[string]*event.Event
State RoomStateMap
}
// UpdateState updates the room's current state with the given Event. This will clobber events based
@ -47,6 +49,6 @@ func NewRoom(roomID id.RoomID) *Room {
// Init the State map and return a pointer to the Room
return &Room{
ID: roomID,
State: make(map[event.Type]map[string]*event.Event),
State: make(RoomStateMap),
}
}