diff --git a/src/github.com/matrix-org/dendrite/clientapi/events/clientevent.go b/src/github.com/matrix-org/dendrite/clientapi/events/clientevent.go index 5c9679637..84bcf57e8 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/events/clientevent.go +++ b/src/github.com/matrix-org/dendrite/clientapi/events/clientevent.go @@ -1,6 +1,9 @@ package events -import "encoding/json" +import ( + "encoding/json" + "github.com/matrix-org/gomatrixserverlib" +) // ClientEvent is an event which is fit for consumption by clients, in accordance with the specification. type ClientEvent struct { @@ -8,7 +11,28 @@ type ClientEvent struct { Sender string `json:"sender"` Type string `json:"type"` StateKey *string `json:"state_key,omitempty"` - Unsigned json.RawMessage `json:"unsigned"` + Unsigned json.RawMessage `json:"unsigned,omitempty"` OriginServerTS int64 `json:"origin_server_ts"` EventID string `json:"event_id"` } + +// ToClientEvents converts server events to client events +func ToClientEvents(serverEvs []gomatrixserverlib.Event) []ClientEvent { + evs := make([]ClientEvent, len(serverEvs)) + for i, se := range serverEvs { + evs[i] = ToClientEvent(se) + } + return evs +} + +// ToClientEvent converts a single server event to a client event +func ToClientEvent(se gomatrixserverlib.Event) ClientEvent { + return ClientEvent{ + Content: json.RawMessage(se.Content()), + Sender: se.Sender(), + Type: se.Type(), + StateKey: se.StateKey(), + // TODO: No unsigned / origin_server_ts fields? + EventID: se.EventID(), + } +} diff --git a/src/github.com/matrix-org/dendrite/syncserver/sync/requestpool.go b/src/github.com/matrix-org/dendrite/syncserver/sync/requestpool.go index 6056521d0..cef731ffd 100644 --- a/src/github.com/matrix-org/dendrite/syncserver/sync/requestpool.go +++ b/src/github.com/matrix-org/dendrite/syncserver/sync/requestpool.go @@ -8,6 +8,7 @@ import ( log "github.com/Sirupsen/logrus" "github.com/matrix-org/dendrite/clientapi/auth" + "github.com/matrix-org/dendrite/clientapi/events" "github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/syncserver/storage" @@ -148,9 +149,9 @@ func (rp *RequestPool) currentSyncForUser(req syncRequest) (*types.Response, err res.NextBatch = pos.String() for roomID, d := range data { jr := types.NewJoinResponse() - jr.Timeline.Events = d.RecentEvents + jr.Timeline.Events = events.ToClientEvents(d.RecentEvents) jr.Timeline.Limited = true - jr.State.Events = d.State + jr.State.Events = events.ToClientEvents(d.State) res.Rooms.Join[roomID] = *jr } return res, nil @@ -170,16 +171,16 @@ func (rp *RequestPool) currentSyncForUser(req syncRequest) (*types.Response, err // c) Check if the user is CURRENTLY left/banned. If so, add room to 'archived' block. // Synapse has a TODO: How do we handle ban -> leave in same batch? // 4) Add joined rooms (joined room list) - events, err := rp.db.EventsInRange(req.since, currentPos) + evs, err := rp.db.EventsInRange(req.since, currentPos) if err != nil { return nil, err } res := types.NewResponse() // for now, dump everything as join timeline events - for _, ev := range events { + for _, ev := range evs { roomData := res.Rooms.Join[ev.RoomID()] - roomData.Timeline.Events = append(roomData.Timeline.Events, ev) + roomData.Timeline.Events = append(roomData.Timeline.Events, events.ToClientEvent(ev)) res.Rooms.Join[ev.RoomID()] = roomData } diff --git a/src/github.com/matrix-org/dendrite/syncserver/types/types.go b/src/github.com/matrix-org/dendrite/syncserver/types/types.go index 69cf6760d..150b7095c 100644 --- a/src/github.com/matrix-org/dendrite/syncserver/types/types.go +++ b/src/github.com/matrix-org/dendrite/syncserver/types/types.go @@ -3,6 +3,7 @@ package types import ( "strconv" + "github.com/matrix-org/dendrite/clientapi/events" "github.com/matrix-org/gomatrixserverlib" ) @@ -24,10 +25,10 @@ type RoomData struct { type Response struct { NextBatch string `json:"next_batch"` AccountData struct { - Events []gomatrixserverlib.Event `json:"events"` + Events []events.ClientEvent `json:"events"` } `json:"account_data"` Presence struct { - Events []gomatrixserverlib.Event `json:"events"` + Events []events.ClientEvent `json:"events"` } `json:"presence"` Rooms struct { Join map[string]JoinResponse `json:"join"` @@ -49,8 +50,8 @@ func NewResponse() *Response { // TODO: We really shouldn't have to do all this to coerce encoding/json to Do The Right Thing. We should // really be using our own Marshal/Unmarshal implementations otherwise this may prove to be a CPU bottleneck. // This also applies to NewJoinResponse, NewInviteResponse and NewLeaveResponse. - res.AccountData.Events = make([]gomatrixserverlib.Event, 0) - res.Presence.Events = make([]gomatrixserverlib.Event, 0) + res.AccountData.Events = make([]events.ClientEvent, 0) + res.Presence.Events = make([]events.ClientEvent, 0) return &res } @@ -58,61 +59,61 @@ func NewResponse() *Response { // JoinResponse represents a /sync response for a room which is under the 'join' key. type JoinResponse struct { State struct { - Events []gomatrixserverlib.Event `json:"events"` + Events []events.ClientEvent `json:"events"` } `json:"state"` Timeline struct { - Events []gomatrixserverlib.Event `json:"events"` - Limited bool `json:"limited"` - PrevBatch string `json:"prev_batch"` + Events []events.ClientEvent `json:"events"` + Limited bool `json:"limited"` + PrevBatch string `json:"prev_batch"` } `json:"timeline"` Ephemeral struct { - Events []gomatrixserverlib.Event `json:"events"` + Events []events.ClientEvent `json:"events"` } `json:"ephemeral"` AccountData struct { - Events []gomatrixserverlib.Event `json:"events"` + Events []events.ClientEvent `json:"events"` } `json:"account_data"` } // NewJoinResponse creates an empty response with initialised arrays. func NewJoinResponse() *JoinResponse { res := JoinResponse{} - res.State.Events = make([]gomatrixserverlib.Event, 0) - res.Timeline.Events = make([]gomatrixserverlib.Event, 0) - res.Ephemeral.Events = make([]gomatrixserverlib.Event, 0) - res.AccountData.Events = make([]gomatrixserverlib.Event, 0) + res.State.Events = make([]events.ClientEvent, 0) + res.Timeline.Events = make([]events.ClientEvent, 0) + res.Ephemeral.Events = make([]events.ClientEvent, 0) + res.AccountData.Events = make([]events.ClientEvent, 0) return &res } // InviteResponse represents a /sync response for a room which is under the 'invite' key. type InviteResponse struct { InviteState struct { - Events []gomatrixserverlib.Event + Events []events.ClientEvent } `json:"invite_state"` } // NewInviteResponse creates an empty response with initialised arrays. func NewInviteResponse() *InviteResponse { res := InviteResponse{} - res.InviteState.Events = make([]gomatrixserverlib.Event, 0) + res.InviteState.Events = make([]events.ClientEvent, 0) return &res } // LeaveResponse represents a /sync response for a room which is under the 'leave' key. type LeaveResponse struct { State struct { - Events []gomatrixserverlib.Event `json:"events"` + Events []events.ClientEvent `json:"events"` } `json:"state"` Timeline struct { - Events []gomatrixserverlib.Event `json:"events"` - Limited bool `json:"limited"` - PrevBatch string `json:"prev_batch"` + Events []events.ClientEvent `json:"events"` + Limited bool `json:"limited"` + PrevBatch string `json:"prev_batch"` } `json:"timeline"` } // NewLeaveResponse creates an empty response with initialised arrays. func NewLeaveResponse() *LeaveResponse { res := LeaveResponse{} - res.State.Events = make([]gomatrixserverlib.Event, 0) - res.Timeline.Events = make([]gomatrixserverlib.Event, 0) + res.State.Events = make([]events.ClientEvent, 0) + res.Timeline.Events = make([]events.ClientEvent, 0) return &res }