aboutsummaryrefslogtreecommitdiff
path: root/xmpp/handlers.go
diff options
context:
space:
mode:
Diffstat (limited to 'xmpp/handlers.go')
-rw-r--r--xmpp/handlers.go100
1 files changed, 91 insertions, 9 deletions
diff --git a/xmpp/handlers.go b/xmpp/handlers.go
index 8c6ba37..a062f0c 100644
--- a/xmpp/handlers.go
+++ b/xmpp/handlers.go
@@ -26,6 +26,7 @@ const (
TypeVCard4
)
const NodeVCard4 string = "urn:xmpp:vcard4"
+const NSCommand string = "http://jabber.org/protocol/commands"
func logPacketType(p stanza.Packet) {
log.Warnf("Ignoring packet: %T\n", p)
@@ -53,14 +54,14 @@ func HandleIq(s xmpp.Sender, p stanza.Packet) {
return
}
}
- _, ok = iq.Payload.(*stanza.DiscoInfo)
+ discoInfo, ok := iq.Payload.(*stanza.DiscoInfo)
if ok {
- go handleGetDiscoInfo(s, iq)
+ go handleGetDiscoInfo(s, iq, discoInfo)
return
}
- _, ok = iq.Payload.(*stanza.DiscoItems)
+ discoItems, ok := iq.Payload.(*stanza.DiscoItems)
if ok {
- go handleGetDiscoItems(s, iq)
+ go handleGetDiscoItems(s, iq, discoItems)
return
}
_, ok = iq.Payload.(*extensions.QueryRegister)
@@ -74,6 +75,11 @@ func HandleIq(s xmpp.Sender, p stanza.Packet) {
go handleSetQueryRegister(s, iq, query)
return
}
+ command, ok := iq.Payload.(*stanza.Command)
+ if ok {
+ go handleSetQueryCommand(s, iq, command)
+ return
+ }
}
}
@@ -468,7 +474,7 @@ func handleGetVcardIq(s xmpp.Sender, iq *stanza.IQ, typ byte) {
_ = gateway.ResumableSend(component, &answer)
}
-func handleGetDiscoInfo(s xmpp.Sender, iq *stanza.IQ) {
+func handleGetDiscoInfo(s xmpp.Sender, iq *stanza.IQ, di *stanza.DiscoInfo) {
answer, err := stanza.NewIQ(stanza.Attrs{
Type: stanza.IQTypeResult,
From: iq.To,
@@ -488,8 +494,20 @@ func handleGetDiscoInfo(s xmpp.Sender, iq *stanza.IQ) {
disco.AddFeatures(stanza.NSMsgChatMarkers)
disco.AddFeatures(stanza.NSMsgReceipts)
} else {
- disco.AddIdentity("Telegram Gateway", "gateway", "telegram")
- disco.AddFeatures("jabber:iq:register")
+ if di.Node == "" {
+ disco.AddIdentity("Telegram Gateway", "gateway", "telegram")
+ disco.AddFeatures("jabber:iq:register")
+ disco.AddFeatures(NSCommand)
+ } else {
+ for name, command := range telegram.GetCommands(telegram.CommandTypeTransport) {
+ if di.Node == name {
+ answer.Payload = di
+ di.AddIdentity(telegram.CommandToHelpString(name, command), "automation", "command-node")
+ di.AddFeatures(NSCommand, "jabber:x:data")
+ break
+ }
+ }
+ }
}
answer.Payload = disco
@@ -504,7 +522,7 @@ func handleGetDiscoInfo(s xmpp.Sender, iq *stanza.IQ) {
_ = gateway.ResumableSend(component, answer)
}
-func handleGetDiscoItems(s xmpp.Sender, iq *stanza.IQ) {
+func handleGetDiscoItems(s xmpp.Sender, iq *stanza.IQ, di *stanza.DiscoItems) {
answer, err := stanza.NewIQ(stanza.Attrs{
Type: stanza.IQTypeResult,
From: iq.To,
@@ -517,7 +535,20 @@ func handleGetDiscoItems(s xmpp.Sender, iq *stanza.IQ) {
return
}
- answer.Payload = answer.DiscoItems()
+ log.Debugf("discoItems: %#v", di)
+
+ _, ok := toToID(iq.To)
+ if !ok {
+ commands := telegram.GetCommands(telegram.CommandTypeTransport)
+ if di.Node == NSCommand {
+ answer.Payload = di
+ for name, command := range commands {
+ di.AddItem(iq.To, name, telegram.CommandToHelpString(name, command))
+ }
+ } else {
+ answer.Payload = answer.DiscoItems()
+ }
+ }
component, ok := s.(*xmpp.Component)
if !ok {
@@ -647,6 +678,57 @@ func handleSetQueryRegister(s xmpp.Sender, iq *stanza.IQ, query *extensions.Quer
}
}
+func handleSetQueryCommand(s xmpp.Sender, iq *stanza.IQ, command *stanza.Command) {
+ 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
+ }
+
+ defer gateway.ResumableSend(component, answer)
+
+ log.Debugf("command: %#v", command)
+
+ if command.Action == "" || command.Action == stanza.CommandActionExecute {
+ _, ok := toToID(iq.To)
+ if !ok {
+ bare, resource, ok := gateway.SplitJID(iq.From)
+ if !ok {
+ return
+ }
+
+ session, ok := sessions[bare]
+ if !ok {
+ return
+ }
+
+ response := session.ProcessTransportCommand("/" + command.Node, resource)
+
+ answer.Payload = &stanza.Command{
+ Node: command.Node,
+ Status: stanza.CommandStatusCompleted,
+ CommandElement: &stanza.Note{
+ Text: response,
+ Type: stanza.CommandNoteTypeInfo,
+ },
+ }
+ log.Debugf("command response: %#v", answer.Payload)
+ }
+ }
+}
+
func iqAnswerSetError(answer *stanza.IQ, payload *extensions.QueryRegister, code int) {
answer.Type = stanza.IQTypeError
answer.Payload = *payload