Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bridgev2/matrix/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ func (br *Connector) Init(bridge *bridgev2.Bridge) {
br.EventProcessor.On(event.StateMember, br.handleRoomEvent)
br.EventProcessor.On(event.StatePowerLevels, br.handleRoomEvent)
br.EventProcessor.On(event.StateRoomName, br.handleRoomEvent)
br.EventProcessor.On(event.BeeperSendState, br.handleRoomEvent)
br.EventProcessor.On(event.StateRoomAvatar, br.handleRoomEvent)
br.EventProcessor.On(event.StateTopic, br.handleRoomEvent)
br.EventProcessor.On(event.StateTombstone, br.handleRoomEvent)
Expand Down
9 changes: 6 additions & 3 deletions bridgev2/messagestatus.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (

type MessageStatusEventInfo struct {
RoomID id.RoomID
TransactionID string
SourceEventID id.EventID
NewEventID id.EventID
EventType event.Type
Expand All @@ -41,6 +42,7 @@ func StatusEventInfoFromEvent(evt *event.Event) *MessageStatusEventInfo {

return &MessageStatusEventInfo{
RoomID: evt.RoomID,
TransactionID: evt.Unsigned.TransactionID,
SourceEventID: evt.ID,
EventType: evt.Type,
MessageType: evt.Content.AsMessage().MsgType,
Expand Down Expand Up @@ -182,9 +184,10 @@ func (ms *MessageStatus) ToMSSEvent(evt *MessageStatusEventInfo) *event.BeeperMe
Type: event.RelReference,
EventID: evt.SourceEventID,
},
Status: ms.Status,
Reason: ms.ErrorReason,
Message: ms.Message,
TargetTxnID: evt.TransactionID,
Status: ms.Status,
Reason: ms.ErrorReason,
Message: ms.Message,
}
if ms.InternalError != nil {
content.InternalError = ms.InternalError.Error()
Expand Down
44 changes: 43 additions & 1 deletion bridgev2/portal.go
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,13 @@ func (portal *Portal) handleSingleEvent(ctx context.Context, rawEvt any, doneCal
}()
switch evt := rawEvt.(type) {
case *portalMatrixEvent:
isStateRequest := evt.evt.Type == event.BeeperSendState
if isStateRequest {
if err := portal.unwrapBeeperSendState(ctx, evt.evt); err != nil {
portal.sendErrorStatus(ctx, evt.evt, err)
return
}
}
res = portal.handleMatrixEvent(ctx, evt.sender, evt.evt)
if res.SendMSS {
if res.Error != nil {
Expand All @@ -520,9 +527,21 @@ func (portal *Portal) handleSingleEvent(ctx context.Context, rawEvt any, doneCal
portal.sendSuccessStatus(ctx, evt.evt, 0, "")
}
}
if res.Error != nil && evt.evt.StateKey != nil {
if !isStateRequest && res.Error != nil && evt.evt.StateKey != nil {
portal.revertRoomMeta(ctx, evt.evt)
}
if isStateRequest && res.Success {
portal.sendRoomMeta(
ctx,
evt.sender.DoublePuppet(ctx),
time.UnixMilli(evt.evt.Timestamp),
evt.evt.Type,
evt.evt.GetStateKey(),
evt.evt.Content.Parsed,
false,
evt.evt.Content.Raw,
)
}
case *portalRemoteEvent:
res = portal.handleRemoteEvent(ctx, evt.source, evt.evtType, evt.evt)
case *portalCreateEvent:
Expand All @@ -534,6 +553,29 @@ func (portal *Portal) handleSingleEvent(ctx context.Context, rawEvt any, doneCal
}
}

func (portal *Portal) unwrapBeeperSendState(ctx context.Context, evt *event.Event) error {
content, ok := evt.Content.Parsed.(*event.BeeperSendStateEventContent)
if !ok {
return fmt.Errorf("%w: %T", ErrUnexpectedParsedContentType, evt.Content.Parsed)
}
evt.Content = content.Content
evt.StateKey = &content.StateKey
evt.Type = event.Type{Type: content.Type, Class: event.StateEventType}
_ = evt.Content.ParseRaw(evt.Type)
mx, ok := portal.Bridge.Matrix.(MatrixConnectorWithArbitraryRoomState)
if !ok {
return fmt.Errorf("matrix connector doesn't support fetching state")
}
prevEvt, err := mx.GetStateEvent(ctx, portal.MXID, evt.Type, evt.GetStateKey())
if err != nil {
return fmt.Errorf("failed to get prev event: %w", err)
} else if prevEvt != nil {
evt.Unsigned.PrevContent = &prevEvt.Content
evt.Unsigned.PrevSender = prevEvt.Sender
}
return nil
}

func (portal *Portal) FindPreferredLogin(ctx context.Context, user *User, allowRelay bool) (*UserLogin, *database.UserPortal, error) {
if portal.Receiver != "" {
login, err := portal.Bridge.GetExistingUserLoginByID(ctx, portal.Receiver)
Expand Down
8 changes: 8 additions & 0 deletions event/beeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ type BeeperMessageStatusEventContent struct {

LastRetry id.EventID `json:"last_retry,omitempty"`

TargetTxnID string `json:"relates_to_txn_id,omitempty"`

MutateEventKey string `json:"mutate_event_key,omitempty"`

// Indicates the set of users to whom the event was delivered. If nil, then
Expand Down Expand Up @@ -90,6 +92,12 @@ type BeeperChatDeleteEventContent struct {
DeleteForEveryone bool `json:"delete_for_everyone,omitempty"`
}

type BeeperSendStateEventContent struct {
Type string `json:"type"`
StateKey string `json:"state_key"`
Content Content `json:"content"`
}

type IntOrString int

func (ios *IntOrString) UnmarshalJSON(data []byte) error {
Expand Down
1 change: 1 addition & 0 deletions event/content.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ var TypeMap = map[Type]reflect.Type{
BeeperMessageStatus: reflect.TypeOf(BeeperMessageStatusEventContent{}),
BeeperTranscription: reflect.TypeOf(BeeperTranscriptionEventContent{}),
BeeperDeleteChat: reflect.TypeOf(BeeperChatDeleteEventContent{}),
BeeperSendState: reflect.TypeOf(BeeperSendStateEventContent{}),

AccountDataRoomTags: reflect.TypeOf(TagEventContent{}),
AccountDataDirectChats: reflect.TypeOf(DirectChatsEventContent{}),
Expand Down
1 change: 1 addition & 0 deletions event/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ var (
BeeperMessageStatus = Type{"com.beeper.message_send_status", MessageEventType}
BeeperTranscription = Type{"com.beeper.transcription", MessageEventType}
BeeperDeleteChat = Type{"com.beeper.delete_chat", MessageEventType}
BeeperSendState = Type{"com.beeper.send_state", MessageEventType}

EventUnstablePollStart = Type{Type: "org.matrix.msc3381.poll.start", Class: MessageEventType}
EventUnstablePollResponse = Type{Type: "org.matrix.msc3381.poll.response", Class: MessageEventType}
Expand Down