summaryrefslogtreecommitdiffstats
path: root/xmppbot.go
blob: 72ab7778818f7c3558641b68b2352bd909117650 (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
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
	b, err := bots.Dial(url, timeout)
	if err != nil {
		return fmt.Sprintf("ERROR: %s.", err)
	}
	xb = b
	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 pingHandler(args []string) string {
	if xb == nil {
		return "ERROR: bot is not connected."
	}

	//	xb.Sendf(`<iq type='get' to='%s' id='ping'><ping xmlns='urn:xmpp:ping'/></iq>`, xb.JID().Domain())
	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},
		{"ping", pingHandler},
	})
	if err := gc.Start(); err != nil {
		log15.Crit("Coudln't start command listener.", "error", err)
		return
	}
	defer gc.Stop()

	<-stopChan
}