From aaca93e66d10e55950b4f3c8f4542646b4d9cc34 Mon Sep 17 00:00:00 2001 From: Bohdan Horbeshko Date: Fri, 10 Oct 2025 07:44:44 -0400 Subject: [PATCH] Respond to jabber:version (XEP-0092) queries --- telegabber.go | 2 +- xmpp/component.go | 3 ++- xmpp/gateway/gateway.go | 3 +++ xmpp/handlers.go | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/telegabber.go b/telegabber.go index 6fb5d5b..fefbc93 100644 --- a/telegabber.go +++ b/telegabber.go @@ -68,7 +68,7 @@ func main() { log.Infof("Starting telegabber version %v", version) - sm, component, err = xmpp.NewComponent(config.XMPP, config.Telegram, *idsPath) + sm, component, err = xmpp.NewComponent(config.XMPP, config.Telegram, *idsPath, version) if err != nil { log.Fatal(err) } diff --git a/xmpp/component.go b/xmpp/component.go index b7ccd7b..6a0ae98 100644 --- a/xmpp/component.go +++ b/xmpp/component.go @@ -39,10 +39,11 @@ var sizeRegex = regexp.MustCompile("\\A([0-9]+) ?([KMGTPE]?B?)\\z") // NewComponent starts a new component and wraps it in // a stream manager that you should start yourself -func NewComponent(conf config.XMPPConfig, tc config.TelegramConfig, idsPath string) (*xmpp.StreamManager, *xmpp.Component, error) { +func NewComponent(conf config.XMPPConfig, tc config.TelegramConfig, idsPath string, version string) (*xmpp.StreamManager, *xmpp.Component, error) { var err error gateway.Jid, err = stanza.NewJid(conf.Jid) + gateway.Version = version if err != nil { return nil, nil, err } diff --git a/xmpp/gateway/gateway.go b/xmpp/gateway/gateway.go index 0b6b492..1efba08 100644 --- a/xmpp/gateway/gateway.go +++ b/xmpp/gateway/gateway.go @@ -50,6 +50,9 @@ var QueueLock = sync.Mutex{} // Jid stores the component's JID object var Jid *stanza.Jid +// Version stores this software's version +var Version string + // IdsDB provides a disk-backed bidirectional dictionary of Telegram and XMPP ids var IdsDB badger.IdsDB diff --git a/xmpp/handlers.go b/xmpp/handlers.go index 5c00419..a926523 100644 --- a/xmpp/handlers.go +++ b/xmpp/handlers.go @@ -75,6 +75,11 @@ func HandleIq(s xmpp.Sender, p stanza.Packet) { go handleGetQueryRegister(s, iq) return } + _, ok = iq.Payload.(*stanza.Version) + if ok { + go handleGetVersion(s, iq) + return + } } else if iq.Type == stanza.IQTypeSet { query, ok := iq.Payload.(*extensions.QueryRegister) if ok { @@ -643,6 +648,7 @@ func handleGetDiscoInfo(s xmpp.Sender, iq *stanza.IQ, di *stanza.DiscoInfo) { disco.AddFeatures("jabber:iq:register") } disco.AddFeatures(gateway.NSCommand) + disco.AddFeatures("jabber:iq:version") } else { chatType, chatTypeErr := getTelegramChatType(iq.From, iq.To) @@ -801,6 +807,32 @@ func handleGetQueryRegister(s xmpp.Sender, iq *stanza.IQ) { } } +func handleGetVersion(s xmpp.Sender, iq *stanza.IQ) { + component, ok := s.(*xmpp.Component) + if !ok { + log.Error("Not a component") + return + } + + 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.Version().SetInfo(gateway.Jid.Resource, gateway.Version, "") + + log.Debugf("%#v", answer.Payload) + + _ = gateway.ResumableSend(component, answer) +} + func handleSetQueryRegister(s xmpp.Sender, iq *stanza.IQ, query *extensions.QueryRegister) { component, ok := s.(*xmpp.Component) if !ok {