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) } } } }