From 599cf16cdbb8567cf2ab1ce42aee5f493884de96 Mon Sep 17 00:00:00 2001 From: Bohdan Horbeshko Date: Sat, 27 Jan 2024 06:13:45 -0500 Subject: [PATCH] Request and send to Telegram XEP-0333 displayed markers by "receipts" option --- persistence/sessions.go | 11 +++++++++++ telegram/commands.go | 1 + telegram/handlers.go | 2 +- telegram/utils.go | 21 ++++++++++++++------- xmpp/gateway/gateway.go | 19 +++++++++++-------- xmpp/handlers.go | 24 ++++++++++++++++++++++++ 6 files changed, 62 insertions(+), 16 deletions(-) diff --git a/persistence/sessions.go b/persistence/sessions.go index 1658cc9..56ff152 100644 --- a/persistence/sessions.go +++ b/persistence/sessions.go @@ -42,6 +42,7 @@ type Session struct { OOBMode bool `yaml:":oobmode"` Carbons bool `yaml:":carbons"` HideIds bool `yaml:":hideids"` + Receipts bool `yaml:":receipts"` } var configKeys = []string{ @@ -52,6 +53,7 @@ var configKeys = []string{ "oobmode", "carbons", "hideids", + "receipts", } var sessionDB *SessionsYamlDB @@ -130,6 +132,8 @@ func (s *Session) Get(key string) (string, error) { return fromBool(s.Carbons), nil case "hideids": return fromBool(s.HideIds), nil + case "receipts": + return fromBool(s.Receipts), nil } return "", errors.New("Unknown session property") @@ -194,6 +198,13 @@ func (s *Session) Set(key string, value string) (string, error) { } s.HideIds = b return value, nil + case "receipts": + b, err := toBool(value) + if err != nil { + return "", err + } + s.Receipts = b + return value, nil } return "", errors.New("Unknown session property") diff --git a/telegram/commands.go b/telegram/commands.go index 19fd655..b5c856e 100644 --- a/telegram/commands.go +++ b/telegram/commands.go @@ -202,6 +202,7 @@ func (c *Client) sendMessagesReverse(chatID int64, messages []*client.Message) { c.xmpp, reply, false, + false, ) } } diff --git a/telegram/handlers.go b/telegram/handlers.go index 6f6d339..c715932 100644 --- a/telegram/handlers.go +++ b/telegram/handlers.go @@ -298,7 +298,7 @@ func (c *Client) updateMessageContent(update *client.UpdateMessageContent) { markupFunction, )) for _, jid := range jids { - gateway.SendMessage(jid, strconv.FormatInt(update.ChatId, 10), text, "e"+strconv.FormatInt(update.MessageId, 10), c.xmpp, nil, false) + gateway.SendMessage(jid, strconv.FormatInt(update.ChatId, 10), text, "e"+strconv.FormatInt(update.MessageId, 10), c.xmpp, nil, false, false) } } } diff --git a/telegram/utils.go b/telegram/utils.go index 6aab03a..966c5c2 100644 --- a/telegram/utils.go +++ b/telegram/utils.go @@ -1074,24 +1074,31 @@ func (c *Client) ProcessIncomingMessage(chatId int64, message *client.Message) { } // mark message as read - c.client.ViewMessages(&client.ViewMessagesRequest{ - ChatId: chatId, - MessageIds: []int64{message.Id}, - ForceRead: true, - }) + if !c.Session.Receipts { + c.MarkAsRead(chatId, message.Id) + } // forward message to XMPP sId := strconv.FormatInt(message.Id, 10) sChatId := strconv.FormatInt(chatId, 10) for _, jid := range jids { - gateway.SendMessageWithOOB(jid, sChatId, text, sId, c.xmpp, reply, oob, isCarbon) + gateway.SendMessageWithOOB(jid, sChatId, text, sId, c.xmpp, reply, oob, isCarbon, c.Session.Receipts) if auxText != "" { - gateway.SendMessage(jid, sChatId, auxText, sId, c.xmpp, reply, isCarbon) + gateway.SendMessage(jid, sChatId, auxText, sId, c.xmpp, reply, isCarbon, c.Session.Receipts) } } } +// MarkAsRead marks a message as read +func (c *Client) MarkAsRead(chatId, messageId int64) { + c.client.ViewMessages(&client.ViewMessagesRequest{ + ChatId: chatId, + MessageIds: []int64{messageId}, + ForceRead: true, + }) +} + // PrepareMessageContent creates a simple text message func (c *Client) PrepareOutgoingMessageContent(text string) client.InputMessageContent { return c.prepareOutgoingMessageContent(text, nil) diff --git a/xmpp/gateway/gateway.go b/xmpp/gateway/gateway.go index 5ba201a..7d3cbb6 100644 --- a/xmpp/gateway/gateway.go +++ b/xmpp/gateway/gateway.go @@ -54,23 +54,23 @@ var DirtySessions = false var MessageOutgoingPermissionVersion = 0 // SendMessage creates and sends a message stanza -func SendMessage(to string, from string, body string, id string, component *xmpp.Component, reply *Reply, isCarbon bool) { - sendMessageWrapper(to, from, body, id, component, reply, nil, "", isCarbon) +func SendMessage(to string, from string, body string, id string, component *xmpp.Component, reply *Reply, isCarbon, requestReceipt bool) { + sendMessageWrapper(to, from, body, id, component, reply, nil, "", isCarbon, requestReceipt) } // SendServiceMessage creates and sends a simple message stanza from transport func SendServiceMessage(to string, body string, component *xmpp.Component) { - sendMessageWrapper(to, "", body, "", component, nil, nil, "", false) + sendMessageWrapper(to, "", body, "", component, nil, nil, "", false, false) } // SendTextMessage creates and sends a simple message stanza func SendTextMessage(to string, from string, body string, component *xmpp.Component) { - sendMessageWrapper(to, from, body, "", component, nil, nil, "", false) + sendMessageWrapper(to, from, body, "", component, nil, nil, "", false, false) } // SendMessageWithOOB creates and sends a message stanza with OOB URL -func SendMessageWithOOB(to string, from string, body string, id string, component *xmpp.Component, reply *Reply, oob string, isCarbon bool) { - sendMessageWrapper(to, from, body, id, component, reply, nil, oob, isCarbon) +func SendMessageWithOOB(to string, from string, body string, id string, component *xmpp.Component, reply *Reply, oob string, isCarbon, requestReceipt bool) { + sendMessageWrapper(to, from, body, id, component, reply, nil, oob, isCarbon, requestReceipt) } // SendMessageMarker creates and sends a message stanza with a XEP-0333 marker @@ -78,10 +78,10 @@ func SendMessageMarker(to string, from string, component *xmpp.Component, marker sendMessageWrapper(to, from, "", "", component, nil, &marker{ Type: markerType, Id: markerId, - }, "", false) + }, "", false, false) } -func sendMessageWrapper(to string, from string, body string, id string, component *xmpp.Component, reply *Reply, marker *marker, oob string, isCarbon bool) { +func sendMessageWrapper(to string, from string, body string, id string, component *xmpp.Component, reply *Reply, marker *marker, oob string, isCarbon, requestReceipt bool) { toJid, err := stanza.NewJid(to) if err != nil { log.WithFields(log.Fields{ @@ -150,6 +150,9 @@ func sendMessageWrapper(to string, from string, body string, id string, componen if !isCarbon && toJid.Resource != "" { message.Extensions = append(message.Extensions, stanza.HintNoCopy{}) } + if requestReceipt { + message.Extensions = append(message.Extensions, stanza.ReceiptRequest{}) + } if isCarbon { carbonMessage := extensions.ClientMessage{ diff --git a/xmpp/handlers.go b/xmpp/handlers.go index 541eb63..9caf886 100644 --- a/xmpp/handlers.go +++ b/xmpp/handlers.go @@ -254,6 +254,30 @@ func HandleMessage(s xmpp.Sender, p stanza.Packet) { gateway.MessageOutgoingPermissionVersion = 2 } } + + var displayed stanza.MarkDisplayed + msg.Get(&displayed) + if displayed.ID != "" { + log.Debugf("displayed: %#v", displayed) + + bare, _, ok := gateway.SplitJID(msg.From) + if !ok { + return + } + session, ok := sessions[bare] + if !ok { + return + } + toID, ok := toToID(msg.To) + if !ok { + return + } + msgId, err := strconv.ParseInt(displayed.ID, 10, 64) + if err == nil { + session.MarkAsRead(toID, msgId) + } + return + } } if msg.Type == "error" {