Browse Source

Implement simple Matrix client.

change-name
Robert Jacob 1 year ago
parent
commit
e906871502
2 changed files with 112 additions and 0 deletions
  1. +36
    -0
      cmd/spaceapi-server/main.go
  2. +76
    -0
      matrix/matrix.go

+ 36
- 0
cmd/spaceapi-server/main.go View File

@@ -5,6 +5,7 @@ import (
"net/http"

"git.hacknology.de/projekte/spaceapi"
"git.hacknology.de/projekte/spaceapi/matrix"
"git.hacknology.de/projekte/spaceapi/web"
"git.hacknology.de/projekte/spaceapi/xmpp"
"github.com/spf13/pflag"
@@ -16,6 +17,7 @@ type config struct {
StatusFile string
WebPrefix string
XMPP xmppConfig
Matrix matrixConfig
}

type xmppConfig struct {
@@ -25,6 +27,13 @@ type xmppConfig struct {
Nickname string
}

type matrixConfig struct {
Homeserver string
UserID string
Token string
Room string
}

func readConfig() (config, error) {
c := config{
Addr: ":8080",
@@ -36,6 +45,12 @@ func readConfig() (config, error) {
Room: "",
Nickname: "spacebot",
},
Matrix: matrixConfig{
Homeserver: "",
UserID: "",
Token: "",
Room: "",
},
}

pflag.String("addr", c.Addr, "Network address to listen on.")
@@ -45,6 +60,10 @@ func readConfig() (config, error) {
pflag.String("xmpp-password", c.XMPP.Password, "Password of XMPP user.")
pflag.String("xmpp-target", c.XMPP.Room, "JID of target MUC to send XMPP messages to.")
pflag.String("xmpp-handle", c.XMPP.Nickname, "Nickname for MUC.")
pflag.String("matrix-server", c.Matrix.Homeserver, "Homeserver to connect Matrix client to.")
pflag.String("matrix-user", c.Matrix.UserID, "User-ID of Matrix user (ex: @user:example.com).")
pflag.String("matrix-token", c.Matrix.Token, "Accesstoken to use for Matrix connection.")
pflag.String("matrix-room", c.Matrix.Room, "Matrix room to join.")
pflag.Parse()

viper.BindPFlags(pflag.CommandLine)
@@ -55,6 +74,10 @@ func readConfig() (config, error) {
viper.BindEnv("xmpp-password", "SPACEAPI_XMPP_PASSWORD")
viper.BindEnv("xmpp-target", "SPACEAPI_XMPP_TARGET")
viper.BindEnv("xmpp-handle", "SPACEAPI_XMPP_HANDLE")
viper.BindEnv("matrix-server", "SPACEAPI_MATRIX_SERVER")
viper.BindEnv("matrix-user", "SPACEAPI_MATRIX_USER")
viper.BindEnv("matrix-token", "SPACEAPI_MATRIX_TOKEN")
viper.BindEnv("matrix-room", "SPACEAPI_MATRIX_ROOM")

c.Addr = viper.GetString("addr")
c.StatusFile = viper.GetString("status-file")
@@ -63,6 +86,10 @@ func readConfig() (config, error) {
c.XMPP.Password = viper.GetString("xmpp-password")
c.XMPP.Room = viper.GetString("xmpp-target")
c.XMPP.Nickname = viper.GetString("xmpp-handle")
c.Matrix.Homeserver = viper.GetString("matrix-server")
c.Matrix.UserID = viper.GetString("matrix-user")
c.Matrix.Token = viper.GetString("matrix-token")
c.Matrix.Room = viper.GetString("matrix-room")

return c, nil
}
@@ -89,6 +116,15 @@ func main() {
storage.AddListener(xmppListener)
}

if c.Matrix.Homeserver != "" {
matrixListener, err := matrix.Listener(storage, c.Matrix.Homeserver, c.Matrix.UserID, c.Matrix.Token, c.Matrix.Room)
if err != nil {
log.Fatalf("Error creating Matrix client: %s", err)
}

storage.AddListener(matrixListener)
}

mux := web.CreateMux(storage, c.WebPrefix)

log.Printf("Listening on %s...", c.Addr)

+ 76
- 0
matrix/matrix.go View File

@@ -0,0 +1,76 @@
package matrix

import (
"fmt"
"log"
"strings"

"git.hacknology.de/projekte/spaceapi"
"git.hacknology.de/projekte/spaceapi/txt"
"github.com/matrix-org/gomatrix"
)

// Listener creates a listener, that will broadcast the spaceapi status to a Matrix room.
func Listener(storage *spaceapi.Storage, homeServer, userID, token, room string) (spaceapi.Listener, error) {
if !strings.HasPrefix(room, "!") {
return nil, fmt.Errorf("room needs to start with a '!'")
}

log.Printf("[matrix] Connecting to %s as %s", homeServer, userID)
cli, err := gomatrix.NewClient(homeServer, userID, token)
if err != nil {
return nil, fmt.Errorf("error creating client: %s", err)
}

rooms, err := cli.JoinedRooms()
if err != nil {
return nil, fmt.Errorf("error getting room list: %s", err)
}

joined := false
for _, r := range rooms.JoinedRooms {
if r == room {
log.Printf("[matrix] Room already joined.")
joined = true
}
}

if !joined {
log.Printf("[matrix] Joining room %q", room)
if _, err := cli.JoinRoom(room, "", nil); err != nil {
return nil, fmt.Errorf("error joining room: %s", err)
}
}

syncer := cli.Syncer.(*gomatrix.DefaultSyncer)
syncer.OnEventType("m.room.message", func(ev *gomatrix.Event) {
// TODO react to events
})

go func() {
for {
if err := cli.Sync(); err != nil {
log.Printf("Error during sync: %s", err)
}
}
}()

return func(old, new spaceapi.SpaceStatus) {
if new.State.Open == nil {
return
}

if old.State.Open == new.State.Open {
return
}

msg := txt.TransitionToOpen
if !*new.State.Open {
msg = txt.TransitionToClosed
}

if _, err := cli.SendText(room, msg); err != nil {
log.Printf("Error sending Matrix message: %s", err)
}
}, nil
}

Loading…
Cancel
Save