aboutsummaryrefslogtreecommitdiff
path: root/appservice/matrix.go
diff options
context:
space:
mode:
Diffstat (limited to 'appservice/matrix.go')
-rw-r--r--appservice/matrix.go192
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
+}