summaryrefslogtreecommitdiffstats
path: root/xmppbot.go
blob: 75c6c5dc99fedcb0d6fea4efca9af38c467a1da5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
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"
)

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)

	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},
	})
	if err := gc.Start(); err != nil {
		log15.Crit("Coudln't start command listener.", "error", err)
		return
	}
	defer gc.Stop()

	<-stopChan
}