mirror of https://github.com/matrix-org/gomatrix
86 lines
3.3 KiB
Go
86 lines
3.3 KiB
Go
// Package gomatrix implements the Matrix Client-Server API.
|
|
//
|
|
// Specification can be found at http://matrix.org/docs/spec/client_server/r0.2.0.html
|
|
package gomatrix
|
|
|
|
import (
|
|
"net/http"
|
|
"net/url"
|
|
"path"
|
|
"sync"
|
|
)
|
|
|
|
// Client represents a Matrix client.
|
|
type Client struct {
|
|
HomeserverURL *url.URL // The base homeserver URL
|
|
Prefix string // The API prefix eg '/_matrix/client/r0'
|
|
UserID string // The user ID of the client. Used for forming HTTP paths which use the client's user ID.
|
|
AccessToken string // The access_token for the client.
|
|
syncingMutex sync.Mutex // protects syncingID
|
|
syncingID uint32 // Identifies the current Sync. Only one Sync can be active at any given time.
|
|
Client *http.Client // The underlying HTTP client which will be used to make HTTP requests.
|
|
FilterStorer FilterStorer // Interface for saving and loading the filter ID for sync.
|
|
NextBatchStorer NextBatchStorer // Interface for saving and loading the "next_batch" sync token.
|
|
// TODO: Worker and Rooms
|
|
}
|
|
|
|
// BuildURL builds a URL with the Client's homserver/prefix/access_token set already.
|
|
func (cli *Client) BuildURL(urlPath ...string) string {
|
|
ps := []string{cli.Prefix}
|
|
for _, p := range urlPath {
|
|
ps = append(ps, p)
|
|
}
|
|
return cli.BuildBaseURL(ps...)
|
|
}
|
|
|
|
// BuildBaseURL builds a URL with the Client's homeserver/access_token set already. You must
|
|
// supply the prefix in the path.
|
|
func (cli *Client) BuildBaseURL(urlPath ...string) string {
|
|
// copy the URL. Purposefully ignore error as the input is from a valid URL already
|
|
hsURL, _ := url.Parse(cli.HomeserverURL.String())
|
|
parts := []string{hsURL.Path}
|
|
parts = append(parts, urlPath...)
|
|
hsURL.Path = path.Join(parts...)
|
|
query := hsURL.Query()
|
|
query.Set("access_token", cli.AccessToken)
|
|
hsURL.RawQuery = query.Encode()
|
|
return hsURL.String()
|
|
}
|
|
|
|
// BuildURLWithQuery builds a URL with query paramters in addition to the Client's homeserver/prefix/access_token set already.
|
|
func (cli *Client) BuildURLWithQuery(urlPath []string, urlQuery map[string]string) string {
|
|
u, _ := url.Parse(cli.BuildURL(urlPath...))
|
|
q := u.Query()
|
|
for k, v := range urlQuery {
|
|
q.Set(k, v)
|
|
}
|
|
u.RawQuery = q.Encode()
|
|
return u.String()
|
|
}
|
|
|
|
// NewClient creates a new Matrix Client ready for syncing
|
|
func NewClient(homeserverURL, userID, accessToken string) (*Client, error) {
|
|
hsURL, err := url.Parse(homeserverURL)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
cli := Client{
|
|
AccessToken: accessToken,
|
|
HomeserverURL: hsURL,
|
|
UserID: userID,
|
|
Prefix: "/_matrix/client/r0",
|
|
}
|
|
// By default, use a no-op next_batch storer which will never save tokens and always
|
|
// "load" the empty string as a token. The client will work with this storer: it just won't
|
|
// remember the token across restarts. In practice, a database backend should be used.
|
|
cli.NextBatchStorer = NopNextBatchStore{}
|
|
// By default, use a no-op filter storer which will never save the filter ID and always
|
|
// "load" nothing. The client will work with this storer: it just won't remember the filter
|
|
// ID across restarts and hence request a new one. In practice, a database backend should be used.
|
|
cli.FilterStorer = NopFilterStore{}
|
|
// By default, use the default HTTP client.
|
|
cli.Client = http.DefaultClient
|
|
|
|
return &cli, nil
|
|
}
|