aboutsummaryrefslogtreecommitdiff
path: root/xmpp/handlers.go
diff options
context:
space:
mode:
Diffstat (limited to 'xmpp/handlers.go')
-rw-r--r--xmpp/handlers.go121
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 {