From 5ba69f7e8e574edeb8127e258962046756def4d8 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 30 Jul 2022 11:30:55 +0300 Subject: [PATCH] Add support for admin redactions in groups --- messagetracking.go | 6 ++++-- portal.go | 35 ++++++++++++++++++++++++++++++----- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/messagetracking.go b/messagetracking.go index 6edf17e..9a66b87 100644 --- a/messagetracking.go +++ b/messagetracking.go @@ -49,7 +49,8 @@ var ( errReactionDatabaseNotFound = errors.New("reaction database entry not found") errReactionTargetNotFound = errors.New("reaction target message not found") errTargetIsFake = errors.New("target is a fake event") - errTargetSentBySomeoneElse = errors.New("target is a fake event") + errReactionSentBySomeoneElse = errors.New("target reaction was sent by someone else") + errDMSentByOtherUser = errors.New("target message was sent by the other user in a DM") errBroadcastReactionNotSupported = errors.New("reacting to status messages is not currently supported") errBroadcastSendDisabled = errors.New("sending status messages is disabled") @@ -82,7 +83,8 @@ func errorToStatusReason(err error) (reason event.MessageStatusReason, status ev errors.Is(err, errTargetIsFake), errors.Is(err, errReactionDatabaseNotFound), errors.Is(err, errReactionTargetNotFound), - errors.Is(err, errTargetSentBySomeoneElse): + errors.Is(err, errReactionSentBySomeoneElse), + errors.Is(err, errDMSentByOtherUser): return event.MessageStatusGenericError, event.MessageStatusFail, true, false, "" case errors.Is(err, whatsmeow.ErrNotConnected), errors.Is(err, errUserNotConnected): diff --git a/portal.go b/portal.go index 820670e..633b7a5 100644 --- a/portal.go +++ b/portal.go @@ -3106,6 +3106,14 @@ func (portal *Portal) convertMatrixMessage(ctx context.Context, sender *User, ev FileSha256: media.FileSHA256, FileLength: proto.Uint64(uint64(media.FileLength)), } + if media.Caption != "" { + msg.DocumentWithCaptionMessage = &waProto.FutureProofMessage{ + Message: &waProto.Message{ + DocumentMessage: msg.DocumentMessage, + }, + } + msg.DocumentMessage = nil + } case event.MsgLocation: lat, long, err := parseGeoURI(content.GeoURI) if err != nil { @@ -3333,13 +3341,12 @@ func (portal *Portal) HandleMatrixRedaction(sender *User, evt *event.Event) { go portal.sendMessageMetrics(evt, errTargetNotFound, "Ignoring", nil) } else if msg.IsFakeJID() { go portal.sendMessageMetrics(evt, errTargetIsFake, "Ignoring", nil) - } else if msg.Sender.User != sender.JID.User { - go portal.sendMessageMetrics(evt, errTargetSentBySomeoneElse, "Ignoring", nil) } else if portal.Key.JID == types.StatusBroadcastJID && portal.bridge.Config.Bridge.DisableStatusBroadcastSend { go portal.sendMessageMetrics(evt, errBroadcastSendDisabled, "Ignoring", nil) - return } else if msg.Type == database.MsgReaction { - if reaction := portal.bridge.DB.Reaction.GetByMXID(evt.Redacts); reaction == nil { + if msg.Sender.User != sender.JID.User { + go portal.sendMessageMetrics(evt, errReactionSentBySomeoneElse, "Ignoring", nil) + } else if reaction := portal.bridge.DB.Reaction.GetByMXID(evt.Redacts); reaction == nil { go portal.sendMessageMetrics(evt, errReactionDatabaseNotFound, "Ignoring", nil) } else if reactionTarget := reaction.GetTarget(); reactionTarget == nil { go portal.sendMessageMetrics(evt, errReactionTargetNotFound, "Ignoring", nil) @@ -3349,8 +3356,26 @@ func (portal *Portal) HandleMatrixRedaction(sender *User, evt *event.Event) { go portal.sendMessageMetrics(evt, err, "Error sending", nil) } } else { + key := &waProto.MessageKey{ + FromMe: proto.Bool(true), + Id: proto.String(msg.JID), + RemoteJid: proto.String(portal.Key.JID.String()), + } + if msg.Sender.User != sender.JID.User { + if portal.IsPrivateChat() { + go portal.sendMessageMetrics(evt, errDMSentByOtherUser, "Ignoring", nil) + return + } + key.FromMe = proto.Bool(false) + key.Participant = proto.String(msg.Sender.ToNonAD().String()) + } portal.log.Debugfln("Sending redaction %s of %s/%s to WhatsApp", evt.ID, msg.MXID, msg.JID) - _, err := sender.Client.RevokeMessage(portal.Key.JID, msg.JID) + _, err := sender.Client.SendMessage(context.TODO(), portal.Key.JID, "", &waProto.Message{ + ProtocolMessage: &waProto.ProtocolMessage{ + Type: waProto.ProtocolMessage_REVOKE.Enum(), + Key: key, + }, + }) go portal.sendMessageMetrics(evt, err, "Error sending", nil) } }