diff --git a/telegram/utils.go b/telegram/utils.go index 40553a4..5c27f7c 100644 --- a/telegram/utils.go +++ b/telegram/utils.go @@ -328,6 +328,8 @@ func (c *Client) JoinMUC(chatId int64, resource string, limit int32) { if err == nil { c.sendMessagesReverse(chatId, messages, false, c.jid+"/"+resource) } + + c.sendMUCSubject(chatId, resource) } func (c *Client) sendMUCStatuses(chatID int64) { @@ -392,6 +394,26 @@ func (c *Client) sendMUCStatuses(chatID int64) { ) } +func (c *Client) sendMUCSubject(chatID int64, resource string) { + pin, err := c.client.GetChatPinnedMessage(&client.GetChatPinnedMessageRequest{ + ChatId: chatID, + }) + mucJid := strconv.FormatInt(chatID, 10) + "@" + gateway.Jid.Bare() + toJid := c.jid + "/" + resource + if err == nil { + gateway.SendSubjectMessage( + toJid, + mucJid + "/" + c.getMUCNickname(c.getSenderId(pin)), + c.messageToText(pin, false), + strconv.FormatInt(pin.Id, 10), + c.xmpp, + int64(pin.Date), + ) + } else { + gateway.SendSubjectMessage(toJid, mucJid, "", "", c.xmpp, 0) + } +} + func (c *Client) getMUCNickname(chatID int64) string { return c.formatContact(chatID) } diff --git a/xmpp/extensions/extensions.go b/xmpp/extensions/extensions.go index 41a58fa..8ff034d 100644 --- a/xmpp/extensions/extensions.go +++ b/xmpp/extensions/extensions.go @@ -261,6 +261,11 @@ type MessageAddress struct { Jid string `xml:"jid,attr"` } +// EmptySubject is a dummy for MUCs to circumvent omitempty. Not registered as it would conflict with Subject field +type EmptySubject struct { + XMLName xml.Name `xml:"subject"` +} + // Namespace is a namespace! func (c PresenceNickExtension) Namespace() string { return c.XMLName.Space diff --git a/xmpp/gateway/gateway.go b/xmpp/gateway/gateway.go index a831db6..89f1eb8 100644 --- a/xmpp/gateway/gateway.go +++ b/xmpp/gateway/gateway.go @@ -43,26 +43,31 @@ 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, timestamp int64, isCarbon, isGroupchat bool, originalFrom string) { - sendMessageWrapper(to, from, body, id, component, reply, timestamp, "", isCarbon, isGroupchat, originalFrom) +func SendMessage(to, from, body, id string, component *xmpp.Component, reply *Reply, timestamp int64, isCarbon, isGroupchat bool, originalFrom string) { + sendMessageWrapper(to, from, body, "", id, component, reply, timestamp, "", isCarbon, isGroupchat, false, originalFrom) } // SendServiceMessage creates and sends a simple message stanza from transport -func SendServiceMessage(to string, body string, component *xmpp.Component) { - sendMessageWrapper(to, "", body, "", component, nil, 0, "", false, false, "") +func SendServiceMessage(to, body string, component *xmpp.Component) { + sendMessageWrapper(to, "", body, "", "", component, nil, 0, "", false, 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, 0, "", false, false, "") +func SendTextMessage(to, from, body string, component *xmpp.Component) { + sendMessageWrapper(to, from, body, "", "", component, nil, 0, "", false, 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, timestamp int64, oob string, isCarbon bool, isGroupchat bool, originalFrom string) { - sendMessageWrapper(to, from, body, id, component, reply, timestamp, oob, isCarbon, isGroupchat, originalFrom) +func SendMessageWithOOB(to, from, body, id string, component *xmpp.Component, reply *Reply, timestamp int64, oob string, isCarbon, isGroupchat bool, originalFrom string) { + sendMessageWrapper(to, from, body, "", id, component, reply, timestamp, oob, isCarbon, isGroupchat, false, originalFrom) } -func sendMessageWrapper(to string, from string, body string, id string, component *xmpp.Component, reply *Reply, timestamp int64, oob string, isCarbon bool, isGroupchat bool, originalFrom string) { +// SendSubjectMessage creates and sends a MUC subject +func SendSubjectMessage(to, from, subject, id string, component *xmpp.Component, timestamp int64) { + sendMessageWrapper(to, from, "", subject, id, component, nil, timestamp, "", false, true, true, "") +} + +func sendMessageWrapper(to, from, body, subject, id string, component *xmpp.Component, reply *Reply, timestamp int64, oob string, isCarbon, isGroupchat, forceSubject bool, originalFrom string) { toJid, err := stanza.NewJid(to) if err != nil { log.WithFields(log.Fields{ @@ -115,7 +120,8 @@ func sendMessageWrapper(to string, from string, body string, id string, componen Type: messageType, Id: id, }, - Body: body, + Subject: subject, + Body: body, } if oob != "" { @@ -132,7 +138,7 @@ func sendMessageWrapper(to string, from string, body string, id string, componen message.Extensions = append(message.Extensions, extensions.NewReplyFallback(reply.Start, reply.End)) } } - if !isCarbon && toJid.Resource != "" { + if !isGroupchat && !isCarbon && toJid.Resource != "" { message.Extensions = append(message.Extensions, stanza.HintNoCopy{}) } if timestamp != 0 { @@ -159,6 +165,9 @@ func sendMessageWrapper(to string, from string, body string, id string, componen }, }) } + if subject == "" && forceSubject { + message.Extensions = append(message.Extensions, extensions.EmptySubject{}) + } if isCarbon { carbonMessage := extensions.ClientMessage{