easybridge/appservice/server.go

127 lines
2.8 KiB
Go

package appservice
import (
"encoding/json"
"fmt"
"strings"
"net/http"
"github.com/gorilla/mux"
log "github.com/sirupsen/logrus"
"git.deuxfleurs.fr/Deuxfleurs/easybridge/mxlib"
"git.deuxfleurs.fr/Deuxfleurs/easybridge/connector"
)
type Config struct {
HttpBindAddr string
Server string
DbType string
DbPath string
MatrixDomain string
}
var registration *mxlib.Registration
var config *Config
func Start(r *mxlib.Registration, c *Config) (chan error, error) {
registration = r
config = c
err := InitDb()
if err != nil {
return nil, err
}
router := mux.NewRouter()
router.HandleFunc("/_matrix/app/v1/transactions/{txnId}", handleTxn)
router.HandleFunc("/transactions/{txnId}", handleTxn)
errch := make(chan error)
go func() {
log.Printf("Starting HTTP server on %s", config.HttpBindAddr)
err := http.ListenAndServe(config.HttpBindAddr, checkTokenAndLog(router))
if err != nil {
errch <- err
}
}()
return errch, nil
}
func checkTokenAndLog(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
if strings.Join(r.Form["access_token"], "") != registration.HsToken {
http.Error(w, "Wrong or no token provided", http.StatusUnauthorized)
return
}
log.Printf("%s %s %s\n", r.RemoteAddr, r.Method, r.URL)
handler.ServeHTTP(w, r)
})
}
func handleTxn(w http.ResponseWriter, r *http.Request) {
if r.Method == "PUT" {
var txn mxlib.Transaction
err := json.NewDecoder(r.Body).Decode(&txn)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
log.Printf("JSON decode error: %s\n", err)
return
}
log.Printf("Got transaction %#v\n", txn)
for i := range txn.Events {
handleTxnEvent(&txn.Events[i])
}
fmt.Fprintf(w, "{}\n")
} else {
http.Error(w, "Expected PUT request", http.StatusBadRequest)
}
}
func handleTxnEvent(e *mxlib.Event) {
if e.Type == "m.room.message" {
ev := &connector.Event{
Type: connector.EVENT_MESSAGE,
Text: e.Content["body"].(string),
}
typ := e.Content["msgtype"].(string)
if typ == "m.emote" {
ev.Type = connector.EVENT_MESSAGE
}
// Look up if this is a private message room
var pm_room DbPmRoomMap
is_pm_room := !db.First(&pm_room, DbPmRoomMap{
MxRoomID: e.RoomId,
}).RecordNotFound()
if is_pm_room {
acct := FindAccount(pm_room.MxUserID, pm_room.AccountName)
if acct != nil && e.Sender == pm_room.MxUserID {
ev.Author = acct.Conn.User()
ev.Recipient = pm_room.UserID
acct.Conn.Send(ev)
}
}
// Look up if this is a regular room
var room DbRoomMap
is_room := !db.First(&room, DbRoomMap{
MxRoomID: e.RoomId,
}).RecordNotFound()
if is_room {
acct := FindJoinedAccount(e.Sender, room.Protocol, room.RoomID)
if acct != nil {
ev.Author = acct.Conn.User()
ev.Room = room.RoomID
acct.Conn.Send(ev)
}
}
}
}