Add support for deletions in both directions
This commit is contained in:
parent
b5257f53d3
commit
c0313dca87
3 changed files with 106 additions and 9 deletions
|
@ -7,6 +7,7 @@
|
||||||
* [x] Reactions (RCS)
|
* [x] Reactions (RCS)
|
||||||
* [ ] Typing notifications (RCS)
|
* [ ] Typing notifications (RCS)
|
||||||
* [ ] Read receipts (RCS)
|
* [ ] Read receipts (RCS)
|
||||||
|
* [x] Message deletions (own device only)
|
||||||
* Google Messages → Matrix
|
* Google Messages → Matrix
|
||||||
* [ ] Message content
|
* [ ] Message content
|
||||||
* [x] Plain text
|
* [x] Plain text
|
||||||
|
@ -15,6 +16,7 @@
|
||||||
* [x] Reactions (RCS)
|
* [x] Reactions (RCS)
|
||||||
* [ ] Typing notifications (RCS)
|
* [ ] Typing notifications (RCS)
|
||||||
* [ ] Read receipts (RCS)
|
* [ ] Read receipts (RCS)
|
||||||
|
* [x] Message deletions (own device only)
|
||||||
* Misc
|
* Misc
|
||||||
* [x] Automatic portal creation
|
* [x] Automatic portal creation
|
||||||
* [x] After login
|
* [x] After login
|
||||||
|
|
|
@ -79,3 +79,10 @@ func UnicodeToEmojiType(emoji string) EmojiType {
|
||||||
return EmojiType_CUSTOM
|
return EmojiType_CUSTOM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func MakeReactionData(emoji string) *ReactionData {
|
||||||
|
return &ReactionData{
|
||||||
|
Unicode: emoji,
|
||||||
|
Type: UnicodeToEmojiType(emoji),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
102
portal.go
102
portal.go
|
@ -291,6 +291,8 @@ func (portal *Portal) handleMatrixMessageLoopItem(msg PortalMatrixMessage) {
|
||||||
portal.HandleMatrixMessage(msg.user, msg.evt, timings)
|
portal.HandleMatrixMessage(msg.user, msg.evt, timings)
|
||||||
case event.EventReaction:
|
case event.EventReaction:
|
||||||
portal.HandleMatrixReaction(msg.user, msg.evt)
|
portal.HandleMatrixReaction(msg.user, msg.evt)
|
||||||
|
case event.EventRedaction:
|
||||||
|
portal.HandleMatrixRedaction(msg.user, msg.evt)
|
||||||
default:
|
default:
|
||||||
portal.zlog.Warn().
|
portal.zlog.Warn().
|
||||||
Str("event_type", msg.evt.Type.Type).
|
Str("event_type", msg.evt.Type.Type).
|
||||||
|
@ -365,7 +367,8 @@ func (portal *Portal) handleMessage(source *User, evt *binary.Message) {
|
||||||
log := portal.zlog.With().
|
log := portal.zlog.With().
|
||||||
Str("message_id", evt.MessageID).
|
Str("message_id", evt.MessageID).
|
||||||
Str("participant_id", evt.ParticipantID).
|
Str("participant_id", evt.ParticipantID).
|
||||||
Str("action", "handleMessage").
|
Str("status", evt.GetMessageStatus().GetStatus().String()).
|
||||||
|
Str("action", "handle google message").
|
||||||
Logger()
|
Logger()
|
||||||
ctx := log.WithContext(context.TODO())
|
ctx := log.WithContext(context.TODO())
|
||||||
switch evt.GetMessageStatus().GetStatus() {
|
switch evt.GetMessageStatus().GetStatus() {
|
||||||
|
@ -373,7 +376,7 @@ func (portal *Portal) handleMessage(source *User, evt *binary.Message) {
|
||||||
log.Debug().Msg("Not handling incoming message that is auto downloading")
|
log.Debug().Msg("Not handling incoming message that is auto downloading")
|
||||||
return
|
return
|
||||||
case binary.MessageStatusType_MESSAGE_DELETED:
|
case binary.MessageStatusType_MESSAGE_DELETED:
|
||||||
// TODO handle deletion
|
portal.handleGoogleDeletion(ctx, evt.MessageID)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if hasInProgressMedia(evt) {
|
if hasInProgressMedia(evt) {
|
||||||
|
@ -412,6 +415,24 @@ func (portal *Portal) handleMessage(source *User, evt *binary.Message) {
|
||||||
log.Debug().Interface("event_ids", eventIDs).Msg("Handled message")
|
log.Debug().Interface("event_ids", eventIDs).Msg("Handled message")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (portal *Portal) handleGoogleDeletion(ctx context.Context, messageID string) {
|
||||||
|
log := zerolog.Ctx(ctx)
|
||||||
|
msg, err := portal.bridge.DB.Message.GetByID(ctx, portal.Key, messageID)
|
||||||
|
if err != nil {
|
||||||
|
log.Err(err).Msg("Failed to get deleted message from database")
|
||||||
|
} else if msg == nil {
|
||||||
|
log.Debug().Msg("Didn't find deleted message in database")
|
||||||
|
} else {
|
||||||
|
if _, err = portal.MainIntent().RedactEvent(portal.MXID, msg.MXID); err != nil {
|
||||||
|
log.Err(err).Msg("Faield to redact deleted message")
|
||||||
|
}
|
||||||
|
if err = msg.Delete(ctx); err != nil {
|
||||||
|
log.Err(err).Msg("Failed to delete message from database")
|
||||||
|
}
|
||||||
|
log.Debug().Msg("Handled message deletion")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (portal *Portal) syncReactions(ctx context.Context, source *User, message *database.Message, reactions []*binary.ReactionResponse) {
|
func (portal *Portal) syncReactions(ctx context.Context, source *User, message *database.Message, reactions []*binary.ReactionResponse) {
|
||||||
log := zerolog.Ctx(ctx)
|
log := zerolog.Ctx(ctx)
|
||||||
existing, err := portal.bridge.DB.Reaction.GetAllByMessage(ctx, portal.Key, message.ID)
|
existing, err := portal.bridge.DB.Reaction.GetAllByMessage(ctx, portal.Key, message.ID)
|
||||||
|
@ -1242,7 +1263,7 @@ func (portal *Portal) handleMatrixReaction(sender *User, evt *event.Event) error
|
||||||
Str("target_event_id", content.RelatesTo.EventID.String()).
|
Str("target_event_id", content.RelatesTo.EventID.String()).
|
||||||
Str("action", "handle matrix reaction").
|
Str("action", "handle matrix reaction").
|
||||||
Logger()
|
Logger()
|
||||||
ctx := log.WithContext(context.Background())
|
ctx := log.WithContext(context.TODO())
|
||||||
log.Debug().Msg("Handling Matrix reaction")
|
log.Debug().Msg("Handling Matrix reaction")
|
||||||
|
|
||||||
msg, err := portal.bridge.DB.Message.GetByMXID(ctx, content.RelatesTo.EventID)
|
msg, err := portal.bridge.DB.Message.GetByMXID(ctx, content.RelatesTo.EventID)
|
||||||
|
@ -1266,10 +1287,7 @@ func (portal *Portal) handleMatrixReaction(sender *User, evt *event.Event) error
|
||||||
}
|
}
|
||||||
resp, err := sender.Client.Messages.React(&binary.SendReactionPayload{
|
resp, err := sender.Client.Messages.React(&binary.SendReactionPayload{
|
||||||
MessageID: msg.ID,
|
MessageID: msg.ID,
|
||||||
ReactionData: &binary.ReactionData{
|
ReactionData: binary.MakeReactionData(emoji),
|
||||||
Unicode: emoji,
|
|
||||||
Type: binary.UnicodeToEmojiType(emoji),
|
|
||||||
},
|
|
||||||
Action: action,
|
Action: action,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1302,6 +1320,76 @@ func (portal *Portal) handleMatrixReaction(sender *User, evt *event.Event) error
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (portal *Portal) HandleMatrixRedaction(sender *User, evt *event.Event) {
|
||||||
|
err := portal.handleMatrixRedaction(sender, evt)
|
||||||
|
go portal.sendMessageMetrics(evt, err, "Error sending", nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (portal *Portal) handleMatrixMessageRedaction(ctx context.Context, sender *User, redacts id.EventID) error {
|
||||||
|
log := zerolog.Ctx(ctx)
|
||||||
|
msg, err := portal.bridge.DB.Message.GetByMXID(ctx, redacts)
|
||||||
|
if err != nil {
|
||||||
|
log.Err(err).Msg("Failed to get redaction target message")
|
||||||
|
return fmt.Errorf("failed to get event from database")
|
||||||
|
} else if msg == nil {
|
||||||
|
return errTargetNotFound
|
||||||
|
}
|
||||||
|
resp, err := sender.Client.Messages.Delete(msg.ID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to send message removal: %w", err)
|
||||||
|
} else if !resp.Success {
|
||||||
|
return fmt.Errorf("got non-success response")
|
||||||
|
}
|
||||||
|
err = msg.Delete(ctx)
|
||||||
|
if err != nil {
|
||||||
|
log.Err(err).Msg("Failed to delete message from database after Matrix redaction")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (portal *Portal) handleMatrixReactionRedaction(ctx context.Context, sender *User, redacts id.EventID) error {
|
||||||
|
log := zerolog.Ctx(ctx)
|
||||||
|
existingReaction, err := portal.bridge.DB.Reaction.GetByMXID(ctx, redacts)
|
||||||
|
if err != nil {
|
||||||
|
log.Err(err).Msg("Failed to get redaction target reaction")
|
||||||
|
return fmt.Errorf("failed to get event from database")
|
||||||
|
} else if existingReaction == nil {
|
||||||
|
return errTargetNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := sender.Client.Messages.React(&binary.SendReactionPayload{
|
||||||
|
MessageID: existingReaction.MessageID,
|
||||||
|
ReactionData: binary.MakeReactionData(existingReaction.Reaction),
|
||||||
|
Action: binary.Reaction_REMOVE,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to send reaction removal: %w", err)
|
||||||
|
} else if !resp.Success {
|
||||||
|
return fmt.Errorf("got non-success response")
|
||||||
|
}
|
||||||
|
err = existingReaction.Delete(ctx)
|
||||||
|
if err != nil {
|
||||||
|
log.Err(err).Msg("Failed to remove reaction from database after Matrix redaction")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (portal *Portal) handleMatrixRedaction(sender *User, evt *event.Event) error {
|
||||||
|
log := portal.zlog.With().
|
||||||
|
Str("event_id", evt.ID.String()).
|
||||||
|
Str("target_event_id", evt.Redacts.String()).
|
||||||
|
Str("action", "handle matrix redaction").
|
||||||
|
Logger()
|
||||||
|
ctx := log.WithContext(context.TODO())
|
||||||
|
log.Debug().Msg("Handling Matrix redaction")
|
||||||
|
|
||||||
|
err := portal.handleMatrixMessageRedaction(ctx, sender, evt.Redacts)
|
||||||
|
if err == errTargetNotFound {
|
||||||
|
err = portal.handleMatrixReactionRedaction(ctx, sender, evt.Redacts)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func (portal *Portal) Delete() {
|
func (portal *Portal) Delete() {
|
||||||
err := portal.Portal.Delete(context.TODO())
|
err := portal.Portal.Delete(context.TODO())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in a new issue