aboutsummaryrefslogtreecommitdiff
path: root/telegram
diff options
context:
space:
mode:
authorBohdan Horbeshko <bodqhrohro@gmail.com>2024-01-27 05:02:47 +0300
committerBohdan Horbeshko <bodqhrohro@gmail.com>2024-01-27 05:02:47 +0300
commite37c428c6764eff8e7b5ea286b1c7a0ba52be11a (patch)
treeff1dd7c431499e93dff99669b8df90805ea59118 /telegram
parentb9b6ba14a442f3c4394c535461bd6b1d03a7ef7b (diff)
XEP-0333 read markers for outgoing messages
Diffstat (limited to 'telegram')
-rw-r--r--telegram/client.go8
-rw-r--r--telegram/handlers.go45
-rw-r--r--telegram/utils.go27
3 files changed, 72 insertions, 8 deletions
diff --git a/telegram/client.go b/telegram/client.go
index 49fc1ef..38dff4c 100644
--- a/telegram/client.go
+++ b/telegram/client.go
@@ -34,11 +34,13 @@ type Client struct {
jid string
Session *persistence.Session
resources map[string]bool
- outbox map[string]string
content *config.TelegramContentConfig
cache *cache.Cache
online bool
+ outbox map[string]string
+ editOutbox map[string]string
+
DelayedStatuses map[int64]*DelayedStatus
DelayedStatusesLock sync.Mutex
@@ -54,6 +56,7 @@ type clientLocks struct {
chatMessageLocks map[int64]*sync.Mutex
resourcesLock sync.Mutex
outboxLock sync.Mutex
+ editOutboxLock sync.Mutex
lastMsgHashesLock sync.Mutex
authorizerReadLock sync.Mutex
@@ -109,9 +112,10 @@ func NewClient(conf config.TelegramConfig, jid string, component *xmpp.Component
jid: jid,
Session: session,
resources: make(map[string]bool),
- outbox: make(map[string]string),
content: &conf.Content,
cache: cache.NewCache(),
+ outbox: make(map[string]string),
+ editOutbox: make(map[string]string),
options: options,
DelayedStatuses: make(map[int64]*DelayedStatus),
lastMsgHashes: make(map[int64]uint64),
diff --git a/telegram/handlers.go b/telegram/handlers.go
index 0d1cda9..6f6d339 100644
--- a/telegram/handlers.go
+++ b/telegram/handlers.go
@@ -55,6 +55,33 @@ func (c *Client) cleanTempFile(path string) {
}
}
+func (c *Client) sendMarker(chatId, messageId int64, typ gateway.MarkerType) {
+ if xmppId, err := gateway.IdsDB.GetByTgIds(c.Session.Login, c.jid, chatId, messageId); err == nil {
+ resource := c.getFromOutbox(xmppId)
+
+ var stringType string
+ if typ == gateway.MarkerTypeReceived {
+ stringType = "received"
+ } else if typ == gateway.MarkerTypeDisplayed {
+ stringType = "displayed"
+ }
+ log.WithFields(log.Fields{
+ "xmppId": xmppId,
+ "resource": resource,
+ }).Debugf("marker: %s", stringType)
+
+ if resource != "" {
+ gateway.SendMessageMarker(
+ c.jid+"/"+resource,
+ strconv.FormatInt(chatId, 10),
+ c.xmpp,
+ typ,
+ xmppId,
+ )
+ }
+ }
+}
+
func (c *Client) updateHandler() {
listener := c.client.GetListener()
defer listener.Close()
@@ -141,6 +168,12 @@ func (c *Client) updateHandler() {
uhOh()
}
c.updateChatTitle(typedUpdate)
+ case client.TypeUpdateChatReadOutbox:
+ typedUpdate, ok := update.(*client.UpdateChatReadOutbox)
+ if !ok {
+ uhOh()
+ }
+ c.updateChatReadOutbox(typedUpdate)
default:
// log only handled types
continue
@@ -239,7 +272,7 @@ func (c *Client) updateMessageContent(update *client.UpdateMessageContent) {
xmppId, err := gateway.IdsDB.GetByTgIds(c.Session.Login, c.jid, update.ChatId, update.MessageId)
var ignoredResource string
if err == nil {
- ignoredResource = c.popFromOutbox(xmppId)
+ ignoredResource = c.popFromEditOutbox(xmppId)
} else {
log.Infof("Couldn't retrieve XMPP message ids for %v, an echo may happen", update.MessageId)
}
@@ -294,19 +327,23 @@ func (c *Client) updateAuthorizationState(update *client.UpdateAuthorizationStat
}
}
-// clean uploaded files
func (c *Client) updateMessageSendSucceeded(update *client.UpdateMessageSendSucceeded) {
+ // replace message ID in local database
log.Debugf("replace message %v with %v", update.OldMessageId, update.Message.Id)
if err := gateway.IdsDB.ReplaceTgId(c.Session.Login, c.jid, update.Message.ChatId, update.OldMessageId, update.Message.Id); err != nil {
log.Errorf("failed to replace %v with %v: %v", update.OldMessageId, update.Message.Id, err.Error())
}
+ c.sendMarker(update.Message.ChatId, update.Message.Id, gateway.MarkerTypeReceived)
+
+ // clean uploaded files
file, _ := c.contentToFile(update.Message.Content)
if file != nil && file.Local != nil {
c.cleanTempFile(file.Local.Path)
}
}
func (c *Client) updateMessageSendFailed(update *client.UpdateMessageSendFailed) {
+ // clean uploaded files
file, _ := c.contentToFile(update.Message.Content)
if file != nil && file.Local != nil {
c.cleanTempFile(file.Local.Path)
@@ -328,3 +365,7 @@ func (c *Client) updateChatTitle(update *client.UpdateChatTitle) {
chat.Title = update.Title
}
}
+
+func (c *Client) updateChatReadOutbox(update *client.UpdateChatReadOutbox) {
+ c.sendMarker(update.ChatId, update.LastReadOutboxMessageId, gateway.MarkerTypeDisplayed)
+}
diff --git a/telegram/utils.go b/telegram/utils.go
index 3f15488..6aab03a 100644
--- a/telegram/utils.go
+++ b/telegram/utils.go
@@ -1472,6 +1472,27 @@ func (c *Client) UpdateChatNicknames() {
}
}
+// AddToEditOutbox temporarily store the resource from which a replace message with given ID was sent
+func (c *Client) AddToEditOutbox(xmppId, resource string) {
+ c.locks.editOutboxLock.Lock()
+ defer c.locks.editOutboxLock.Unlock()
+
+ c.editOutbox[xmppId] = resource
+}
+
+func (c *Client) popFromEditOutbox(xmppId string) string {
+ c.locks.editOutboxLock.Lock()
+ defer c.locks.editOutboxLock.Unlock()
+
+ resource, ok := c.editOutbox[xmppId]
+ if ok {
+ delete(c.editOutbox, xmppId)
+ } else {
+ log.Warnf("No %v xmppId in edit outbox", xmppId)
+ }
+ return resource
+}
+
// AddToOutbox remembers the resource from which a message with given ID was sent
func (c *Client) AddToOutbox(xmppId, resource string) {
c.locks.outboxLock.Lock()
@@ -1480,14 +1501,12 @@ func (c *Client) AddToOutbox(xmppId, resource string) {
c.outbox[xmppId] = resource
}
-func (c *Client) popFromOutbox(xmppId string) string {
+func (c *Client) getFromOutbox(xmppId string) string {
c.locks.outboxLock.Lock()
defer c.locks.outboxLock.Unlock()
resource, ok := c.outbox[xmppId]
- if ok {
- delete(c.outbox, xmppId)
- } else {
+ if !ok {
log.Warnf("No %v xmppId in outbox", xmppId)
}
return resource