aboutsummaryrefslogtreecommitdiff
path: root/telegram
diff options
context:
space:
mode:
Diffstat (limited to 'telegram')
-rw-r--r--telegram/client.go7
-rw-r--r--telegram/handlers.go6
-rw-r--r--telegram/utils.go57
3 files changed, 69 insertions, 1 deletions
diff --git a/telegram/client.go b/telegram/client.go
index 61d46aa..5b0217a 100644
--- a/telegram/client.go
+++ b/telegram/client.go
@@ -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),
},
diff --git a/telegram/handlers.go b/telegram/handlers.go
index abc1f5d..cc6e635 100644
--- a/telegram/handlers.go
+++ b/telegram/handlers.go
@@ -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 {
diff --git a/telegram/utils.go b/telegram/utils.go
index 9486349..4835696 100644
--- a/telegram/utils.go
+++ b/telegram/utils.go
@@ -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
+}