Avoid webpage preview updates being sent as message edits (by hash matching)
This commit is contained in:
parent
eadef987be
commit
748366ad6a
|
@ -2,6 +2,7 @@ package telegram
|
|||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"hash/maphash"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
@ -60,6 +61,9 @@ type Client struct {
|
|||
DelayedStatuses map[int64]*DelayedStatus
|
||||
DelayedStatusesLock sync.Mutex
|
||||
|
||||
lastMsgHashes map[int64]uint64
|
||||
msgHashSeed maphash.Seed
|
||||
|
||||
locks clientLocks
|
||||
SendMessageLock sync.Mutex
|
||||
}
|
||||
|
@ -69,6 +73,7 @@ type clientLocks struct {
|
|||
chatMessageLocks map[int64]*sync.Mutex
|
||||
resourcesLock sync.Mutex
|
||||
outboxLock sync.Mutex
|
||||
lastMsgHashesLock sync.Mutex
|
||||
}
|
||||
|
||||
// NewClient instantiates a Telegram App
|
||||
|
@ -129,6 +134,8 @@ func NewClient(conf config.TelegramConfig, jid string, component *xmpp.Component
|
|||
cache: cache.NewCache(),
|
||||
options: options,
|
||||
DelayedStatuses: make(map[int64]*DelayedStatus),
|
||||
lastMsgHashes: make(map[int64]uint64),
|
||||
msgHashSeed: maphash.MakeSeed(),
|
||||
locks: clientLocks{
|
||||
chatMessageLocks: make(map[int64]*sync.Mutex),
|
||||
},
|
||||
|
|
|
@ -226,6 +226,8 @@ func (c *Client) updateNewMessage(update *client.UpdateNewMessage) {
|
|||
}).Warn("New message from chat")
|
||||
|
||||
c.ProcessIncomingMessage(chatId, update.Message, ignoredResource)
|
||||
|
||||
c.updateLastMessageHash(update.Message.ChatId, update.Message.Id, update.Message.Content)
|
||||
}()
|
||||
}
|
||||
|
||||
|
@ -233,6 +235,8 @@ func (c *Client) updateNewMessage(update *client.UpdateNewMessage) {
|
|||
func (c *Client) updateMessageContent(update *client.UpdateMessageContent) {
|
||||
markupFunction := formatter.EntityToXEP0393
|
||||
|
||||
defer c.updateLastMessageHash(update.ChatId, update.MessageId, update.NewContent)
|
||||
|
||||
c.SendMessageLock.Lock()
|
||||
c.SendMessageLock.Unlock()
|
||||
xmppId, err := gateway.IdsDB.GetByTgIds(c.Session.Login, c.jid, update.ChatId, update.MessageId)
|
||||
|
@ -250,7 +254,7 @@ func (c *Client) updateMessageContent(update *client.UpdateMessageContent) {
|
|||
return
|
||||
}
|
||||
|
||||
if update.NewContent.MessageContentType() == client.TypeMessageText {
|
||||
if update.NewContent.MessageContentType() == client.TypeMessageText && c.hasLastMessageHashChanged(update.ChatId, update.MessageId, update.NewContent) {
|
||||
textContent := update.NewContent.(*client.MessageText)
|
||||
var editChar string
|
||||
if c.Session.AsciiArrows {
|
||||
|
|
|
@ -2,8 +2,10 @@ package telegram
|
|||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"hash/maphash"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
@ -1384,3 +1386,58 @@ func (c *Client) getCarbonFullJids(isOutgoing bool, ignoredResource string) []st
|
|||
}
|
||||
return jids
|
||||
}
|
||||
|
||||
func (c *Client) calculateMessageHash(messageId int64, content client.MessageContent) uint64 {
|
||||
var h maphash.Hash
|
||||
h.SetSeed(c.msgHashSeed)
|
||||
|
||||
buf8 := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(buf8, uint64(messageId))
|
||||
h.Write(buf8)
|
||||
|
||||
if content != nil && content.MessageContentType() == client.TypeMessageText {
|
||||
textContent, ok := content.(*client.MessageText)
|
||||
if !ok {
|
||||
uhOh()
|
||||
}
|
||||
|
||||
if textContent.Text != nil {
|
||||
h.WriteString(textContent.Text.Text)
|
||||
for _, entity := range textContent.Text.Entities {
|
||||
buf4 := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(buf4, uint32(entity.Offset))
|
||||
h.Write(buf4)
|
||||
binary.BigEndian.PutUint32(buf4, uint32(entity.Length))
|
||||
h.Write(buf4)
|
||||
h.WriteString(entity.Type.TextEntityTypeType())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return h.Sum64()
|
||||
}
|
||||
|
||||
func (c *Client) updateLastMessageHash(chatId, messageId int64, content client.MessageContent) {
|
||||
c.locks.lastMsgHashesLock.Lock()
|
||||
defer c.locks.lastMsgHashesLock.Unlock()
|
||||
|
||||
c.lastMsgHashes[chatId] = c.calculateMessageHash(messageId, content)
|
||||
}
|
||||
|
||||
func (c *Client) hasLastMessageHashChanged(chatId, messageId int64, content client.MessageContent) bool {
|
||||
c.locks.lastMsgHashesLock.Lock()
|
||||
defer c.locks.lastMsgHashesLock.Unlock()
|
||||
|
||||
oldHash, ok := c.lastMsgHashes[chatId]
|
||||
newHash := c.calculateMessageHash(messageId, content)
|
||||
|
||||
if !ok {
|
||||
log.Warnf("Last message hash for chat %v does not exist", chatId)
|
||||
}
|
||||
log.WithFields(log.Fields{
|
||||
"old hash": oldHash,
|
||||
"new hash": newHash,
|
||||
}).Info("Message hashes")
|
||||
|
||||
return !ok || oldHash != newHash
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue