aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--appservice/account.go65
-rw-r--r--appservice/db.go2
-rw-r--r--appservice/matrix.go31
-rw-r--r--appservice/server.go21
-rw-r--r--mxlib/api.go16
5 files changed, 112 insertions, 23 deletions
diff --git a/appservice/account.go b/appservice/account.go
index 4316362..230860a 100644
--- a/appservice/account.go
+++ b/appservice/account.go
@@ -84,23 +84,32 @@ func (a *Account) Event(event *Event) {
if err != nil {
log.Printf("Could not leave %s as %s", a.MatrixUser, mx_room_id)
}
- } else if event.Type == EVENT_MESSAGE {
+ } else {
+ log.Printf("%s msg %s %s", a.Protocol, event.Author, event.Room)
+ mx_room_id := ""
+
if len(event.Room) > 0 {
- log.Printf("%s msg %s %s", a.Protocol, event.Author, event.Room)
- mx_room_id, err := dbGetMxRoom(a.Protocol, event.Room)
+ mx_room_id, err = dbGetMxRoom(a.Protocol, event.Room)
if err != nil {
return
}
-
- err = mxSendMessageAs(mx_room_id, event.Text, mx_user_id)
+ } else {
+ mx_room_id, err = dbGetMxPmRoom(a.Protocol, event.Author, mx_user_id, a.MatrixUser, a.AccountName)
if err != nil {
- log.Printf("Could not send %s as %s", event.Text, mx_user_id)
+ return
}
- } else {
- // TODO
+ }
+
+ typ := "m.text"
+ if event.Type == EVENT_ACTION {
+ typ = "m.emote"
+ }
+
+ err = mxSendMessageAs(mx_room_id, typ, event.Text, mx_user_id)
+ if err != nil {
+ log.Printf("Could not send %s as %s", event.Text, mx_user_id)
}
}
- // TODO
}
// ----
@@ -142,6 +151,44 @@ func dbGetMxRoom(protocol string, roomId RoomID) (string, error) {
return room.MxRoomID, nil
}
+func dbGetMxPmRoom(protocol string, them UserID, themMxId string, usMxId string, usAccount string) (string, error) {
+ var room DbPmRoomMap
+
+ must_create := db.First(&room, DbPmRoomMap{
+ MxUserID: usMxId,
+ Protocol: protocol,
+ AccountName: usAccount,
+ UserID: them,
+ }).RecordNotFound()
+ if must_create {
+ name := fmt.Sprintf("%s (%s)", them, protocol)
+
+ mx_room_id, err := mxCreateDirectRoomAs(name, []string{usMxId}, themMxId)
+ if err != nil {
+ log.Printf("Could not create room for %s: %s", name, err)
+ return "", err
+ }
+
+ err = mxRoomJoinAs(mx_room_id, themMxId)
+ if err != nil {
+ log.Printf("Could not join %s as %s", mx_room_id, themMxId)
+ return "", err
+ }
+
+ room = DbPmRoomMap{
+ MxUserID: usMxId,
+ Protocol: protocol,
+ AccountName: usAccount,
+ UserID: them,
+ MxRoomID: mx_room_id,
+ }
+ db.Create(&room)
+ }
+ log.Printf("Got PM room id: %s", room.MxRoomID)
+
+ return room.MxRoomID, nil
+}
+
func dbGetMxUser(protocol string, userId UserID) (string, error) {
var user DbUserMap
diff --git a/appservice/db.go b/appservice/db.go
index f8cbccf..c2af428 100644
--- a/appservice/db.go
+++ b/appservice/db.go
@@ -63,7 +63,7 @@ type DbPmRoomMap struct {
AccountName string
// User id to reach them
- UserID connector.RoomID
+ UserID connector.UserID
// Bridged room for PMs
MxRoomID string `gorm:"index:mxroomoid"`
diff --git a/appservice/matrix.go b/appservice/matrix.go
index 96f643a..c85861d 100644
--- a/appservice/matrix.go
+++ b/appservice/matrix.go
@@ -135,6 +135,9 @@ func mxCreateRoom(name string, alias string, invite []string) (string, error) {
CreationContent: map[string]interface{} {
"m.federate": false,
},
+ PowerLevels: map[string]interface{} {
+ "invite": 100,
+ },
}
var rep CreateRoomResponse
err := mxPostApiCall("/_matrix/client/r0/createRoom", &rq, &rep)
@@ -144,6 +147,28 @@ func mxCreateRoom(name string, alias string, invite []string) (string, error) {
return rep.RoomId, nil
}
+func mxCreateDirectRoomAs(name string, invite []string, as_user string) (string, error) {
+ rq := CreateRoomNoAliasRequest{
+ Preset: "private_chat",
+ Name: name,
+ Topic: "",
+ Invite: invite,
+ CreationContent: map[string]interface{} {
+ "m.federate": false,
+ },
+ PowerLevels: map[string]interface{} {
+ "invite": 100,
+ },
+ IsDirect: true,
+ }
+ var rep CreateRoomResponse
+ err := mxPostApiCall("/_matrix/client/r0/createRoom?user_id=" + url.QueryEscape(as_user), &rq, &rep)
+ if err != nil {
+ return "", err
+ }
+ return rep.RoomId, nil
+}
+
func mxRoomInvite(room string, user string) error {
rq := RoomInviteRequest{
UserId: user,
@@ -177,10 +202,10 @@ func mxRoomLeaveAs(room string, user string) error {
return err
}
-func mxSendMessageAs(room string, body string, user string) error {
+func mxSendMessageAs(room string, typ string, body string, user string) error {
txn_id := time.Now().UnixNano()
- rq := RoomSendRequest{
- MsgType: "m.text",
+ rq := RoomSendMessageRequest{
+ MsgType: typ,
Body: body,
}
var rep RoomSendResponse
diff --git a/appservice/server.go b/appservice/server.go
index 8e4c263..3f52119 100644
--- a/appservice/server.go
+++ b/appservice/server.go
@@ -62,13 +62,18 @@ func checkTokenAndLog(handler http.Handler) http.Handler {
}
func handleTxn(w http.ResponseWriter, r *http.Request) {
- var txn mxlib.Transaction
- err := json.NewDecoder(r.Body).Decode(&txn)
- if err != nil {
- http.Error(w, err.Error(), http.StatusBadRequest)
- }
-
- log.Printf("Got transaction %#v\n", txn)
+ 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
+ }
- fmt.Fprintf(w, "{}\n")
+ log.Printf("Got transaction %#v\n", txn)
+ fmt.Fprintf(w, "{}\n")
+ } else {
+ http.Error(w, "Expected PUT request", http.StatusBadRequest)
+ }
}
diff --git a/mxlib/api.go b/mxlib/api.go
index cb2d10c..84c125b 100644
--- a/mxlib/api.go
+++ b/mxlib/api.go
@@ -18,7 +18,7 @@ type Transaction struct {
}
type Event struct {
- Content map[string]string `json:"content"`
+ Content map[string]interface{} `json:"content"`
Type string `json:"type"`
EventId string `json:"event_id"`
RoomId string `json:"room_id"`
@@ -47,6 +47,17 @@ type CreateRoomRequest struct {
Topic string `json:"topic"`
Invite []string `json:"invite"`
CreationContent map[string]interface{} `json:"creation_content"`
+ PowerLevels map[string]interface{} `json:"power_level_content_override"`
+}
+
+type CreateRoomNoAliasRequest struct {
+ Preset string `json:"preset"`
+ Name string `json:"name"`
+ Topic string `json:"topic"`
+ Invite []string `json:"invite"`
+ CreationContent map[string]interface{} `json:"creation_content"`
+ PowerLevels map[string]interface{} `json:"power_level_content_override"`
+ IsDirect bool `json:"is_direct"`
}
type CreateRoomResponse struct {
@@ -70,10 +81,11 @@ type RoomJoinResponse struct {
RoomId string `json:"room_id"`
}
-type RoomSendRequest struct {
+type RoomSendMessageRequest struct {
MsgType string `json:"msgtype"`
Body string `json:"body"`
}
type RoomSendResponse struct {
EventId string `json:"event_id"`
}
+