spaceapi/xmpp/xmpp.go

157 lines
3.1 KiB
Go
Raw Normal View History

2018-03-27 22:26:26 +00:00
package xmpp
import (
2018-03-31 23:53:40 +00:00
"crypto/tls"
2018-03-27 22:26:26 +00:00
"fmt"
"log"
2018-03-31 22:51:41 +00:00
"net"
2018-03-27 22:26:26 +00:00
"strings"
"git.hacknology.de/projekte/spaceapi"
2018-03-31 22:51:41 +00:00
"github.com/mattn/go-xmpp"
2018-03-27 22:26:26 +00:00
)
2018-04-01 13:58:17 +00:00
const (
2018-04-17 21:34:19 +00:00
commandHelp = "!help"
commandState = "!state"
commandClose = "!closed"
helpMessage = `Spacebot hat folgende Kommandos:
!help - Diese Nachricht.
!state - Ist der Space offen?
!closed - Space ist zu.
Gern geschehen.`
stateUnknown = "Ich weiß leider nicht ob der Space offen ist."
stateOpen = "Space ist OFFEN."
stateClosed = "Space ist zu."
2018-04-01 13:58:17 +00:00
)
2018-03-27 22:26:26 +00:00
func AddXMPPListener(storage *spaceapi.Storage, jid, password, target, handle string) error {
2018-03-31 22:51:41 +00:00
xmppHost, err := lookupHost(jid)
2018-03-27 22:26:26 +00:00
if err != nil {
2018-03-31 22:51:41 +00:00
return fmt.Errorf("can not find SRV record: %s", err)
2018-03-27 22:26:26 +00:00
}
2018-03-31 23:53:40 +00:00
clientOpts := xmpp.Options{
Host: xmppHost,
User: jid,
Password: password,
NoTLS: true,
Debug: false,
Session: false,
TLSConfig: &tls.Config{
InsecureSkipVerify: true,
},
}
2018-03-31 22:51:41 +00:00
log.Printf("Connecting to %s as %s", xmppHost, jid)
2018-03-31 23:53:40 +00:00
client, err := clientOpts.NewClient()
2018-03-31 22:51:41 +00:00
if err != nil {
return fmt.Errorf("can not connect to server: %s", err)
2018-03-27 22:26:26 +00:00
}
2018-03-31 22:51:41 +00:00
if _, err := client.JoinMUCNoHistory(target, handle); err != nil {
return fmt.Errorf("can not join room: %s", err)
2018-03-27 22:26:26 +00:00
}
2018-04-01 13:58:17 +00:00
go func() {
for {
chat, err := client.Recv()
if err != nil {
log.Printf("Error receiving XMPP message: %s", err)
continue
}
switch v := chat.(type) {
case xmpp.Chat:
switch v.Text {
2018-04-17 21:34:19 +00:00
case commandHelp:
if err := sendGroupMessage(client, target, helpMessage); err != nil {
log.Printf("Error sending message: %s", err)
}
case commandState:
state := storage.Status().State
msg := stateUnknown
if state.Open != nil {
switch *state.Open {
case true:
msg = stateOpen
case false:
msg = stateClosed
}
}
if err := sendGroupMessage(client, target, msg); err != nil {
2018-04-01 13:58:17 +00:00
log.Printf("Error sending message: %s", err)
}
case commandClose:
open := false
storage.Modify(func(status *spaceapi.SpaceStatus) {
status.State.Open = &open
})
}
}
}
}()
2018-04-17 21:28:01 +00:00
storage.AddListener(func(old, new spaceapi.SpaceStatus) {
if new.State.Open == nil {
return
}
if old.State.Open == new.State.Open {
2018-03-27 22:26:26 +00:00
return
}
2018-04-17 21:28:44 +00:00
msg := "Space ist jetzt OFFEN!"
2018-04-17 21:28:01 +00:00
if !*new.State.Open {
2018-04-17 21:28:44 +00:00
msg = "Space ist jetzt ZU!"
2018-03-27 22:26:26 +00:00
}
2018-04-01 13:58:17 +00:00
if err := sendGroupMessage(client, target, msg); err != nil {
2018-03-31 22:51:41 +00:00
log.Printf("Error sending status update: %s", err)
2018-03-27 22:26:26 +00:00
}
})
return nil
}
2018-03-31 22:51:41 +00:00
const defaultClientPort = 5222
func lookupHost(jid string) (string, error) {
if !strings.Contains(jid, "@") {
return "", fmt.Errorf("not a valid JID: %s", jid)
}
parts := strings.SplitN(jid, "@", 2)
_, addrs, err := net.LookupSRV("xmpp-client", "tcp", parts[1])
if err != nil {
return "", fmt.Errorf("%s", err)
}
if len(addrs) == 0 {
return fmt.Sprintf("%s:%d", parts[1], defaultClientPort), nil
}
return fmt.Sprintf("%s:%d", addrs[0].Target, addrs[0].Port), nil
}
2018-04-01 13:58:17 +00:00
func sendGroupMessage(client *xmpp.Client, target, msg string) error {
chat := xmpp.Chat{
Remote: target,
Type: "groupchat",
Text: msg,
}
if _, err := client.Send(chat); err != nil {
return err
}
return nil
}