easybridge/appservice/matrix.go
2020-02-16 22:07:41 +01:00

193 lines
4.5 KiB
Go

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
}