From b70bb53c6d1c06f8c39806b4f71ee4e77c07657c Mon Sep 17 00:00:00 2001 From: Bohdan Horbeshko Date: Fri, 29 Sep 2023 08:24:15 -0400 Subject: [PATCH] Display outgoing MUC messages --- telegram/utils.go | 52 ++++++++++++++++++++++++++++------------------- xmpp/handlers.go | 23 +++++++++++++++++---- 2 files changed, 50 insertions(+), 25 deletions(-) diff --git a/telegram/utils.go b/telegram/utils.go index 5c27f7c..21c4ad3 100644 --- a/telegram/utils.go +++ b/telegram/utils.go @@ -362,7 +362,7 @@ func (c *Client) sendMUCStatuses(chatID int64) { senderId = memberChat.ChatId } - nickname := c.getMUCNickname(senderId) + nickname := c.GetMUCNickname(senderId) affiliation := c.memberStatusToAffiliation(member.Status) if c.me != nil && senderId == c.me.Id { myNickname = nickname @@ -403,7 +403,7 @@ func (c *Client) sendMUCSubject(chatID int64, resource string) { if err == nil { gateway.SendSubjectMessage( toJid, - mucJid + "/" + c.getMUCNickname(c.getSenderId(pin)), + mucJid + "/" + c.GetMUCNickname(c.GetSenderId(pin)), c.messageToText(pin, false), strconv.FormatInt(pin.Id, 10), c.xmpp, @@ -414,7 +414,8 @@ func (c *Client) sendMUCSubject(chatID int64, resource string) { } } -func (c *Client) getMUCNickname(chatID int64) string { +// GetMUCNickname generates a unique nickname for a MUC member +func (c *Client) GetMUCNickname(chatID int64) string { return c.formatContact(chatID) } @@ -450,7 +451,8 @@ func (c *Client) formatContact(chatID int64) string { return str } -func (c *Client) getSenderId(message *client.Message) (senderId int64) { +// GetSenderId extracts a sender id from a message +func (c *Client) GetSenderId(message *client.Message) (senderId int64) { if message.SenderId != nil { switch message.SenderId.MessageSenderType() { case client.TypeMessageSenderUser: @@ -466,7 +468,7 @@ func (c *Client) getSenderId(message *client.Message) (senderId int64) { } func (c *Client) formatSender(message *client.Message) string { - return c.formatContact(c.getSenderId(message)) + return c.formatContact(c.GetSenderId(message)) } func (c *Client) getMessageReply(message *client.Message) (reply *gateway.Reply, replyMsg *client.Message) { @@ -486,7 +488,7 @@ func (c *Client) getMessageReply(message *client.Message) (reply *gateway.Reply, replyId = strconv.FormatInt(message.ReplyToMessageId, 10) } reply = &gateway.Reply{ - Author: fmt.Sprintf("%v@%s", c.getSenderId(replyMsg), gateway.Jid.Full()), + Author: fmt.Sprintf("%v@%s", c.GetSenderId(replyMsg), gateway.Jid.Full()), Id: replyId, } } @@ -1006,7 +1008,7 @@ func (c *Client) messageToPrefix(message *client.Message, previewString string, } } } - if chatType != ChatTypePM || !c.Session.HideIds { + if (chatType != ChatTypePM && !c.Session.MUC) || !c.Session.HideIds { prefix = append(prefix, directionChar+strconv.FormatInt(message.Id, 10)) } // show sender in group chats @@ -1059,12 +1061,13 @@ func (c *Client) ensureDownloadFile(file *client.File) *client.File { return file } -// ProcessIncomingMessage transfers a message to XMPP side and marks it as read on Telegram side +// ProcessIncomingMessage is a legacy wrapper for SendMessageToGateway aiming only PM messages func (c *Client) ProcessIncomingMessage(chatId int64, message *client.Message) { - c.sendMessageToGateway(chatId, message, false, "", []string{}) + c.SendMessageToGateway(chatId, message, "", false, "", []string{}) } -func (c *Client) sendMessageToGateway(chatId int64, message *client.Message, delay bool, groupChatFrom string, groupChatTos []string) { +// SendMessageToGateway transfers a message to XMPP side and marks it as read on Telegram side +func (c *Client) SendMessageToGateway(chatId int64, message *client.Message, id string, delay bool, groupChatFrom string, groupChatTos []string) { var isCarbon bool var jids []string var isGroupchat bool @@ -1076,7 +1079,7 @@ func (c *Client) sendMessageToGateway(chatId int64, message *client.Message, del isGroupchat = true jids = groupChatTos - senderId := c.getSenderId(message) + senderId := c.GetSenderId(message) if senderId != 0 { originalFrom = strconv.FormatInt(senderId, 10) + "@" + gateway.Jid.Full() } @@ -1152,7 +1155,13 @@ func (c *Client) sendMessageToGateway(chatId int64, message *client.Message, del }) // forward message to XMPP - sId := strconv.FormatInt(message.Id, 10) + var sId string + if id == "" { + sId = strconv.FormatInt(message.Id, 10) + } else { + sId = id + } + var from string if groupChatFrom == "" { from = strconv.FormatInt(chatId, 10) @@ -1179,10 +1188,10 @@ func (c *Client) PrepareOutgoingMessageContent(text string) client.InputMessageC } // ProcessOutgoingMessage executes commands or sends messages to mapped chats, returns message id -func (c *Client) ProcessOutgoingMessage(chatID int64, text string, returnJid string, replyId int64, replaceId int64) int64 { +func (c *Client) ProcessOutgoingMessage(chatID int64, text string, returnJid string, replyId int64, replaceId int64) *client.Message { if !c.Online() { // we're offline - return 0 + return nil } if replaceId == 0 && (strings.HasPrefix(text, "/") || strings.HasPrefix(text, "!")) { @@ -1193,7 +1202,7 @@ func (c *Client) ProcessOutgoingMessage(chatID int64, text string, returnJid str } // do not send on success if isCommand { - return 0 + return nil } } @@ -1264,9 +1273,9 @@ func (c *Client) ProcessOutgoingMessage(chatID int64, text string, returnJid str }) if err != nil { c.returnError(returnJid, chatID, "Not edited", err) - return 0 + return nil } - return tgMessage.Id + return tgMessage } tgMessage, err := c.client.SendMessage(&client.SendMessageRequest{ @@ -1276,9 +1285,9 @@ func (c *Client) ProcessOutgoingMessage(chatID int64, text string, returnJid str }) if err != nil { c.returnError(returnJid, chatID, "Not sent", err) - return 0 + return nil } - return tgMessage.Id + return tgMessage } func (c *Client) returnMessage(returnJid string, chatID int64, text string) { @@ -1799,11 +1808,12 @@ func (c *Client) sendMessagesReverse(chatID int64, messages []*client.Message, p "", ) } else { - c.sendMessageToGateway( + c.SendMessageToGateway( chatID, message, + "", true, - mucJid + "/" + c.getMUCNickname(c.getSenderId(message)), + mucJid + "/" + c.GetMUCNickname(c.GetSenderId(message)), []string{toJid}, ) } diff --git a/xmpp/handlers.go b/xmpp/handlers.go index cfa6226..3443573 100644 --- a/xmpp/handlers.go +++ b/xmpp/handlers.go @@ -197,8 +197,8 @@ func HandleMessage(s xmpp.Sender, p stanza.Packet) { session.SendMessageLock.Lock() defer session.SendMessageLock.Unlock() - tgMessageId := session.ProcessOutgoingMessage(toID, text, msg.From, replyId, replaceId) - if tgMessageId != 0 { + tgMessage := session.ProcessOutgoingMessage(toID, text, msg.From, replyId, replaceId) + if tgMessage != nil { if replaceId != 0 { // not needed (is it persistent among clients though?) /* err = gateway.IdsDB.ReplaceIdPair(session.Session.Login, bare, replace.Id, msg.Id, tgMessageId) @@ -207,9 +207,24 @@ func HandleMessage(s xmpp.Sender, p stanza.Packet) { } */ session.AddToOutbox(replace.Id, resource) } else { - err = gateway.IdsDB.Set(session.Session.Login, bare, toID, tgMessageId, msg.Id) + err = gateway.IdsDB.Set(session.Session.Login, bare, toID, tgMessage.Id, msg.Id) if err != nil { - log.Errorf("Failed to save ids %v/%v %v", toID, tgMessageId, msg.Id) + log.Errorf("Failed to save ids %v/%v %v", toID, tgMessage.Id, msg.Id) + } + } + + // pong groupchat messages back + if msg.Type == "groupchat" { + toJid, err := stanza.NewJid(msg.To) + if err == nil && toJid.Resource == "" { + session.SendMessageToGateway( + toID, + tgMessage, + msg.Id, + false, + msg.To + "/" + session.GetMUCNickname(session.GetSenderId(tgMessage)), + []string{msg.From}, + ) } } } else {