diff --git a/bridge/xmpp/xmpp.go b/bridge/xmpp/xmpp.go index cf58a2fc..42bc15f0 100644 --- a/bridge/xmpp/xmpp.go +++ b/bridge/xmpp/xmpp.go @@ -14,6 +14,7 @@ import ( "github.com/42wim/matterbridge/bridge" "github.com/42wim/matterbridge/bridge/config" "github.com/42wim/matterbridge/bridge/helper" + lru "github.com/hashicorp/golang-lru" "github.com/jpillora/backoff" "github.com/matterbridge/go-xmpp" "github.com/rs/xid" @@ -28,13 +29,20 @@ type Bxmpp struct { connected bool sync.RWMutex + StanzaIDs *lru.Cache + OriginIDs *lru.Cache + avatarAvailability map[string]bool avatarMap map[string]string } func New(cfg *bridge.Config) bridge.Bridger { + stanzaIDs, _ := lru.New(5000) + originIDs, _ := lru.New(5000) return &Bxmpp{ Config: cfg, + StanzaIDs: stanzaIDs, + OriginIDs: originIDs, xmppMap: make(map[string]string), avatarAvailability: make(map[string]bool), avatarMap: make(map[string]string), @@ -124,12 +132,20 @@ func (b *Bxmpp) Send(msg config.Message) (string, error) { return "", nil } + if msg.ParentNotFound() { + msg.ParentID = "" + } + // Post normal message. var msgReplaceID string msgID := xid.New().String() if msg.ID != "" { msgReplaceID = msg.ID } + var replyID string + if res, ok := b.StanzaIDs.Get(msg.ParentID); ok { + replyID, _ = res.(string) + } b.Log.Debugf("=> Sending message %#v", msg) if _, err := b.xc.Send(xmpp.Chat{ Type: "groupchat", @@ -137,6 +153,7 @@ func (b *Bxmpp) Send(msg config.Message) (string, error) { Text: msg.Username + msg.Text, ID: msgID, ReplaceID: msgReplaceID, + ReplyID: replyID, }); err != nil { return "", err } @@ -297,6 +314,11 @@ func (b *Bxmpp) handleXMPP() error { if v.Type == "groupchat" { b.Log.Debugf("== Receiving %#v", v) + if v.ID != "" && v.StanzaID != "" { + b.StanzaIDs.Add(v.ID, v.StanzaID) + b.OriginIDs.Add(v.StanzaID, v.ID) + } + // Skip invalid messages. if b.skipMessage(v) { continue @@ -321,6 +343,12 @@ func (b *Bxmpp) handleXMPP() error { if v.ReplaceID != "" { msgID = v.ReplaceID } + + var parentID string + if res, ok := b.OriginIDs.Get(v.ReplyID); ok { + parentID, _ = res.(string) + } + rmsg := config.Message{ Username: b.parseNick(v.Remote), Text: v.Text, @@ -328,6 +356,7 @@ func (b *Bxmpp) handleXMPP() error { Account: b.Account, Avatar: avatar, UserID: v.Remote, + ParentID: parentID, ID: msgID, Event: event, }