diff options
Diffstat (limited to 'appservice/matrix.go')
-rw-r--r-- | appservice/matrix.go | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/appservice/matrix.go b/appservice/matrix.go new file mode 100644 index 0000000..96f643a --- /dev/null +++ b/appservice/matrix.go @@ -0,0 +1,192 @@ +package appservice + +import ( + "fmt" + "net/url" + "log" + "net/http" + "time" + "bytes" + "encoding/json" + + . "git.deuxfleurs.fr/Deuxfleurs/easybridge/mxlib" +) + +var httpClient *http.Client + +func init() { + tr := &http.Transport{ + MaxIdleConns: 10, + IdleConnTimeout: 30 * time.Second, + DisableCompression: true, + } + httpClient = &http.Client{Transport: tr} +} + +func mxGetApiCall(endpoint string, response interface{}) error { + log.Printf("Matrix GET request: %s\n", endpoint) + + req, err := http.NewRequest("GET", config.Server + endpoint, nil) + if err != nil { + return err + } + + return mxDoAndParse(req, response) +} + +func mxPutApiCall(endpoint string, data interface{}, response interface{}) error { + body, err := json.Marshal(data) + if err != nil { + return err + } + + log.Printf("Matrix PUT request: %s %s\n", endpoint, string(body)) + + req, err := http.NewRequest("PUT", config.Server + endpoint, bytes.NewBuffer(body)) + if err != nil { + return err + } + req.Header.Add("Content-Type", "application/json") + + return mxDoAndParse(req, response) +} + +func mxPostApiCall(endpoint string, data interface{}, response interface{}) error { + body, err := json.Marshal(data) + if err != nil { + return err + } + + log.Printf("Matrix POST request: %s %s\n", endpoint, string(body)) + + req, err := http.NewRequest("POST", config.Server + endpoint, bytes.NewBuffer(body)) + if err != nil { + return err + } + req.Header.Add("Content-Type", "application/json") + + return mxDoAndParse(req, response) +} + +func mxDoAndParse(req *http.Request, response interface{}) error { + req.Header.Add("Authorization", "Bearer " + registration.AsToken) + + resp, err := httpClient.Do(req) + if err != nil { + return err + } + + if resp.StatusCode != http.StatusOK { + var e MxError + err = json.NewDecoder(resp.Body).Decode(&e) + if err != nil { + return err + } + log.Printf("Response (%d): %#v\n", resp.StatusCode, e) + return &e + } + + err = json.NewDecoder(resp.Body).Decode(response) + if err != nil { + return err + } + + log.Printf("Response: %#v\n", response) + return nil +} + +// ---- + +func mxRegisterUser(username string) error { + req := RegisterRequest{ + Username: username, + } + var rep RegisterResponse + return mxPostApiCall("/_matrix/client/r0/register?kind=user", &req, &rep) +} + +func mxProfileDisplayname(userid string, displayname string) error { + req := ProfileDisplaynameRequest{ + Displayname: displayname, + } + var rep struct{} + err := mxPutApiCall(fmt.Sprintf("/_matrix/client/r0/profile/%s/displayname?user_id=%s", + url.QueryEscape(userid), url.QueryEscape(userid)), + &req, &rep) + return err +} + +func mxDirectoryRoom(alias string) (string, error) { + var rep DirectoryRoomResponse + err := mxGetApiCall("/_matrix/client/r0/directory/room/" + url.QueryEscape(alias), &rep) + if err != nil { + return "", err + } + return rep.RoomId, nil +} + +func mxCreateRoom(name string, alias string, invite []string) (string, error) { + rq := CreateRoomRequest{ + Preset: "private_chat", + RoomAliasName: alias, + Name: name, + Topic: "", + Invite: invite, + CreationContent: map[string]interface{} { + "m.federate": false, + }, + } + var rep CreateRoomResponse + err := mxPostApiCall("/_matrix/client/r0/createRoom", &rq, &rep) + if err != nil { + return "", err + } + return rep.RoomId, nil +} + +func mxRoomInvite(room string, user string) error { + rq := RoomInviteRequest{ + UserId: user, + } + var rep struct{} + err := mxPostApiCall("/_matrix/client/r0/rooms/" + url.QueryEscape(room) + "/invite", &rq, &rep) + return err +} + +func mxRoomKick(room string, user string, reason string) error { + rq := RoomKickRequest{ + UserId: user, + Reason: reason, + } + var rep struct{} + err := mxPostApiCall("/_matrix/client/r0/rooms/" + url.QueryEscape(room) + "/kick", &rq, &rep) + return err +} + +func mxRoomJoinAs(room string, user string) error { + rq := struct{}{} + var rep RoomJoinResponse + err := mxPostApiCall("/_matrix/client/r0/rooms/" + url.QueryEscape(room) + "/join?user_id=" + url.QueryEscape(user), &rq, &rep) + return err +} + +func mxRoomLeaveAs(room string, user string) error { + rq := struct{}{} + var rep struct{} + err := mxPostApiCall("/_matrix/client/r0/rooms/" + url.QueryEscape(room) + "/leave?user_id=" + url.QueryEscape(user), &rq, &rep) + return err +} + +func mxSendMessageAs(room string, body string, user string) error { + txn_id := time.Now().UnixNano() + rq := RoomSendRequest{ + MsgType: "m.text", + Body: body, + } + var rep RoomSendResponse + err := mxPutApiCall(fmt.Sprintf( + "/_matrix/client/r0/rooms/%s/send/m.room.message/%d?user_id=%s", + url.QueryEscape(room), txn_id, url.QueryEscape(user)), + &rq, &rep) + return err +} |