aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBohdan Horbeshko <bodqhrohro@gmail.com>2023-08-26 15:59:14 +0300
committerBohdan Horbeshko <bodqhrohro@gmail.com>2023-08-26 15:59:14 +0300
commit8ba7596ab5b9cd731fb507f60da51c6acf1ef27f (patch)
tree91e17a6bdd70300f2d784e60a1f88d47d3ec18ad
parent3c917c16983c1afdd4a21d8021461585a1e785c9 (diff)
parent64515e2c666067953e3a9680b4f0db84f3838498 (diff)
Merge branch 'master' into dev
-rw-r--r--Makefile2
-rw-r--r--telegram/cache/cache.go10
-rw-r--r--telegram/commands.go4
-rw-r--r--telegram/handlers.go19
-rw-r--r--telegram/utils.go57
-rw-r--r--xmpp/extensions/extensions.go26
-rw-r--r--xmpp/gateway/gateway.go22
-rw-r--r--xmpp/handlers.go43
8 files changed, 131 insertions, 52 deletions
diff --git a/Makefile b/Makefile
index 2eb17ac..d6323d0 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
COMMIT := $(shell git rev-parse --short HEAD)
TD_COMMIT := "8517026415e75a8eec567774072cbbbbb52376c1"
-VERSION := "v1.7.2"
+VERSION := "v1.8.0-dev"
MAKEOPTS := "-j4"
all:
diff --git a/telegram/cache/cache.go b/telegram/cache/cache.go
index 3d9608d..6847d3e 100644
--- a/telegram/cache/cache.go
+++ b/telegram/cache/cache.go
@@ -133,3 +133,13 @@ func (cache *Cache) SetStatus(id int64, show string, status string) {
Description: status,
}
}
+
+// Destruct splits a cached status into show, description and type
+func (status *Status) Destruct() (show, description, typ string) {
+ show, description = status.XMPP, status.Description
+ if show == "unavailable" {
+ typ = show
+ show = ""
+ }
+ return
+}
diff --git a/telegram/commands.go b/telegram/commands.go
index e164ce1..0c83945 100644
--- a/telegram/commands.go
+++ b/telegram/commands.go
@@ -384,7 +384,7 @@ func (c *Client) ProcessTransportCommand(cmdline string, resource string) string
}
case "config":
if len(args) > 1 {
- if !gateway.MessageOutgoingPermission && args[0] == "carbons" && args[1] == "true" {
+ if gateway.MessageOutgoingPermissionVersion == 0 && args[0] == "carbons" && args[1] == "true" {
return "The server did not allow to enable carbons"
}
@@ -658,7 +658,7 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
}
if messages != nil && messages.Messages != nil {
for _, message := range messages.Messages {
- c.ProcessIncomingMessage(targetChatId, message, "")
+ c.ProcessIncomingMessage(targetChatId, message)
}
}
// print vCard
diff --git a/telegram/handlers.go b/telegram/handlers.go
index cedea63..0d1cda9 100644
--- a/telegram/handlers.go
+++ b/telegram/handlers.go
@@ -205,27 +205,24 @@ func (c *Client) updateChatLastMessage(update *client.UpdateChatLastMessage) {
func (c *Client) updateNewMessage(update *client.UpdateNewMessage) {
chatId := update.Message.ChatId
- c.SendMessageLock.Lock()
- c.SendMessageLock.Unlock()
- xmppId, err := gateway.IdsDB.GetByTgIds(c.Session.Login, c.jid, chatId, update.Message.Id)
- var ignoredResource string
- if err == nil {
- ignoredResource = c.popFromOutbox(xmppId)
- } else {
- log.Infof("Couldn't retrieve XMPP message ids for %v, an echo may happen", update.Message.Id)
- }
-
// guarantee sequential message delivering per chat
lock := c.getChatMessageLock(chatId)
go func() {
lock.Lock()
defer lock.Unlock()
+ // ignore self outgoing messages
+ if update.Message.IsOutgoing &&
+ update.Message.SendingState != nil &&
+ update.Message.SendingState.MessageSendingStateType() == client.TypeMessageSendingStatePending {
+ return
+ }
+
log.WithFields(log.Fields{
"chat_id": chatId,
}).Warn("New message from chat")
- c.ProcessIncomingMessage(chatId, update.Message, ignoredResource)
+ c.ProcessIncomingMessage(chatId, update.Message)
c.updateLastMessageHash(update.Message.ChatId, update.Message.Id, update.Message.Content)
}()
diff --git a/telegram/utils.go b/telegram/utils.go
index a91c6da..4d77fc4 100644
--- a/telegram/utils.go
+++ b/telegram/utils.go
@@ -243,15 +243,33 @@ func (c *Client) ProcessStatusUpdate(chatID int64, status string, show string, o
cachedStatus, ok := c.cache.GetStatus(chatID)
if status == "" {
if ok {
- show, status = cachedStatus.XMPP, cachedStatus.Description
+ var typ string
+ show, status, typ = cachedStatus.Destruct()
+ if presenceType == "" {
+ presenceType = typ
+ }
+ log.WithFields(log.Fields{
+ "show": show,
+ "status": status,
+ "presenceType": presenceType,
+ }).Debug("Cached status")
} else if user != nil && user.Status != nil {
show, status, presenceType = c.userStatusToText(user.Status, chatID)
+ log.WithFields(log.Fields{
+ "show": show,
+ "status": status,
+ "presenceType": presenceType,
+ }).Debug("Status to text")
} else {
show, status = "chat", chat.Title
}
}
- c.cache.SetStatus(chatID, show, status)
+ cacheShow := show
+ if presenceType == "unavailable" {
+ cacheShow = presenceType
+ }
+ c.cache.SetStatus(chatID, cacheShow, status)
newArgs := []args.V{
gateway.SPFrom(strconv.FormatInt(chatID, 10)),
@@ -837,7 +855,7 @@ func (c *Client) messageToPrefix(message *client.Message, previewString string,
if err != nil {
log.Errorf("Could not determine if chat is PM: %v", err)
}
- isCarbonsEnabled := gateway.MessageOutgoingPermission && c.Session.Carbons
+ isCarbonsEnabled := gateway.MessageOutgoingPermissionVersion > 0 && c.Session.Carbons
// with carbons, hide for all messages in PM and only for outgoing in group chats
hideSender := isCarbonsEnabled && (message.IsOutgoing || isPM)
@@ -914,18 +932,9 @@ func (c *Client) ensureDownloadFile(file *client.File) *client.File {
}
// ProcessIncomingMessage transfers a message to XMPP side and marks it as read on Telegram side
-func (c *Client) ProcessIncomingMessage(chatId int64, message *client.Message, ignoredResource string) {
- var isCarbon bool
- isOutgoing := message.IsOutgoing
- if gateway.MessageOutgoingPermission && c.Session.Carbons {
- isCarbon = isOutgoing
- }
-
- jids := c.getCarbonFullJids(isOutgoing, ignoredResource)
- if len(jids) == 0 {
- log.Info("The only resource is ignored, aborting")
- return
- }
+func (c *Client) ProcessIncomingMessage(chatId int64, message *client.Message) {
+ isCarbon := gateway.MessageOutgoingPermissionVersion > 0 && c.Session.Carbons && message.IsOutgoing
+ jids := c.getCarbonFullJids(isCarbon, "")
var text, oob, auxText string
@@ -1369,12 +1378,26 @@ func (c *Client) UpdateChatNicknames() {
for _, id := range c.cache.ChatsKeys() {
chat, ok := c.cache.GetChat(id)
if ok {
+ newArgs := []args.V{
+ gateway.SPFrom(strconv.FormatInt(id, 10)),
+ gateway.SPNickname(chat.Title),
+ }
+
+ cachedStatus, ok := c.cache.GetStatus(id)
+ if ok {
+ show, status, typ := cachedStatus.Destruct()
+ newArgs = append(newArgs, gateway.SPShow(show), gateway.SPStatus(status))
+ if typ != "" {
+ newArgs = append(newArgs, gateway.SPType(typ))
+ }
+ }
+
gateway.SendPresence(
c.xmpp,
c.jid,
- gateway.SPFrom(strconv.FormatInt(id, 10)),
- gateway.SPNickname(chat.Title),
+ newArgs...,
)
+
gateway.SetNickname(c.jid, strconv.FormatInt(id, 10), chat.Title, c.xmpp)
}
}
diff --git a/xmpp/extensions/extensions.go b/xmpp/extensions/extensions.go
index 2d547af..192b630 100644
--- a/xmpp/extensions/extensions.go
+++ b/xmpp/extensions/extensions.go
@@ -154,12 +154,19 @@ type CarbonSent struct {
}
// ComponentPrivilege is from XEP-0356
-type ComponentPrivilege struct {
+type ComponentPrivilege1 struct {
XMLName xml.Name `xml:"urn:xmpp:privilege:1 privilege"`
Perms []ComponentPerm `xml:"perm"`
Forwarded stanza.Forwarded `xml:"urn:xmpp:forward:0 forwarded"`
}
+// ComponentPrivilege is from XEP-0356
+type ComponentPrivilege2 struct {
+ XMLName xml.Name `xml:"urn:xmpp:privilege:2 privilege"`
+ Perms []ComponentPerm `xml:"perm"`
+ Forwarded stanza.Forwarded `xml:"urn:xmpp:forward:0 forwarded"`
+}
+
// ComponentPerm is from XEP-0356
type ComponentPerm struct {
XMLName xml.Name `xml:"perm"`
@@ -227,7 +234,12 @@ func (c CarbonSent) Namespace() string {
}
// Namespace is a namespace!
-func (c ComponentPrivilege) Namespace() string {
+func (c ComponentPrivilege1) Namespace() string {
+ return c.XMLName.Space
+}
+
+// Namespace is a namespace!
+func (c ComponentPrivilege2) Namespace() string {
return c.XMLName.Space
}
@@ -297,11 +309,17 @@ func init() {
"sent",
}, CarbonSent{})
- // component privilege
+ // component privilege v1
stanza.TypeRegistry.MapExtension(stanza.PKTMessage, xml.Name{
"urn:xmpp:privilege:1",
"privilege",
- }, ComponentPrivilege{})
+ }, ComponentPrivilege1{})
+
+ // component privilege v2
+ stanza.TypeRegistry.MapExtension(stanza.PKTMessage, xml.Name{
+ "urn:xmpp:privilege:2",
+ "privilege",
+ }, ComponentPrivilege2{})
// message edit
stanza.TypeRegistry.MapExtension(stanza.PKTMessage, xml.Name{
diff --git a/xmpp/gateway/gateway.go b/xmpp/gateway/gateway.go
index 1be2fca..7a2500e 100644
--- a/xmpp/gateway/gateway.go
+++ b/xmpp/gateway/gateway.go
@@ -38,8 +38,8 @@ var IdsDB badger.IdsDB
// were changed and need to be re-flushed to the YamlDB
var DirtySessions = false
-// MessageOutgoingPermission allows to fake outgoing messages by foreign JIDs
-var MessageOutgoingPermission = false
+// MessageOutgoingPermissionVersion contains a XEP-0356 version to fake outgoing messages by foreign JIDs
+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) {
@@ -142,11 +142,19 @@ func sendMessageWrapper(to string, from string, body string, id string, componen
To: toJid.Domain,
},
}
- privilegeMessage.Extensions = append(privilegeMessage.Extensions, extensions.ComponentPrivilege{
- Forwarded: stanza.Forwarded{
- Stanza: carbonMessage,
- },
- })
+ if MessageOutgoingPermissionVersion == 2 {
+ privilegeMessage.Extensions = append(privilegeMessage.Extensions, extensions.ComponentPrivilege2{
+ Forwarded: stanza.Forwarded{
+ Stanza: carbonMessage,
+ },
+ })
+ } else {
+ privilegeMessage.Extensions = append(privilegeMessage.Extensions, extensions.ComponentPrivilege1{
+ Forwarded: stanza.Forwarded{
+ Stanza: carbonMessage,
+ },
+ })
+ }
sendMessage(&privilegeMessage, component)
} else {
sendMessage(&message, component)
diff --git a/xmpp/handlers.go b/xmpp/handlers.go
index fd1afad..36f9cf9 100644
--- a/xmpp/handlers.go
+++ b/xmpp/handlers.go
@@ -15,6 +15,7 @@ import (
"dev.narayana.im/narayana/telegabber/xmpp/gateway"
log "github.com/sirupsen/logrus"
+ "github.com/soheilhy/args"
"gosrc.io/xmpp"
"gosrc.io/xmpp/stanza"
)
@@ -148,7 +149,12 @@ func HandleMessage(s xmpp.Sender, p stanza.Packet) {
"end": body.End,
}).Warn(errors.Wrap(err, "Failed to parse fallback end!"))
}
- text = text[:start] + text[end:]
+
+ fullRunes := []rune(text)
+ cutRunes := make([]rune, 0, len(text)-int(end-start))
+ cutRunes = append(cutRunes, fullRunes[:start]...)
+ cutRunes = append(cutRunes, fullRunes[end:]...)
+ text = string(cutRunes)
}
}
var replaceId int64
@@ -183,7 +189,6 @@ func HandleMessage(s xmpp.Sender, p stanza.Packet) {
if err != nil {
log.Errorf("Failed to save ids %v/%v %v", toID, tgMessageId, msg.Id)
}
- session.AddToOutbox(msg.Id, resource)
}
} else {
/*
@@ -210,14 +215,25 @@ func HandleMessage(s xmpp.Sender, p stanza.Packet) {
}
if msg.Body == "" {
- var privilege extensions.ComponentPrivilege
- if ok := msg.Get(&privilege); ok {
- log.Debugf("privilege: %#v", privilege)
+ var privilege1 extensions.ComponentPrivilege1
+ if ok := msg.Get(&privilege1); ok {
+ log.Debugf("privilege1: %#v", privilege1)
}
- for _, perm := range privilege.Perms {
+ for _, perm := range privilege1.Perms {
if perm.Access == "message" && perm.Type == "outgoing" {
- gateway.MessageOutgoingPermission = true
+ gateway.MessageOutgoingPermissionVersion = 1
+ }
+ }
+
+ var privilege2 extensions.ComponentPrivilege2
+ if ok := msg.Get(&privilege2); ok {
+ log.Debugf("privilege2: %#v", privilege2)
+ }
+
+ for _, perm := range privilege2.Perms {
+ if perm.Access == "message" && perm.Type == "outgoing" {
+ gateway.MessageOutgoingPermissionVersion = 2
}
}
}
@@ -339,11 +355,18 @@ func handlePresence(s xmpp.Sender, p stanza.Presence) {
log.Error(errors.Wrap(err, "TDlib connection failure"))
} else {
for status := range session.StatusesRange() {
+ show, description, typ := status.Destruct()
+ newArgs := []args.V{
+ gateway.SPImmed(false),
+ }
+ if typ != "" {
+ newArgs = append(newArgs, gateway.SPType(typ))
+ }
go session.ProcessStatusUpdate(
status.ID,
- status.Description,
- status.XMPP,
- gateway.SPImmed(false),
+ description,
+ show,
+ newArgs...,
)
}
session.UpdateChatNicknames()