diff options
Diffstat (limited to 'xmpp/handlers.go')
-rw-r--r-- | xmpp/handlers.go | 121 |
1 files changed, 88 insertions, 33 deletions
diff --git a/xmpp/handlers.go b/xmpp/handlers.go index 4c27b3c..96a30c4 100644 --- a/xmpp/handlers.go +++ b/xmpp/handlers.go @@ -27,6 +27,12 @@ const ( ) const NodeVCard4 string = "urn:xmpp:vcard4" +type discoType int +const ( + discoTypeInfo discoType = iota + discoTypeItems +) + func logPacketType(p stanza.Packet) { log.Warnf("Ignoring packet: %T\n", p) } @@ -55,12 +61,12 @@ func HandleIq(s xmpp.Sender, p stanza.Packet) { } _, ok = iq.Payload.(*stanza.DiscoInfo) if ok { - go handleGetDiscoInfo(s, iq) + go handleGetDisco(discoTypeInfo, s, iq) return } _, ok = iq.Payload.(*stanza.DiscoItems) if ok { - go handleGetDiscoItems(s, iq) + go handleGetDisco(discoTypeItems, s, iq) return } _, ok = iq.Payload.(*extensions.QueryRegister) @@ -441,7 +447,7 @@ func handleGetVcardIq(s xmpp.Sender, iq *stanza.IQ, typ byte) { _ = gateway.ResumableSend(component, &answer) } -func handleGetDiscoInfo(s xmpp.Sender, iq *stanza.IQ) { +func handleGetDisco(dt discoType, s xmpp.Sender, iq *stanza.IQ) { answer, err := stanza.NewIQ(stanza.Attrs{ Type: stanza.IQTypeResult, From: iq.To, @@ -454,41 +460,90 @@ func handleGetDiscoInfo(s xmpp.Sender, iq *stanza.IQ) { return } - disco := answer.DiscoInfo() - _, ok := toToID(iq.To) - if ok { - disco.AddIdentity("", "account", "registered") - } else { - disco.AddIdentity("Telegram Gateway", "gateway", "telegram") - disco.AddFeatures("jabber:iq:register") - } - answer.Payload = disco - - log.Debugf("%#v", answer) + if dt == discoTypeInfo { + disco := answer.DiscoInfo() + toID, toOk := toToID(iq.To) + if toOk { + disco.AddIdentity("", "account", "registered") + } else { + disco.AddIdentity("Telegram Gateway", "gateway", "telegram") + disco.AddFeatures("jabber:iq:register") + } + + var isMuc bool + bare, _, fromOk := gateway.SplitJID(iq.From) + if fromOk { + session, sessionOk := sessions[bare] + if sessionOk && session.Session.MUC { + if toOk { + chat, _, err := session.GetContactByID(toID, nil) + if err == nil && session.IsGroup(chat) { + isMuc = true + disco.AddIdentity(chat.Title, "conference", "text") + + disco.AddFeatures( + "http://jabber.org/protocol/muc", + "muc_persistent", + "muc_hidden", + "muc_membersonly", + "muc_unmoderated", + "muc_nonanonymous", + "muc_unsecured", + ) + fields := []*stanza.Field{ + &stanza.Field{ + Var: "FORM_TYPE", + Type: "hidden", + ValuesList: []string{"http://jabber.org/protocol/muc#roominfo"}, + }, + &stanza.Field{ + Var: "muc#roominfo_description", + Label: "Description", + ValuesList: []string{session.GetChatDescription(chat)}, + }, + &stanza.Field{ + Var: "muc#roominfo_occupants", + Label: "Number of occupants", + ValuesList: []string{strconv.FormatInt(int64(session.GetChatMemberCount(chat)), 10)}, + }, + } - component, ok := s.(*xmpp.Component) - if !ok { - log.Error("Not a component") - return - } + disco.Form = stanza.NewForm(fields, "result") + } + } else { + disco.AddFeatures(stanza.NSDiscoItems) + disco.AddIdentity("Telegram group chats", "conference", "text") + } + } + } + if toOk && !isMuc { + disco.AddIdentity("", "account", "registered") + } + answer.Payload = disco + } else if dt == discoTypeItems { + disco := answer.DiscoItems() - _ = gateway.ResumableSend(component, answer) -} + _, ok := toToID(iq.To) + if !ok { + bare, _, ok := gateway.SplitJID(iq.From) + if ok { + // raw access, no need to create a new instance if not connected + session, ok := sessions[bare] + if ok && session.Session.MUC { + bareJid := gateway.Jid.Bare() + disco.AddItem(bareJid, "", "Telegram group chats") + for _, chat := range session.GetGroupChats() { + jid := strconv.FormatInt(chat.Id, 10) + "@" + bareJid + disco.AddItem(jid, "", chat.Title) + } + } + } + } -func handleGetDiscoItems(s xmpp.Sender, iq *stanza.IQ) { - answer, err := stanza.NewIQ(stanza.Attrs{ - Type: stanza.IQTypeResult, - From: iq.To, - To: iq.From, - Id: iq.Id, - Lang: "en", - }) - if err != nil { - log.Errorf("Failed to create answer IQ: %v", err) - return + answer.Payload = disco } - answer.Payload = answer.DiscoItems() + log.Debugf("%#v", answer) component, ok := s.(*xmpp.Component) if !ok { |