diff options
-rw-r--r-- | handlers/bind.go | 28 | ||||
-rw-r--r-- | handlers/dial.go | 50 | ||||
-rw-r--r-- | handlers/handlers.go | 1 | ||||
-rw-r--r-- | handlers/login.go | 28 | ||||
-rw-r--r-- | handlers/presence.go | 28 | ||||
-rw-r--r-- | handlers/raw.go | 32 | ||||
-rw-r--r-- | handlers/stop.go | 25 | ||||
-rw-r--r-- | xmppbot.go | 120 |
8 files changed, 206 insertions, 106 deletions
diff --git a/handlers/bind.go b/handlers/bind.go new file mode 100644 index 0000000..cdacf06 --- /dev/null +++ b/handlers/bind.go @@ -0,0 +1,28 @@ +package handlers + +import ( + "fmt" + + "github.com/bjc/goctl" +) + +type Bind struct{} + +func (bh Bind) Name() string { + return "bind" +} + +func (bh Bind) Help() string { + return "binds XMPP resource" +} + +func (bh Bind) Run(_ *goctl.Goctl, args []string) string { + if xb == nil { + return "ERROR: bot is not connected." + } + + if err := xb.Bind(); err != nil { + return fmt.Sprintf("ERROR: couldn't bind resource: %s.", err) + } + return "ok" +} diff --git a/handlers/dial.go b/handlers/dial.go new file mode 100644 index 0000000..408f748 --- /dev/null +++ b/handlers/dial.go @@ -0,0 +1,50 @@ +package handlers + +import ( + "fmt" + "strings" + "time" + + _ "github.com/ThomsonReutersEikon/nitro/src/sipbot" // "sip" scheme + "github.com/ThomsonReutersEikon/open-nitro/src/bots" + _ "github.com/ThomsonReutersEikon/open-nitro/src/bots/xmppclient" // Register "xmpp" and "xmpp-bosh" bot schemes + "github.com/bjc/goctl" +) + +const timeout = 1 * time.Second + +var xb bots.Bot + +type Dial struct{} + +func (dh Dial) Name() string { + return "dial" +} + +func (dh Dial) Help() string { + return "scheme jid password host[:port]" +} + +func (dh Dial) Run(_ *goctl.Goctl, args []string) string { + if xb != nil { + return "ERROR: bot is already connected." + } + + if len(args) != 4 { + return "ERROR: dial requires scheme, JID, password, and host[:port]" + } + + url := fmt.Sprintf("%s://%s,%s:%s@%s", args[0], args[1], emailFromJID(args[1]), args[2], args[3]) + + var err error + xb, err = bots.Dial(url, timeout) + if err != nil { + return fmt.Sprintf("ERROR: %s.", err) + } + return "ok" +} + +func emailFromJID(jid string) string { + i := strings.Index(jid, "@") + return strings.Replace(jid[:i], ".", "@", 1) +} diff --git a/handlers/handlers.go b/handlers/handlers.go new file mode 100644 index 0000000..5ac8282 --- /dev/null +++ b/handlers/handlers.go @@ -0,0 +1 @@ +package handlers diff --git a/handlers/login.go b/handlers/login.go new file mode 100644 index 0000000..b516c08 --- /dev/null +++ b/handlers/login.go @@ -0,0 +1,28 @@ +package handlers + +import ( + "fmt" + + "github.com/bjc/goctl" +) + +type Login struct{} + +func (lh Login) Name() string { + return "login" +} + +func (lh Login) Help() string { + return "authenticates to server" +} + +func (lh Login) Run(_ *goctl.Goctl, args []string) string { + if xb == nil { + return "ERROR: bot is not connected." + } + + if err := xb.Login(); err != nil { + return fmt.Sprintf("ERROR: couldn't login: %s.", err) + } + return "ok" +} diff --git a/handlers/presence.go b/handlers/presence.go new file mode 100644 index 0000000..aae28d0 --- /dev/null +++ b/handlers/presence.go @@ -0,0 +1,28 @@ +package handlers + +import ( + "fmt" + + "github.com/bjc/goctl" +) + +type Presence struct{} + +func (ph Presence) Name() string { + return "presence" +} + +func (ph Presence) Help() string { + return "sends available presence broadcast" +} + +func (ph Presence) Run(_ *goctl.Goctl, args []string) string { + if xb == nil { + return "ERROR: bot is not connected." + } + + if err := xb.Online(); err != nil { + return fmt.Sprintf("ERROR: sending available presence: %s", err) + } + return "ok" +} diff --git a/handlers/raw.go b/handlers/raw.go new file mode 100644 index 0000000..3a93947 --- /dev/null +++ b/handlers/raw.go @@ -0,0 +1,32 @@ +package handlers + +import ( + "fmt" + + "github.com/ThomsonReutersEikon/open-nitro/src/bots/xmppclient" + "github.com/bjc/goctl" +) + +type Raw struct{} + +func (rh Raw) Name() string { + return "raw" +} + +func (rh Raw) Help() string { + return "send raw data" +} + +func (rh Raw) Run(_ *goctl.Goctl, args []string) string { + if xb == nil { + return "ERROR: bot is not connected." + } + + if b, ok := xb.(*xmppclient.Bot); !ok { + return "ERROR: can only send raw data on XMPP bot." + } else if err := b.Sendf(args[0]); err != nil { + return fmt.Sprintf("ERROR: sending raw data: %s", err) + } + + return "ok" +} diff --git a/handlers/stop.go b/handlers/stop.go new file mode 100644 index 0000000..8c04327 --- /dev/null +++ b/handlers/stop.go @@ -0,0 +1,25 @@ +package handlers + +import "github.com/bjc/goctl" + +type Stop struct { + C chan bool +} + +func (sh Stop) Name() string { + return "stop" +} + +func (sh Stop) Help() string { + return "stops this bot" +} + +func (sh Stop) Run(_ *goctl.Goctl, args []string) string { + if xb != nil { + xb.Shutdown() + xb = nil + } + + sh.C <- true + return "Stopping" +} @@ -2,126 +2,34 @@ package main import ( "flag" - "fmt" - "strings" - "time" "gopkg.in/inconshreveable/log15.v2" - _ "github.com/ThomsonReutersEikon/nitro/src/sipbot" // "sip" scheme - "github.com/ThomsonReutersEikon/open-nitro/src/bots" - "github.com/ThomsonReutersEikon/open-nitro/src/bots/xmppclient" // Register "xmpp" and "xmpp-bosh" bot schemes "github.com/bjc/goctl" + "github.com/bjc/xmppbot/handlers" ) -const timeout = 1 * time.Second - -var ( - gc goctl.Goctl - xb bots.Bot - stopChan chan bool -) - -func emailFromJID(jid string) string { - i := strings.Index(jid, "@") - return strings.Replace(jid[:i], ".", "@", 1) -} - -func dialHandler(args []string) string { - if xb != nil { - return "ERROR: bot is already connected." - } - - if len(args) != 4 { - return "ERROR: dial requires scheme, JID, password, and host[:port]" - } - - url := fmt.Sprintf("%s://%s,%s:%s@%s", args[0], args[1], emailFromJID(args[1]), args[2], args[3]) - - var err error - xb, err = bots.Dial(url, timeout) - if err != nil { - return fmt.Sprintf("ERROR: %s.", err) - } - return "ok" -} - -func loginHandler(args []string) string { - if xb == nil { - return "ERROR: bot is not connected." - } - - if err := xb.Login(); err != nil { - return fmt.Sprintf("ERROR: couldn't login: %s.", err) - } - return "ok" -} - -func bindHandler(args []string) string { - if xb == nil { - return "ERROR: bot is not connected." - } - - if err := xb.Bind(); err != nil { - return fmt.Sprintf("ERROR: couldn't bind resource: %s.", err) - } - return "ok" -} - -func stopHandler(args []string) string { - if xb == nil { - return "ERROR: bot is not connected." - } - xb.Shutdown() - xb = nil - - stopChan <- true - return "Stopping" -} - -func presenceHandler(args []string) string { - if xb == nil { - return "ERROR: bot is not connected." - } - - if err := xb.Online(); err != nil { - return fmt.Sprintf("ERROR: sending available presence: %s", err) - } - return "ok" -} - -func rawHandler(args []string) string { - if xb == nil { - return "ERROR: bot is not connected." - } - - if b, ok := xb.(*xmppclient.Bot); !ok { - return "ERROR: can only send raw data on XMPP bot." - } else if err := b.Sendf(args[0]); err != nil { - return fmt.Sprintf("ERROR: sending raw data: %s", err) - } - - return "ok" -} - func main() { var sockPath string flag.StringVar(&sockPath, "f", "/tmp/xmppbot", "path to UNIX control socket") flag.Parse() - stopChan = make(chan bool, 1) + stopChan := make(chan bool, 1) goctl.Logger.SetHandler(log15.StdoutHandler) - gc = goctl.NewGoctl(sockPath) - gc.AddHandlers([]*goctl.Handler{ - {"dial", dialHandler}, - {"login", loginHandler}, - {"bind", bindHandler}, - {"stop", stopHandler}, - {"presence", presenceHandler}, - {"raw", rawHandler}, - }) + gc := goctl.NewGoctl(sockPath) + if err := gc.AddHandlers([]goctl.Handler{ + handlers.Dial{}, + handlers.Login{}, + handlers.Bind{}, + handlers.Stop{C: stopChan}, + handlers.Presence{}, + handlers.Raw{}, + }); err != nil { + log15.Crit("Couldn't set up command handlers.", "error", err) + return + } if err := gc.Start(); err != nil { log15.Crit("Coudln't start command listener.", "error", err) return |