mirror of
https://github.com/tulir/mautrix-whatsapp
synced 2024-12-13 17:13:11 +01:00
Fix bridging receipts with multiple message IDs
This commit is contained in:
parent
5c1b57d7b8
commit
6b260dceda
3 changed files with 27 additions and 53 deletions
2
go.mod
2
go.mod
|
@ -8,7 +8,7 @@ require (
|
||||||
github.com/mattn/go-sqlite3 v1.14.9
|
github.com/mattn/go-sqlite3 v1.14.9
|
||||||
github.com/prometheus/client_golang v1.11.0
|
github.com/prometheus/client_golang v1.11.0
|
||||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||||
go.mau.fi/whatsmeow v0.0.0-20211109215855-2e8804d7e690
|
go.mau.fi/whatsmeow v0.0.0-20211110182414-ba28bae40fb5
|
||||||
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d
|
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d
|
||||||
google.golang.org/protobuf v1.27.1
|
google.golang.org/protobuf v1.27.1
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -139,8 +139,8 @@ github.com/tidwall/sjson v1.2.3 h1:5+deguEhHSEjmuICXZ21uSSsXotWMA0orU783+Z7Cp8=
|
||||||
github.com/tidwall/sjson v1.2.3/go.mod h1:5WdjKx3AQMvCJ4RG6/2UYT7dLrGvJUV1x4jdTAyGvZs=
|
github.com/tidwall/sjson v1.2.3/go.mod h1:5WdjKx3AQMvCJ4RG6/2UYT7dLrGvJUV1x4jdTAyGvZs=
|
||||||
go.mau.fi/libsignal v0.0.0-20211109153248-a67163214910 h1:9FFhG0OmkuMau5UEaTgiUQ+7cSbtbOQ7hiWKdN8OI3I=
|
go.mau.fi/libsignal v0.0.0-20211109153248-a67163214910 h1:9FFhG0OmkuMau5UEaTgiUQ+7cSbtbOQ7hiWKdN8OI3I=
|
||||||
go.mau.fi/libsignal v0.0.0-20211109153248-a67163214910/go.mod h1:AufGrvVh+00Nc07Jm4hTquh7yleZyn20tKJI2wCPAKg=
|
go.mau.fi/libsignal v0.0.0-20211109153248-a67163214910/go.mod h1:AufGrvVh+00Nc07Jm4hTquh7yleZyn20tKJI2wCPAKg=
|
||||||
go.mau.fi/whatsmeow v0.0.0-20211109215855-2e8804d7e690 h1:Yx5v2ut+kd5YG+bLhCxqPnCEZ+yau2wKsQerk3VYtbY=
|
go.mau.fi/whatsmeow v0.0.0-20211110182414-ba28bae40fb5 h1:ERlXDWd0vj62SldgFSqCkjtVpyUgmxRtyKMH20ADW7Q=
|
||||||
go.mau.fi/whatsmeow v0.0.0-20211109215855-2e8804d7e690/go.mod h1:8jUjOAi3xtGubxcZgG8uSHpAdyQXBRbWAfxkctX/4y4=
|
go.mau.fi/whatsmeow v0.0.0-20211110182414-ba28bae40fb5/go.mod h1:8jUjOAi3xtGubxcZgG8uSHpAdyQXBRbWAfxkctX/4y4=
|
||||||
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
|
66
user.go
66
user.go
|
@ -722,58 +722,32 @@ func (user *User) handleReceipt(receipt *events.Receipt) {
|
||||||
if portal == nil || len(portal.MXID) == 0 {
|
if portal == nil || len(portal.MXID) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if receipt.IsFromMe {
|
// The order of the message ID array depends on the sender's platform, so we just have to find
|
||||||
user.markSelfRead(portal, receipt.MessageID)
|
// the last message based on timestamp. Also, timestamps only have second precision, so if
|
||||||
} else {
|
// there are many messages at the same second just mark them all as read, because we don't
|
||||||
intent := user.bridge.GetPuppetByJID(receipt.Sender).IntentFor(portal)
|
// know which one is last
|
||||||
ok := user.markOtherRead(portal, intent, receipt.MessageID)
|
markAsRead := make([]*database.Message, 0, 1)
|
||||||
if !ok {
|
var bestTimestamp time.Time
|
||||||
// Message not found, try any previous IDs
|
for _, msgID := range receipt.MessageIDs {
|
||||||
for i := len(receipt.PreviousIDs) - 1; i >= 0; i-- {
|
msg := user.bridge.DB.Message.GetByJID(portal.Key, msgID)
|
||||||
ok = user.markOtherRead(portal, intent, receipt.PreviousIDs[i])
|
|
||||||
if ok {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (user *User) markOtherRead(portal *Portal, intent *appservice.IntentAPI, messageID types.MessageID) bool {
|
|
||||||
msg := user.bridge.DB.Message.GetByJID(portal.Key, messageID)
|
|
||||||
if msg == nil || msg.IsFakeMXID() {
|
if msg == nil || msg.IsFakeMXID() {
|
||||||
return false
|
continue
|
||||||
}
|
}
|
||||||
|
if msg.Timestamp.After(bestTimestamp) {
|
||||||
|
bestTimestamp = msg.Timestamp
|
||||||
|
markAsRead = append(markAsRead[:0], msg)
|
||||||
|
} else if msg != nil && msg.Timestamp.Equal(bestTimestamp) {
|
||||||
|
markAsRead = append(markAsRead, msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intent := user.bridge.GetPuppetByJID(receipt.Sender).IntentFor(portal)
|
||||||
|
for _, msg := range markAsRead {
|
||||||
err := intent.MarkReadWithContent(portal.MXID, msg.MXID, &CustomReadReceipt{DoublePuppet: intent.IsCustomPuppet})
|
err := intent.MarkReadWithContent(portal.MXID, msg.MXID, &CustomReadReceipt{DoublePuppet: intent.IsCustomPuppet})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
user.log.Warnfln("Failed to mark message %s as read by %s: %v", msg.MXID, intent.UserID, err)
|
user.log.Warnfln("Failed to mark message %s as read by %s: %v", msg.MXID, intent.UserID, err)
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (user *User) markSelfRead(portal *Portal, messageID types.MessageID) {
|
|
||||||
puppet := user.bridge.GetPuppetByCustomMXID(user.MXID)
|
|
||||||
if puppet == nil || puppet.CustomIntent() == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var message *database.Message
|
|
||||||
if messageID == "" {
|
|
||||||
message = user.bridge.DB.Message.GetLastInChat(portal.Key)
|
|
||||||
if message == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
user.log.Debugfln("User read chat %s/%s in WhatsApp mobile (last known event: %s/%s)", portal.Key.JID, portal.MXID, message.JID, message.MXID)
|
|
||||||
} else {
|
} else {
|
||||||
message = user.bridge.DB.Message.GetByJID(portal.Key, messageID)
|
user.log.Debugfln("Marked %s as read by %s", msg.MXID, intent.UserID)
|
||||||
if message == nil || message.IsFakeMXID() {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
user.log.Debugfln("User read message %s/%s in %s/%s in WhatsApp mobile", message.JID, message.MXID, portal.Key.JID, portal.MXID)
|
|
||||||
}
|
|
||||||
err := puppet.CustomIntent().MarkReadWithContent(portal.MXID, message.MXID, &CustomReadReceipt{DoublePuppet: true})
|
|
||||||
if err != nil {
|
|
||||||
user.log.Warnfln("Failed to bridge own read receipt in %s: %v", portal.Key.JID, err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -788,7 +762,7 @@ func (user *User) markSelfReadFull(portal *Portal) {
|
||||||
}
|
}
|
||||||
err := puppet.CustomIntent().MarkReadWithContent(portal.MXID, lastMessage.MXID, &CustomReadReceipt{DoublePuppet: true})
|
err := puppet.CustomIntent().MarkReadWithContent(portal.MXID, lastMessage.MXID, &CustomReadReceipt{DoublePuppet: true})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
user.log.Warnfln("Failed to mark %s in %s as read after backfill: %v", lastMessage.MXID, portal.MXID, err)
|
user.log.Warnfln("Failed to mark %s (last message) in %s as read: %v", lastMessage.MXID, portal.MXID, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue