Avoid webpage preview updates being sent as message edits

This commit is contained in:
Bohdan Horbeshko 2023-07-16 08:19:11 -04:00
parent e954c73bd2
commit 563cb2d624
3 changed files with 56 additions and 0 deletions

View file

@ -53,6 +53,7 @@ type Client struct {
Session *persistence.Session Session *persistence.Session
resources map[string]bool resources map[string]bool
outbox map[string]string outbox map[string]string
editQueue map[ChatMessageId]bool
content *config.TelegramContentConfig content *config.TelegramContentConfig
cache *cache.Cache cache *cache.Cache
online bool online bool
@ -69,6 +70,7 @@ type clientLocks struct {
chatMessageLocks map[int64]*sync.Mutex chatMessageLocks map[int64]*sync.Mutex
resourcesLock sync.Mutex resourcesLock sync.Mutex
outboxLock sync.Mutex outboxLock sync.Mutex
editQueueLock sync.Mutex
} }
// NewClient instantiates a Telegram App // NewClient instantiates a Telegram App
@ -125,6 +127,7 @@ func NewClient(conf config.TelegramConfig, jid string, component *xmpp.Component
Session: session, Session: session,
resources: make(map[string]bool), resources: make(map[string]bool),
outbox: make(map[string]string), outbox: make(map[string]string),
editQueue: make(map[ChatMessageId]bool),
content: &conf.Content, content: &conf.Content,
cache: cache.NewCache(), cache: cache.NewCache(),
options: options, options: options,

View file

@ -104,6 +104,13 @@ func (c *Client) updateHandler() {
} }
c.updateNewMessage(typedUpdate) c.updateNewMessage(typedUpdate)
log.Debugf("%#v", typedUpdate.Message) log.Debugf("%#v", typedUpdate.Message)
case client.TypeUpdateMessageEdited:
typedUpdate, ok := update.(*client.UpdateMessageEdited)
if !ok {
uhOh()
}
c.updateMessageEdited(typedUpdate)
log.Debugf("%#v", typedUpdate)
case client.TypeUpdateMessageContent: case client.TypeUpdateMessageContent:
typedUpdate, ok := update.(*client.UpdateMessageContent) typedUpdate, ok := update.(*client.UpdateMessageContent)
if !ok { if !ok {
@ -229,6 +236,11 @@ func (c *Client) updateNewMessage(update *client.UpdateNewMessage) {
}() }()
} }
// message content edited
func (c *Client) updateMessageEdited(update *client.UpdateMessageEdited) {
c.addToEditQueue(update.ChatId, update.MessageId)
}
// message content updated // message content updated
func (c *Client) updateMessageContent(update *client.UpdateMessageContent) { func (c *Client) updateMessageContent(update *client.UpdateMessageContent) {
markupFunction := formatter.EntityToXEP0393 markupFunction := formatter.EntityToXEP0393
@ -244,6 +256,14 @@ func (c *Client) updateMessageContent(update *client.UpdateMessageContent) {
} }
log.Infof("ignoredResource: %v", ignoredResource) log.Infof("ignoredResource: %v", ignoredResource)
if !c.deleteFromEditQueue(update.ChatId, update.MessageId) {
log.WithFields(log.Fields{
"chatId": update.ChatId,
"messageId": update.MessageId,
}).Infof("Content update with no preceding message edit, ignoring")
return
}
jids := c.getCarbonFullJids(true, ignoredResource) jids := c.getCarbonFullJids(true, ignoredResource)
if len(jids) == 0 { if len(jids) == 0 {
log.Info("The only resource is ignored, aborting") log.Info("The only resource is ignored, aborting")

View file

@ -24,6 +24,7 @@ import (
"github.com/zelenin/go-tdlib/client" "github.com/zelenin/go-tdlib/client"
) )
// VCardInfo contains intermediate data to produce a vCard
type VCardInfo struct { type VCardInfo struct {
Fn string Fn string
Photo *client.File Photo *client.File
@ -34,6 +35,12 @@ type VCardInfo struct {
Info string Info string
} }
// ChatMessageId uniquely identifies a Telegram message
type ChatMessageId struct {
ChatId int64
MessageId int64
}
var errOffline = errors.New("TDlib instance is offline") var errOffline = errors.New("TDlib instance is offline")
var spaceRegex = regexp.MustCompile(`\s+`) var spaceRegex = regexp.MustCompile(`\s+`)
@ -1384,3 +1391,29 @@ func (c *Client) getCarbonFullJids(isOutgoing bool, ignoredResource string) []st
} }
return jids return jids
} }
func (c *Client) addToEditQueue(chatId, messageId int64) {
c.locks.editQueueLock.Lock()
defer c.locks.editQueueLock.Unlock()
c.editQueue[ChatMessageId{
ChatId: chatId,
MessageId: messageId,
}] = true
}
func (c *Client) deleteFromEditQueue(chatId, messageId int64) bool {
c.locks.editQueueLock.Lock()
defer c.locks.editQueueLock.Unlock()
key := ChatMessageId{
ChatId: chatId,
MessageId: messageId,
}
_, ok := c.editQueue[key]
if ok {
delete(c.editQueue, key)
}
return ok
}