mirror of
				https://github.com/matrix-org/gomatrix
				synced 2025-11-04 06:18:05 +00:00 
			
		
		
		
	Merge branch 'master' into add-send-html
This commit is contained in:
		
						commit
						f1931f45c1
					
				
					 19 changed files with 681 additions and 131 deletions
				
			
		
							
								
								
									
										4
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -2,6 +2,7 @@
 | 
				
			||||||
*.o
 | 
					*.o
 | 
				
			||||||
*.a
 | 
					*.a
 | 
				
			||||||
*.so
 | 
					*.so
 | 
				
			||||||
 | 
					*.out
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Folders
 | 
					# Folders
 | 
				
			||||||
_obj
 | 
					_obj
 | 
				
			||||||
| 
						 | 
					@ -22,3 +23,6 @@ _testmain.go
 | 
				
			||||||
*.exe
 | 
					*.exe
 | 
				
			||||||
*.test
 | 
					*.test
 | 
				
			||||||
*.prof
 | 
					*.prof
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# test editor files
 | 
				
			||||||
 | 
					*.swp
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										21
									
								
								.golangci.yml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								.golangci.yml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,21 @@
 | 
				
			||||||
 | 
					run:
 | 
				
			||||||
 | 
					  timeout: 5m
 | 
				
			||||||
 | 
					  linters:
 | 
				
			||||||
 | 
					    enable:
 | 
				
			||||||
 | 
					      - vet
 | 
				
			||||||
 | 
					      - vetshadow
 | 
				
			||||||
 | 
					      - typecheck
 | 
				
			||||||
 | 
					      - deadcode
 | 
				
			||||||
 | 
					      - gocyclo
 | 
				
			||||||
 | 
					      - golint
 | 
				
			||||||
 | 
					      - varcheck
 | 
				
			||||||
 | 
					      - structcheck
 | 
				
			||||||
 | 
					      - maligned
 | 
				
			||||||
 | 
					      - ineffassign
 | 
				
			||||||
 | 
					      - misspell
 | 
				
			||||||
 | 
					      - unparam
 | 
				
			||||||
 | 
					      - goimports
 | 
				
			||||||
 | 
					      - goconst
 | 
				
			||||||
 | 
					      - unconvert
 | 
				
			||||||
 | 
					      - errcheck
 | 
				
			||||||
 | 
					      - interfacer
 | 
				
			||||||
| 
						 | 
					@ -1,9 +1,7 @@
 | 
				
			||||||
language: go
 | 
					language: go
 | 
				
			||||||
go:
 | 
					go:
 | 
				
			||||||
 - 1.10.x
 | 
					 - 1.13.10
 | 
				
			||||||
install:
 | 
					install:
 | 
				
			||||||
 - go get github.com/golang/lint/golint
 | 
					 - go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.24.0
 | 
				
			||||||
 - go get github.com/fzipp/gocyclo
 | 
					 - go build
 | 
				
			||||||
 - go get github.com/client9/misspell/...
 | 
					 | 
				
			||||||
 - go get github.com/gordonklaus/ineffassign
 | 
					 | 
				
			||||||
script: ./hooks/pre-commit
 | 
					script: ./hooks/pre-commit
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1
									
								
								CHANGELOG.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								CHANGELOG.md
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					## Release 0.1.0 (UNRELEASED)
 | 
				
			||||||
							
								
								
									
										65
									
								
								README.md
									
										
									
									
									
								
							
							
						
						
									
										65
									
								
								README.md
									
										
									
									
									
								
							| 
						 | 
					@ -4,3 +4,68 @@
 | 
				
			||||||
A Golang Matrix client.
 | 
					A Golang Matrix client.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**THIS IS UNDER ACTIVE DEVELOPMENT: BREAKING CHANGES ARE FREQUENT.**
 | 
					**THIS IS UNDER ACTIVE DEVELOPMENT: BREAKING CHANGES ARE FREQUENT.**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Contributing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					All contributions are greatly appreciated!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## How to report issues
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Please check the current open issues for similar reports
 | 
				
			||||||
 | 
					in order to avoid duplicates.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Some general guidelines:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-   Include a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) when possible.
 | 
				
			||||||
 | 
					-   Describe the expected behaviour and what actually happened
 | 
				
			||||||
 | 
					    including a full trace-back in case of exceptions.
 | 
				
			||||||
 | 
					-   Make sure to list details about your environment
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Setting up your environment
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you intend to contribute to gomatrix you'll first need Go installed on your machine (version 1.12+ is required). Also, make sure to have golangci-lint properly set up since we use it for pre-commit hooks (for instructions on how to install it, check the [official docs](https://golangci-lint.run/usage/install/#local-installation)).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-   Fork gomatrix to your GitHub account by clicking the [Fork](https://github.com/matrix-org/gomatrix/fork) button.
 | 
				
			||||||
 | 
					-   [Clone](https://help.github.com/en/articles/fork-a-repo#step-2-create-a-local-clone-of-your-fork) the main repository (not your fork) to your local machine.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        $ git clone https://github.com/matrix-org/gomatrix
 | 
				
			||||||
 | 
					        $ cd gomatrix
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-   Add your fork as a remote to push your contributions.Replace
 | 
				
			||||||
 | 
					    ``{username}`` with your username.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        git remote add fork https://github.com/{username}/gomatrix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-   Create a new branch to identify what feature you are working on.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $ git fetch origin
 | 
				
			||||||
 | 
					        $ git checkout -b your-branch-name origin/master
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-   Make your changes, including tests that cover any code changes you make, and run them as described below.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-   Execute pre-commit hooks by running 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <gomatrix dir>/hooks/pre-commit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-   Push your changes to your fork and [create a pull request](https://help.github.com/en/articles/creating-a-pull-request) describing your changes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $ git push --set-upstream fork your-branch-name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-   Finally, create a [pull request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## How to run tests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can run the test suite and example code with `$ go test -v`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Running Coverage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To run coverage, first generate the coverage report using `go test`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    go test -v -cover -coverprofile=coverage.out
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can now show the generated report as a html page with `go tool`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    go tool cover -html=coverage.out
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										248
									
								
								client.go
									
										
									
									
									
								
							
							
						
						
									
										248
									
								
								client.go
									
										
									
									
									
								
							| 
						 | 
					@ -13,6 +13,7 @@ import (
 | 
				
			||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
	"path"
 | 
						"path"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -38,6 +39,7 @@ type Client struct {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// HTTPError An HTTP Error response, which may wrap an underlying native Go Error.
 | 
					// HTTPError An HTTP Error response, which may wrap an underlying native Go Error.
 | 
				
			||||||
type HTTPError struct {
 | 
					type HTTPError struct {
 | 
				
			||||||
 | 
						Contents     []byte
 | 
				
			||||||
	WrappedError error
 | 
						WrappedError error
 | 
				
			||||||
	Message      string
 | 
						Message      string
 | 
				
			||||||
	Code         int
 | 
						Code         int
 | 
				
			||||||
| 
						 | 
					@ -48,19 +50,16 @@ func (e HTTPError) Error() string {
 | 
				
			||||||
	if e.WrappedError != nil {
 | 
						if e.WrappedError != nil {
 | 
				
			||||||
		wrappedErrMsg = e.WrappedError.Error()
 | 
							wrappedErrMsg = e.WrappedError.Error()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return fmt.Sprintf("msg=%s code=%d wrapped=%s", e.Message, e.Code, wrappedErrMsg)
 | 
						return fmt.Sprintf("contents=%v msg=%s code=%d wrapped=%s", e.Contents, e.Message, e.Code, wrappedErrMsg)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// BuildURL builds a URL with the Client's homserver/prefix/access_token set already.
 | 
					// BuildURL builds a URL with the Client's homeserver/prefix set already.
 | 
				
			||||||
func (cli *Client) BuildURL(urlPath ...string) string {
 | 
					func (cli *Client) BuildURL(urlPath ...string) string {
 | 
				
			||||||
	ps := []string{cli.Prefix}
 | 
						ps := append([]string{cli.Prefix}, urlPath...)
 | 
				
			||||||
	for _, p := range urlPath {
 | 
					 | 
				
			||||||
		ps = append(ps, p)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return cli.BuildBaseURL(ps...)
 | 
						return cli.BuildBaseURL(ps...)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// BuildBaseURL builds a URL with the Client's homeserver/access_token set already. You must
 | 
					// BuildBaseURL builds a URL with the Client's homeserver set already. You must
 | 
				
			||||||
// supply the prefix in the path.
 | 
					// supply the prefix in the path.
 | 
				
			||||||
func (cli *Client) BuildBaseURL(urlPath ...string) string {
 | 
					func (cli *Client) BuildBaseURL(urlPath ...string) string {
 | 
				
			||||||
	// copy the URL. Purposefully ignore error as the input is from a valid URL already
 | 
						// copy the URL. Purposefully ignore error as the input is from a valid URL already
 | 
				
			||||||
| 
						 | 
					@ -68,10 +67,11 @@ func (cli *Client) BuildBaseURL(urlPath ...string) string {
 | 
				
			||||||
	parts := []string{hsURL.Path}
 | 
						parts := []string{hsURL.Path}
 | 
				
			||||||
	parts = append(parts, urlPath...)
 | 
						parts = append(parts, urlPath...)
 | 
				
			||||||
	hsURL.Path = path.Join(parts...)
 | 
						hsURL.Path = path.Join(parts...)
 | 
				
			||||||
	query := hsURL.Query()
 | 
						// Manually add the trailing slash back to the end of the path if it's explicitly needed
 | 
				
			||||||
	if cli.AccessToken != "" {
 | 
						if strings.HasSuffix(urlPath[len(urlPath)-1], "/") {
 | 
				
			||||||
		query.Set("access_token", cli.AccessToken)
 | 
							hsURL.Path = hsURL.Path + "/"
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						query := hsURL.Query()
 | 
				
			||||||
	if cli.AppServiceUserID != "" {
 | 
						if cli.AppServiceUserID != "" {
 | 
				
			||||||
		query.Set("user_id", cli.AppServiceUserID)
 | 
							query.Set("user_id", cli.AppServiceUserID)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -79,7 +79,7 @@ func (cli *Client) BuildBaseURL(urlPath ...string) string {
 | 
				
			||||||
	return hsURL.String()
 | 
						return hsURL.String()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// BuildURLWithQuery builds a URL with query parameters in addition to the Client's homeserver/prefix/access_token set already.
 | 
					// BuildURLWithQuery builds a URL with query parameters in addition to the Client's homeserver/prefix set already.
 | 
				
			||||||
func (cli *Client) BuildURLWithQuery(urlPath []string, urlQuery map[string]string) string {
 | 
					func (cli *Client) BuildURLWithQuery(urlPath []string, urlQuery map[string]string) string {
 | 
				
			||||||
	u, _ := url.Parse(cli.BuildURL(urlPath...))
 | 
						u, _ := url.Parse(cli.BuildURL(urlPath...))
 | 
				
			||||||
	q := u.Query()
 | 
						q := u.Query()
 | 
				
			||||||
| 
						 | 
					@ -178,38 +178,48 @@ func (cli *Client) StopSync() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// MakeRequest makes a JSON HTTP request to the given URL.
 | 
					// MakeRequest makes a JSON HTTP request to the given URL.
 | 
				
			||||||
// If "resBody" is not nil, the response body will be json.Unmarshalled into it.
 | 
					// The response body will be stream decoded into an interface. This will automatically stop if the response
 | 
				
			||||||
 | 
					// body is nil.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Returns the HTTP body as bytes on 2xx with a nil error. Returns an error if the response is not 2xx along
 | 
					// Returns an error if the response is not 2xx along with the HTTP body bytes if it got that far. This error is
 | 
				
			||||||
// with the HTTP body bytes if it got that far. This error is an HTTPError which includes the returned
 | 
					// an HTTPError which includes the returned HTTP status code, byte contents of the response body and possibly a
 | 
				
			||||||
// HTTP status code and possibly a RespError as the WrappedError, if the HTTP body could be decoded as a RespError.
 | 
					// RespError as the WrappedError, if the HTTP body could be decoded as a RespError.
 | 
				
			||||||
func (cli *Client) MakeRequest(method string, httpURL string, reqBody interface{}, resBody interface{}) ([]byte, error) {
 | 
					func (cli *Client) MakeRequest(method string, httpURL string, reqBody interface{}, resBody interface{}) error {
 | 
				
			||||||
	var req *http.Request
 | 
						var req *http.Request
 | 
				
			||||||
	var err error
 | 
						var err error
 | 
				
			||||||
	if reqBody != nil {
 | 
						if reqBody != nil {
 | 
				
			||||||
		var jsonStr []byte
 | 
							buf := new(bytes.Buffer)
 | 
				
			||||||
		jsonStr, err = json.Marshal(reqBody)
 | 
							if err := json.NewEncoder(buf).Encode(reqBody); err != nil {
 | 
				
			||||||
		if err != nil {
 | 
								return err
 | 
				
			||||||
			return nil, err
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		req, err = http.NewRequest(method, httpURL, bytes.NewBuffer(jsonStr))
 | 
							req, err = http.NewRequest(method, httpURL, buf)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		req, err = http.NewRequest(method, httpURL, nil)
 | 
							req, err = http.NewRequest(method, httpURL, nil)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	req.Header.Set("Content-Type", "application/json")
 | 
						req.Header.Set("Content-Type", "application/json")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if cli.AccessToken != "" {
 | 
				
			||||||
 | 
							req.Header.Set("Authorization", "Bearer "+cli.AccessToken)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	res, err := cli.Client.Do(req)
 | 
						res, err := cli.Client.Do(req)
 | 
				
			||||||
	if res != nil {
 | 
						if res != nil {
 | 
				
			||||||
		defer res.Body.Close()
 | 
							defer res.Body.Close()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	contents, err := ioutil.ReadAll(res.Body)
 | 
					 | 
				
			||||||
	if res.StatusCode/100 != 2 { // not 2xx
 | 
						if res.StatusCode/100 != 2 { // not 2xx
 | 
				
			||||||
 | 
							contents, err := ioutil.ReadAll(res.Body)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		var wrap error
 | 
							var wrap error
 | 
				
			||||||
		var respErr RespError
 | 
							var respErr RespError
 | 
				
			||||||
		if _ = json.Unmarshal(contents, &respErr); respErr.ErrCode != "" {
 | 
							if _ = json.Unmarshal(contents, &respErr); respErr.ErrCode != "" {
 | 
				
			||||||
| 
						 | 
					@ -223,29 +233,25 @@ func (cli *Client) MakeRequest(method string, httpURL string, reqBody interface{
 | 
				
			||||||
			msg = msg + ": " + string(contents)
 | 
								msg = msg + ": " + string(contents)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return contents, HTTPError{
 | 
							return HTTPError{
 | 
				
			||||||
 | 
								Contents:     contents,
 | 
				
			||||||
			Code:         res.StatusCode,
 | 
								Code:         res.StatusCode,
 | 
				
			||||||
			Message:      msg,
 | 
								Message:      msg,
 | 
				
			||||||
			WrappedError: wrap,
 | 
								WrappedError: wrap,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err != nil {
 | 
					
 | 
				
			||||||
		return nil, err
 | 
						if resBody != nil && res.Body != nil {
 | 
				
			||||||
 | 
							return json.NewDecoder(res.Body).Decode(&resBody)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if resBody != nil {
 | 
						return nil
 | 
				
			||||||
		if err = json.Unmarshal(contents, &resBody); err != nil {
 | 
					 | 
				
			||||||
			return nil, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return contents, nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CreateFilter makes an HTTP request according to http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-user-userid-filter
 | 
					// CreateFilter makes an HTTP request according to http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-user-userid-filter
 | 
				
			||||||
func (cli *Client) CreateFilter(filter json.RawMessage) (resp *RespCreateFilter, err error) {
 | 
					func (cli *Client) CreateFilter(filter json.RawMessage) (resp *RespCreateFilter, err error) {
 | 
				
			||||||
	urlPath := cli.BuildURL("user", cli.UserID, "filter")
 | 
						urlPath := cli.BuildURL("user", cli.UserID, "filter")
 | 
				
			||||||
	_, err = cli.MakeRequest("POST", urlPath, &filter, &resp)
 | 
						err = cli.MakeRequest("POST", urlPath, &filter, &resp)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -267,13 +273,12 @@ func (cli *Client) SyncRequest(timeout int, since, filterID string, fullState bo
 | 
				
			||||||
		query["full_state"] = "true"
 | 
							query["full_state"] = "true"
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	urlPath := cli.BuildURLWithQuery([]string{"sync"}, query)
 | 
						urlPath := cli.BuildURLWithQuery([]string{"sync"}, query)
 | 
				
			||||||
	_, err = cli.MakeRequest("GET", urlPath, nil, &resp)
 | 
						err = cli.MakeRequest("GET", urlPath, nil, &resp)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (cli *Client) register(u string, req *ReqRegister) (resp *RespRegister, uiaResp *RespUserInteractive, err error) {
 | 
					func (cli *Client) register(u string, req *ReqRegister) (resp *RespRegister, uiaResp *RespUserInteractive, err error) {
 | 
				
			||||||
	var bodyBytes []byte
 | 
						err = cli.MakeRequest("POST", u, req, &resp)
 | 
				
			||||||
	bodyBytes, err = cli.MakeRequest("POST", u, req, nil)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		httpErr, ok := err.(HTTPError)
 | 
							httpErr, ok := err.(HTTPError)
 | 
				
			||||||
		if !ok { // network error
 | 
							if !ok { // network error
 | 
				
			||||||
| 
						 | 
					@ -281,13 +286,10 @@ func (cli *Client) register(u string, req *ReqRegister) (resp *RespRegister, uia
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if httpErr.Code == 401 {
 | 
							if httpErr.Code == 401 {
 | 
				
			||||||
			// body should be RespUserInteractive, if it isn't, fail with the error
 | 
								// body should be RespUserInteractive, if it isn't, fail with the error
 | 
				
			||||||
			err = json.Unmarshal(bodyBytes, &uiaResp)
 | 
								err = json.Unmarshal(httpErr.Contents, &uiaResp)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// body should be RespRegister
 | 
					 | 
				
			||||||
	err = json.Unmarshal(bodyBytes, &resp)
 | 
					 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -351,22 +353,77 @@ func (cli *Client) RegisterDummy(req *ReqRegister) (*RespRegister, error) {
 | 
				
			||||||
// This does not set credentials on this client instance. See SetCredentials() instead.
 | 
					// This does not set credentials on this client instance. See SetCredentials() instead.
 | 
				
			||||||
func (cli *Client) Login(req *ReqLogin) (resp *RespLogin, err error) {
 | 
					func (cli *Client) Login(req *ReqLogin) (resp *RespLogin, err error) {
 | 
				
			||||||
	urlPath := cli.BuildURL("login")
 | 
						urlPath := cli.BuildURL("login")
 | 
				
			||||||
	_, err = cli.MakeRequest("POST", urlPath, req, &resp)
 | 
						err = cli.MakeRequest("POST", urlPath, req, &resp)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Logout the current user. See http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-logout
 | 
					// Logout the current user. See http://matrix.org/docs/spec/client_server/r0.6.0.html#post-matrix-client-r0-logout
 | 
				
			||||||
// This does not clear the credentials from the client instance. See ClearCredentials() instead.
 | 
					// This does not clear the credentials from the client instance. See ClearCredentials() instead.
 | 
				
			||||||
func (cli *Client) Logout() (resp *RespLogout, err error) {
 | 
					func (cli *Client) Logout() (resp *RespLogout, err error) {
 | 
				
			||||||
	urlPath := cli.BuildURL("logout")
 | 
						urlPath := cli.BuildURL("logout")
 | 
				
			||||||
	_, err = cli.MakeRequest("POST", urlPath, nil, &resp)
 | 
						err = cli.MakeRequest("POST", urlPath, nil, &resp)
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// LogoutAll logs the current user out on all devices. See https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-logout-all
 | 
				
			||||||
 | 
					// This does not clear the credentials from the client instance. See ClearCredentails() instead.
 | 
				
			||||||
 | 
					func (cli *Client) LogoutAll() (resp *RespLogoutAll, err error) {
 | 
				
			||||||
 | 
						urlPath := cli.BuildURL("logout/all")
 | 
				
			||||||
 | 
						err = cli.MakeRequest("POST", urlPath, nil, &resp)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Versions returns the list of supported Matrix versions on this homeserver. See http://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-versions
 | 
					// Versions returns the list of supported Matrix versions on this homeserver. See http://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-versions
 | 
				
			||||||
func (cli *Client) Versions() (resp *RespVersions, err error) {
 | 
					func (cli *Client) Versions() (resp *RespVersions, err error) {
 | 
				
			||||||
	urlPath := cli.BuildBaseURL("_matrix", "client", "versions")
 | 
						urlPath := cli.BuildBaseURL("_matrix", "client", "versions")
 | 
				
			||||||
	_, err = cli.MakeRequest("GET", urlPath, nil, &resp)
 | 
						err = cli.MakeRequest("GET", urlPath, nil, &resp)
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PublicRooms returns the list of public rooms on target server. See https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-unstable-publicrooms
 | 
				
			||||||
 | 
					func (cli *Client) PublicRooms(limit int, since string, server string) (resp *RespPublicRooms, err error) {
 | 
				
			||||||
 | 
						args := map[string]string{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if limit != 0 {
 | 
				
			||||||
 | 
							args["limit"] = strconv.Itoa(limit)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if since != "" {
 | 
				
			||||||
 | 
							args["since"] = since
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if server != "" {
 | 
				
			||||||
 | 
							args["server"] = server
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						urlPath := cli.BuildURLWithQuery([]string{"publicRooms"}, args)
 | 
				
			||||||
 | 
						err = cli.MakeRequest("GET", urlPath, nil, &resp)
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PublicRoomsFiltered returns a subset of PublicRooms filtered server side.
 | 
				
			||||||
 | 
					// See https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-unstable-publicrooms
 | 
				
			||||||
 | 
					func (cli *Client) PublicRoomsFiltered(limit int, since string, server string, filter string) (resp *RespPublicRooms, err error) {
 | 
				
			||||||
 | 
						content := map[string]string{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if limit != 0 {
 | 
				
			||||||
 | 
							content["limit"] = strconv.Itoa(limit)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if since != "" {
 | 
				
			||||||
 | 
							content["since"] = since
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if filter != "" {
 | 
				
			||||||
 | 
							content["filter"] = filter
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var urlPath string
 | 
				
			||||||
 | 
						if server == "" {
 | 
				
			||||||
 | 
							urlPath = cli.BuildURL("publicRooms")
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							urlPath = cli.BuildURLWithQuery([]string{"publicRooms"}, map[string]string{
 | 
				
			||||||
 | 
								"server": server,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = cli.MakeRequest("POST", urlPath, content, &resp)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -383,21 +440,21 @@ func (cli *Client) JoinRoom(roomIDorAlias, serverName string, content interface{
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		urlPath = cli.BuildURL("join", roomIDorAlias)
 | 
							urlPath = cli.BuildURL("join", roomIDorAlias)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	_, err = cli.MakeRequest("POST", urlPath, content, &resp)
 | 
						err = cli.MakeRequest("POST", urlPath, content, &resp)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetDisplayName returns the display name of the user from the specified MXID. See https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-profile-userid-displayname
 | 
					// GetDisplayName returns the display name of the user from the specified MXID. See https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-profile-userid-displayname
 | 
				
			||||||
func (cli *Client) GetDisplayName(mxid string) (resp *RespUserDisplayName, err error) {
 | 
					func (cli *Client) GetDisplayName(mxid string) (resp *RespUserDisplayName, err error) {
 | 
				
			||||||
	urlPath := cli.BuildURL("profile", mxid, "displayname")
 | 
						urlPath := cli.BuildURL("profile", mxid, "displayname")
 | 
				
			||||||
	_, err = cli.MakeRequest("GET", urlPath, nil, &resp)
 | 
						err = cli.MakeRequest("GET", urlPath, nil, &resp)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetOwnDisplayName returns the user's display name. See https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-profile-userid-displayname
 | 
					// GetOwnDisplayName returns the user's display name. See https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-profile-userid-displayname
 | 
				
			||||||
func (cli *Client) GetOwnDisplayName() (resp *RespUserDisplayName, err error) {
 | 
					func (cli *Client) GetOwnDisplayName() (resp *RespUserDisplayName, err error) {
 | 
				
			||||||
	urlPath := cli.BuildURL("profile", cli.UserID, "displayname")
 | 
						urlPath := cli.BuildURL("profile", cli.UserID, "displayname")
 | 
				
			||||||
	_, err = cli.MakeRequest("GET", urlPath, nil, &resp)
 | 
						err = cli.MakeRequest("GET", urlPath, nil, &resp)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -407,18 +464,18 @@ func (cli *Client) SetDisplayName(displayName string) (err error) {
 | 
				
			||||||
	s := struct {
 | 
						s := struct {
 | 
				
			||||||
		DisplayName string `json:"displayname"`
 | 
							DisplayName string `json:"displayname"`
 | 
				
			||||||
	}{displayName}
 | 
						}{displayName}
 | 
				
			||||||
	_, err = cli.MakeRequest("PUT", urlPath, &s, nil)
 | 
						err = cli.MakeRequest("PUT", urlPath, &s, nil)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetAvatarURL gets the user's avatar URL. See http://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-profile-userid-avatar-url
 | 
					// GetAvatarURL gets the user's avatar URL. See http://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-profile-userid-avatar-url
 | 
				
			||||||
func (cli *Client) GetAvatarURL() (url string, err error) {
 | 
					func (cli *Client) GetAvatarURL() (string, error) {
 | 
				
			||||||
	urlPath := cli.BuildURL("profile", cli.UserID, "avatar_url")
 | 
						urlPath := cli.BuildURL("profile", cli.UserID, "avatar_url")
 | 
				
			||||||
	s := struct {
 | 
						s := struct {
 | 
				
			||||||
		AvatarURL string `json:"avatar_url"`
 | 
							AvatarURL string `json:"avatar_url"`
 | 
				
			||||||
	}{}
 | 
						}{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err = cli.MakeRequest("GET", urlPath, nil, &s)
 | 
						err := cli.MakeRequest("GET", urlPath, nil, &s)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return "", err
 | 
							return "", err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -427,12 +484,12 @@ func (cli *Client) GetAvatarURL() (url string, err error) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SetAvatarURL sets the user's avatar URL. See http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-profile-userid-avatar-url
 | 
					// SetAvatarURL sets the user's avatar URL. See http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-profile-userid-avatar-url
 | 
				
			||||||
func (cli *Client) SetAvatarURL(url string) (err error) {
 | 
					func (cli *Client) SetAvatarURL(url string) error {
 | 
				
			||||||
	urlPath := cli.BuildURL("profile", cli.UserID, "avatar_url")
 | 
						urlPath := cli.BuildURL("profile", cli.UserID, "avatar_url")
 | 
				
			||||||
	s := struct {
 | 
						s := struct {
 | 
				
			||||||
		AvatarURL string `json:"avatar_url"`
 | 
							AvatarURL string `json:"avatar_url"`
 | 
				
			||||||
	}{url}
 | 
						}{url}
 | 
				
			||||||
	_, err = cli.MakeRequest("PUT", urlPath, &s, nil)
 | 
						err := cli.MakeRequest("PUT", urlPath, &s, nil)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -440,12 +497,35 @@ func (cli *Client) SetAvatarURL(url string) (err error) {
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetStatus returns the status of the user from the specified MXID. See https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-presence-userid-status
 | 
				
			||||||
 | 
					func (cli *Client) GetStatus(mxid string) (resp *RespUserStatus, err error) {
 | 
				
			||||||
 | 
						urlPath := cli.BuildURL("presence", mxid, "status")
 | 
				
			||||||
 | 
						err = cli.MakeRequest("GET", urlPath, nil, &resp)
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetOwnStatus returns the user's status. See https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-presence-userid-status
 | 
				
			||||||
 | 
					func (cli *Client) GetOwnStatus() (resp *RespUserStatus, err error) {
 | 
				
			||||||
 | 
						return cli.GetStatus(cli.UserID)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SetStatus sets the user's status. See https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-presence-userid-status
 | 
				
			||||||
 | 
					func (cli *Client) SetStatus(presence, status string) (err error) {
 | 
				
			||||||
 | 
						urlPath := cli.BuildURL("presence", cli.UserID, "status")
 | 
				
			||||||
 | 
						s := struct {
 | 
				
			||||||
 | 
							Presence  string `json:"presence"`
 | 
				
			||||||
 | 
							StatusMsg string `json:"status_msg"`
 | 
				
			||||||
 | 
						}{presence, status}
 | 
				
			||||||
 | 
						err = cli.MakeRequest("PUT", urlPath, &s, nil)
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SendMessageEvent sends a message event into a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-send-eventtype-txnid
 | 
					// SendMessageEvent sends a message event into a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-send-eventtype-txnid
 | 
				
			||||||
// contentJSON should be a pointer to something that can be encoded as JSON using json.Marshal.
 | 
					// contentJSON should be a pointer to something that can be encoded as JSON using json.Marshal.
 | 
				
			||||||
func (cli *Client) SendMessageEvent(roomID string, eventType string, contentJSON interface{}) (resp *RespSendEvent, err error) {
 | 
					func (cli *Client) SendMessageEvent(roomID string, eventType string, contentJSON interface{}) (resp *RespSendEvent, err error) {
 | 
				
			||||||
	txnID := txnID()
 | 
						txnID := txnID()
 | 
				
			||||||
	urlPath := cli.BuildURL("rooms", roomID, "send", eventType, txnID)
 | 
						urlPath := cli.BuildURL("rooms", roomID, "send", eventType, txnID)
 | 
				
			||||||
	_, err = cli.MakeRequest("PUT", urlPath, contentJSON, &resp)
 | 
						err = cli.MakeRequest("PUT", urlPath, contentJSON, &resp)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -453,7 +533,7 @@ func (cli *Client) SendMessageEvent(roomID string, eventType string, contentJSON
 | 
				
			||||||
// contentJSON should be a pointer to something that can be encoded as JSON using json.Marshal.
 | 
					// contentJSON should be a pointer to something that can be encoded as JSON using json.Marshal.
 | 
				
			||||||
func (cli *Client) SendStateEvent(roomID, eventType, stateKey string, contentJSON interface{}) (resp *RespSendEvent, err error) {
 | 
					func (cli *Client) SendStateEvent(roomID, eventType, stateKey string, contentJSON interface{}) (resp *RespSendEvent, err error) {
 | 
				
			||||||
	urlPath := cli.BuildURL("rooms", roomID, "state", eventType, stateKey)
 | 
						urlPath := cli.BuildURL("rooms", roomID, "state", eventType, stateKey)
 | 
				
			||||||
	_, err = cli.MakeRequest("PUT", urlPath, contentJSON, &resp)
 | 
						err = cli.MakeRequest("PUT", urlPath, contentJSON, &resp)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -461,7 +541,14 @@ func (cli *Client) SendStateEvent(roomID, eventType, stateKey string, contentJSO
 | 
				
			||||||
// See http://matrix.org/docs/spec/client_server/r0.2.0.html#m-text
 | 
					// See http://matrix.org/docs/spec/client_server/r0.2.0.html#m-text
 | 
				
			||||||
func (cli *Client) SendText(roomID, text string) (*RespSendEvent, error) {
 | 
					func (cli *Client) SendText(roomID, text string) (*RespSendEvent, error) {
 | 
				
			||||||
	return cli.SendMessageEvent(roomID, "m.room.message",
 | 
						return cli.SendMessageEvent(roomID, "m.room.message",
 | 
				
			||||||
		TextMessage{"m.text", text})
 | 
							TextMessage{MsgType: "m.text", Body: text})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SendFormattedText sends an m.room.message event into the given room with a msgtype of m.text, supports a subset of HTML for formatting.
 | 
				
			||||||
 | 
					// See https://matrix.org/docs/spec/client_server/r0.6.0#m-text
 | 
				
			||||||
 | 
					func (cli *Client) SendFormattedText(roomID, text, formattedText string) (*RespSendEvent, error) {
 | 
				
			||||||
 | 
						return cli.SendMessageEvent(roomID, "m.room.message",
 | 
				
			||||||
 | 
							TextMessage{MsgType: "m.text", Body: text, FormattedBody: formattedText, Format: "org.matrix.custom.html"})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SendHTML sends an m.room.message event into the given room with a msgtype of m.text and using the org.matrix.custom.html formatting.
 | 
					// SendHTML sends an m.room.message event into the given room with a msgtype of m.text and using the org.matrix.custom.html formatting.
 | 
				
			||||||
| 
						 | 
					@ -500,17 +587,23 @@ func (cli *Client) SendVideo(roomID, body, url string) (*RespSendEvent, error) {
 | 
				
			||||||
// See http://matrix.org/docs/spec/client_server/r0.2.0.html#m-notice
 | 
					// See http://matrix.org/docs/spec/client_server/r0.2.0.html#m-notice
 | 
				
			||||||
func (cli *Client) SendNotice(roomID, text string) (*RespSendEvent, error) {
 | 
					func (cli *Client) SendNotice(roomID, text string) (*RespSendEvent, error) {
 | 
				
			||||||
	return cli.SendMessageEvent(roomID, "m.room.message",
 | 
						return cli.SendMessageEvent(roomID, "m.room.message",
 | 
				
			||||||
		TextMessage{"m.notice", text})
 | 
							TextMessage{MsgType: "m.notice", Body: text})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RedactEvent redacts the given event. See http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-redact-eventid-txnid
 | 
					// RedactEvent redacts the given event. See http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-redact-eventid-txnid
 | 
				
			||||||
func (cli *Client) RedactEvent(roomID, eventID string, req *ReqRedact) (resp *RespSendEvent, err error) {
 | 
					func (cli *Client) RedactEvent(roomID, eventID string, req *ReqRedact) (resp *RespSendEvent, err error) {
 | 
				
			||||||
	txnID := txnID()
 | 
						txnID := txnID()
 | 
				
			||||||
	urlPath := cli.BuildURL("rooms", roomID, "redact", eventID, txnID)
 | 
						urlPath := cli.BuildURL("rooms", roomID, "redact", eventID, txnID)
 | 
				
			||||||
	_, err = cli.MakeRequest("PUT", urlPath, req, &resp)
 | 
						err = cli.MakeRequest("PUT", urlPath, req, &resp)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// MarkRead marks eventID in roomID as read, signifying the event, and all before it have been read. See https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-rooms-roomid-receipt-receipttype-eventid
 | 
				
			||||||
 | 
					func (cli *Client) MarkRead(roomID, eventID string) error {
 | 
				
			||||||
 | 
						urlPath := cli.BuildURL("rooms", roomID, "receipt", "m.read", eventID)
 | 
				
			||||||
 | 
						return cli.MakeRequest("POST", urlPath, nil, nil)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CreateRoom creates a new Matrix room. See https://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-createroom
 | 
					// CreateRoom creates a new Matrix room. See https://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-createroom
 | 
				
			||||||
//  resp, err := cli.CreateRoom(&gomatrix.ReqCreateRoom{
 | 
					//  resp, err := cli.CreateRoom(&gomatrix.ReqCreateRoom{
 | 
				
			||||||
//  	Preset: "public_chat",
 | 
					//  	Preset: "public_chat",
 | 
				
			||||||
| 
						 | 
					@ -518,56 +611,56 @@ func (cli *Client) RedactEvent(roomID, eventID string, req *ReqRedact) (resp *Re
 | 
				
			||||||
//  fmt.Println("Room:", resp.RoomID)
 | 
					//  fmt.Println("Room:", resp.RoomID)
 | 
				
			||||||
func (cli *Client) CreateRoom(req *ReqCreateRoom) (resp *RespCreateRoom, err error) {
 | 
					func (cli *Client) CreateRoom(req *ReqCreateRoom) (resp *RespCreateRoom, err error) {
 | 
				
			||||||
	urlPath := cli.BuildURL("createRoom")
 | 
						urlPath := cli.BuildURL("createRoom")
 | 
				
			||||||
	_, err = cli.MakeRequest("POST", urlPath, req, &resp)
 | 
						err = cli.MakeRequest("POST", urlPath, req, &resp)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// LeaveRoom leaves the given room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-rooms-roomid-leave
 | 
					// LeaveRoom leaves the given room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-rooms-roomid-leave
 | 
				
			||||||
func (cli *Client) LeaveRoom(roomID string) (resp *RespLeaveRoom, err error) {
 | 
					func (cli *Client) LeaveRoom(roomID string) (resp *RespLeaveRoom, err error) {
 | 
				
			||||||
	u := cli.BuildURL("rooms", roomID, "leave")
 | 
						u := cli.BuildURL("rooms", roomID, "leave")
 | 
				
			||||||
	_, err = cli.MakeRequest("POST", u, struct{}{}, &resp)
 | 
						err = cli.MakeRequest("POST", u, struct{}{}, &resp)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ForgetRoom forgets a room entirely. See http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-rooms-roomid-forget
 | 
					// ForgetRoom forgets a room entirely. See http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-rooms-roomid-forget
 | 
				
			||||||
func (cli *Client) ForgetRoom(roomID string) (resp *RespForgetRoom, err error) {
 | 
					func (cli *Client) ForgetRoom(roomID string) (resp *RespForgetRoom, err error) {
 | 
				
			||||||
	u := cli.BuildURL("rooms", roomID, "forget")
 | 
						u := cli.BuildURL("rooms", roomID, "forget")
 | 
				
			||||||
	_, err = cli.MakeRequest("POST", u, struct{}{}, &resp)
 | 
						err = cli.MakeRequest("POST", u, struct{}{}, &resp)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// InviteUser invites a user to a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-rooms-roomid-invite
 | 
					// InviteUser invites a user to a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-rooms-roomid-invite
 | 
				
			||||||
func (cli *Client) InviteUser(roomID string, req *ReqInviteUser) (resp *RespInviteUser, err error) {
 | 
					func (cli *Client) InviteUser(roomID string, req *ReqInviteUser) (resp *RespInviteUser, err error) {
 | 
				
			||||||
	u := cli.BuildURL("rooms", roomID, "invite")
 | 
						u := cli.BuildURL("rooms", roomID, "invite")
 | 
				
			||||||
	_, err = cli.MakeRequest("POST", u, req, &resp)
 | 
						err = cli.MakeRequest("POST", u, req, &resp)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// InviteUserByThirdParty invites a third-party identifier to a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#invite-by-third-party-id-endpoint
 | 
					// InviteUserByThirdParty invites a third-party identifier to a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#invite-by-third-party-id-endpoint
 | 
				
			||||||
func (cli *Client) InviteUserByThirdParty(roomID string, req *ReqInvite3PID) (resp *RespInviteUser, err error) {
 | 
					func (cli *Client) InviteUserByThirdParty(roomID string, req *ReqInvite3PID) (resp *RespInviteUser, err error) {
 | 
				
			||||||
	u := cli.BuildURL("rooms", roomID, "invite")
 | 
						u := cli.BuildURL("rooms", roomID, "invite")
 | 
				
			||||||
	_, err = cli.MakeRequest("POST", u, req, &resp)
 | 
						err = cli.MakeRequest("POST", u, req, &resp)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// KickUser kicks a user from a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-rooms-roomid-kick
 | 
					// KickUser kicks a user from a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-rooms-roomid-kick
 | 
				
			||||||
func (cli *Client) KickUser(roomID string, req *ReqKickUser) (resp *RespKickUser, err error) {
 | 
					func (cli *Client) KickUser(roomID string, req *ReqKickUser) (resp *RespKickUser, err error) {
 | 
				
			||||||
	u := cli.BuildURL("rooms", roomID, "kick")
 | 
						u := cli.BuildURL("rooms", roomID, "kick")
 | 
				
			||||||
	_, err = cli.MakeRequest("POST", u, req, &resp)
 | 
						err = cli.MakeRequest("POST", u, req, &resp)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// BanUser bans a user from a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-rooms-roomid-ban
 | 
					// BanUser bans a user from a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-rooms-roomid-ban
 | 
				
			||||||
func (cli *Client) BanUser(roomID string, req *ReqBanUser) (resp *RespBanUser, err error) {
 | 
					func (cli *Client) BanUser(roomID string, req *ReqBanUser) (resp *RespBanUser, err error) {
 | 
				
			||||||
	u := cli.BuildURL("rooms", roomID, "ban")
 | 
						u := cli.BuildURL("rooms", roomID, "ban")
 | 
				
			||||||
	_, err = cli.MakeRequest("POST", u, req, &resp)
 | 
						err = cli.MakeRequest("POST", u, req, &resp)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// UnbanUser unbans a user from a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-rooms-roomid-unban
 | 
					// UnbanUser unbans a user from a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-rooms-roomid-unban
 | 
				
			||||||
func (cli *Client) UnbanUser(roomID string, req *ReqUnbanUser) (resp *RespUnbanUser, err error) {
 | 
					func (cli *Client) UnbanUser(roomID string, req *ReqUnbanUser) (resp *RespUnbanUser, err error) {
 | 
				
			||||||
	u := cli.BuildURL("rooms", roomID, "unban")
 | 
						u := cli.BuildURL("rooms", roomID, "unban")
 | 
				
			||||||
	_, err = cli.MakeRequest("POST", u, req, &resp)
 | 
						err = cli.MakeRequest("POST", u, req, &resp)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -575,7 +668,7 @@ func (cli *Client) UnbanUser(roomID string, req *ReqUnbanUser) (resp *RespUnbanU
 | 
				
			||||||
func (cli *Client) UserTyping(roomID string, typing bool, timeout int64) (resp *RespTyping, err error) {
 | 
					func (cli *Client) UserTyping(roomID string, typing bool, timeout int64) (resp *RespTyping, err error) {
 | 
				
			||||||
	req := ReqTyping{Typing: typing, Timeout: timeout}
 | 
						req := ReqTyping{Typing: typing, Timeout: timeout}
 | 
				
			||||||
	u := cli.BuildURL("rooms", roomID, "typing", cli.UserID)
 | 
						u := cli.BuildURL("rooms", roomID, "typing", cli.UserID)
 | 
				
			||||||
	_, err = cli.MakeRequest("PUT", u, req, &resp)
 | 
						err = cli.MakeRequest("PUT", u, req, &resp)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -584,7 +677,7 @@ func (cli *Client) UserTyping(roomID string, typing bool, timeout int64) (resp *
 | 
				
			||||||
// See http://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-rooms-roomid-state-eventtype-statekey
 | 
					// See http://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-rooms-roomid-state-eventtype-statekey
 | 
				
			||||||
func (cli *Client) StateEvent(roomID, eventType, stateKey string, outContent interface{}) (err error) {
 | 
					func (cli *Client) StateEvent(roomID, eventType, stateKey string, outContent interface{}) (err error) {
 | 
				
			||||||
	u := cli.BuildURL("rooms", roomID, "state", eventType, stateKey)
 | 
						u := cli.BuildURL("rooms", roomID, "state", eventType, stateKey)
 | 
				
			||||||
	_, err = cli.MakeRequest("GET", u, nil, outContent)
 | 
						err = cli.MakeRequest("GET", u, nil, outContent)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -607,15 +700,21 @@ func (cli *Client) UploadToContentRepo(content io.Reader, contentType string, co
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	req.Header.Set("Content-Type", contentType)
 | 
						req.Header.Set("Content-Type", contentType)
 | 
				
			||||||
 | 
						req.Header.Set("Authorization", "Bearer "+cli.AccessToken)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	req.ContentLength = contentLength
 | 
						req.ContentLength = contentLength
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	res, err := cli.Client.Do(req)
 | 
						res, err := cli.Client.Do(req)
 | 
				
			||||||
	if res != nil {
 | 
						if res != nil {
 | 
				
			||||||
		defer res.Body.Close()
 | 
							defer res.Body.Close()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if res.StatusCode != 200 {
 | 
						if res.StatusCode != 200 {
 | 
				
			||||||
		contents, err := ioutil.ReadAll(res.Body)
 | 
							contents, err := ioutil.ReadAll(res.Body)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
| 
						 | 
					@ -625,14 +724,17 @@ func (cli *Client) UploadToContentRepo(content io.Reader, contentType string, co
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return nil, HTTPError{
 | 
							return nil, HTTPError{
 | 
				
			||||||
 | 
								Contents: contents,
 | 
				
			||||||
			Message:  "Upload request failed: " + string(contents),
 | 
								Message:  "Upload request failed: " + string(contents),
 | 
				
			||||||
			Code:     res.StatusCode,
 | 
								Code:     res.StatusCode,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var m RespMediaUpload
 | 
						var m RespMediaUpload
 | 
				
			||||||
	if err := json.NewDecoder(res.Body).Decode(&m); err != nil {
 | 
						if err := json.NewDecoder(res.Body).Decode(&m); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return &m, nil
 | 
						return &m, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -642,7 +744,7 @@ func (cli *Client) UploadToContentRepo(content io.Reader, contentType string, co
 | 
				
			||||||
// This API is primarily designed for application services which may want to efficiently look up joined members in a room.
 | 
					// This API is primarily designed for application services which may want to efficiently look up joined members in a room.
 | 
				
			||||||
func (cli *Client) JoinedMembers(roomID string) (resp *RespJoinedMembers, err error) {
 | 
					func (cli *Client) JoinedMembers(roomID string) (resp *RespJoinedMembers, err error) {
 | 
				
			||||||
	u := cli.BuildURL("rooms", roomID, "joined_members")
 | 
						u := cli.BuildURL("rooms", roomID, "joined_members")
 | 
				
			||||||
	_, err = cli.MakeRequest("GET", u, nil, &resp)
 | 
						err = cli.MakeRequest("GET", u, nil, &resp)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -652,7 +754,7 @@ func (cli *Client) JoinedMembers(roomID string) (resp *RespJoinedMembers, err er
 | 
				
			||||||
// This API is primarily designed for application services which may want to efficiently look up joined rooms.
 | 
					// This API is primarily designed for application services which may want to efficiently look up joined rooms.
 | 
				
			||||||
func (cli *Client) JoinedRooms() (resp *RespJoinedRooms, err error) {
 | 
					func (cli *Client) JoinedRooms() (resp *RespJoinedRooms, err error) {
 | 
				
			||||||
	u := cli.BuildURL("joined_rooms")
 | 
						u := cli.BuildURL("joined_rooms")
 | 
				
			||||||
	_, err = cli.MakeRequest("GET", u, nil, &resp)
 | 
						err = cli.MakeRequest("GET", u, nil, &resp)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -672,7 +774,7 @@ func (cli *Client) Messages(roomID, from, to string, dir rune, limit int) (resp
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	urlPath := cli.BuildURLWithQuery([]string{"rooms", roomID, "messages"}, query)
 | 
						urlPath := cli.BuildURLWithQuery([]string{"rooms", roomID, "messages"}, query)
 | 
				
			||||||
	_, err = cli.MakeRequest("GET", urlPath, nil, &resp)
 | 
						err = cli.MakeRequest("GET", urlPath, nil, &resp)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -680,7 +782,7 @@ func (cli *Client) Messages(roomID, from, to string, dir rune, limit int) (resp
 | 
				
			||||||
// See http://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-voip-turnserver
 | 
					// See http://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-voip-turnserver
 | 
				
			||||||
func (cli *Client) TurnServer() (resp *RespTurnServer, err error) {
 | 
					func (cli *Client) TurnServer() (resp *RespTurnServer, err error) {
 | 
				
			||||||
	urlPath := cli.BuildURL("voip", "turnServer")
 | 
						urlPath := cli.BuildURL("voip", "turnServer")
 | 
				
			||||||
	_, err = cli.MakeRequest("GET", urlPath, nil, &resp)
 | 
						err = cli.MakeRequest("GET", urlPath, nil, &resp)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,7 +46,7 @@ func Example_customInterfaces() {
 | 
				
			||||||
	cli.Client = http.DefaultClient
 | 
						cli.Client = http.DefaultClient
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Once you call a function, you can't safely change the interfaces.
 | 
						// Once you call a function, you can't safely change the interfaces.
 | 
				
			||||||
	cli.SendText("!foo:bar", "Down the rabbit hole")
 | 
						_, _ = cli.SendText("!foo:bar", "Down the rabbit hole")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func ExampleClient_BuildURLWithQuery() {
 | 
					func ExampleClient_BuildURLWithQuery() {
 | 
				
			||||||
| 
						 | 
					@ -55,7 +55,7 @@ func ExampleClient_BuildURLWithQuery() {
 | 
				
			||||||
		"filter_id": "5",
 | 
							"filter_id": "5",
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	fmt.Println(out)
 | 
						fmt.Println(out)
 | 
				
			||||||
	// Output: https://matrix.org/_matrix/client/r0/sync?access_token=abcdef123456&filter_id=5
 | 
						// Output: https://matrix.org/_matrix/client/r0/sync?filter_id=5
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func ExampleClient_BuildURL() {
 | 
					func ExampleClient_BuildURL() {
 | 
				
			||||||
| 
						 | 
					@ -63,7 +63,7 @@ func ExampleClient_BuildURL() {
 | 
				
			||||||
	cli, _ := NewClient("https://matrix.org", userID, "abcdef123456")
 | 
						cli, _ := NewClient("https://matrix.org", userID, "abcdef123456")
 | 
				
			||||||
	out := cli.BuildURL("user", userID, "filter")
 | 
						out := cli.BuildURL("user", userID, "filter")
 | 
				
			||||||
	fmt.Println(out)
 | 
						fmt.Println(out)
 | 
				
			||||||
	// Output: https://matrix.org/_matrix/client/r0/user/@example:matrix.org/filter?access_token=abcdef123456
 | 
						// Output: https://matrix.org/_matrix/client/r0/user/@example:matrix.org/filter
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func ExampleClient_BuildBaseURL() {
 | 
					func ExampleClient_BuildBaseURL() {
 | 
				
			||||||
| 
						 | 
					@ -71,7 +71,7 @@ func ExampleClient_BuildBaseURL() {
 | 
				
			||||||
	cli, _ := NewClient("https://matrix.org", userID, "abcdef123456")
 | 
						cli, _ := NewClient("https://matrix.org", userID, "abcdef123456")
 | 
				
			||||||
	out := cli.BuildBaseURL("_matrix", "client", "r0", "directory", "room", "#matrix:matrix.org")
 | 
						out := cli.BuildBaseURL("_matrix", "client", "r0", "directory", "room", "#matrix:matrix.org")
 | 
				
			||||||
	fmt.Println(out)
 | 
						fmt.Println(out)
 | 
				
			||||||
	// Output: https://matrix.org/_matrix/client/r0/directory/room/%23matrix:matrix.org?access_token=abcdef123456
 | 
						// Output: https://matrix.org/_matrix/client/r0/directory/room/%23matrix:matrix.org
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Retrieve the content of a m.room.name state event.
 | 
					// Retrieve the content of a m.room.name state event.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -84,6 +84,55 @@ func TestClient_StateEvent(t *testing.T) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestClient_PublicRooms(t *testing.T) {
 | 
				
			||||||
 | 
						cli := mockClient(func(req *http.Request) (*http.Response, error) {
 | 
				
			||||||
 | 
							if req.Method == "GET" && req.URL.Path == "/_matrix/client/r0/publicRooms" {
 | 
				
			||||||
 | 
								return &http.Response{
 | 
				
			||||||
 | 
									StatusCode: 200,
 | 
				
			||||||
 | 
									Body: ioutil.NopCloser(bytes.NewBufferString(`{
 | 
				
			||||||
 | 
					  "chunk": [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      "aliases": [
 | 
				
			||||||
 | 
					        "#murrays:cheese.bar"
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "avatar_url": "mxc://bleeker.street/CHEDDARandBRIE",
 | 
				
			||||||
 | 
					      "guest_can_join": false,
 | 
				
			||||||
 | 
					      "name": "CHEESE",
 | 
				
			||||||
 | 
					      "num_joined_members": 37,
 | 
				
			||||||
 | 
					      "room_id": "!ol19s:bleecker.street",
 | 
				
			||||||
 | 
					      "topic": "Tasty tasty cheese",
 | 
				
			||||||
 | 
					      "world_readable": true
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					  "next_batch": "p190q",
 | 
				
			||||||
 | 
					  "prev_batch": "p1902",
 | 
				
			||||||
 | 
					  "total_room_count_estimate": 115
 | 
				
			||||||
 | 
					}`)),
 | 
				
			||||||
 | 
								}, nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("unhandled URL: %s", req.URL.Path)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						publicRooms, err := cli.PublicRooms(0, "", "")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("PublicRooms: error, got %s", err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if publicRooms.TotalRoomCountEstimate != 115 {
 | 
				
			||||||
 | 
							t.Fatalf("PublicRooms: got %d, want %d", publicRooms.TotalRoomCountEstimate, 115)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(publicRooms.Chunk) != 1 {
 | 
				
			||||||
 | 
							t.Fatalf("PublicRooms: got %d, want %d", len(publicRooms.Chunk), 1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if publicRooms.Chunk[0].Name != "CHEESE" {
 | 
				
			||||||
 | 
							t.Fatalf("PublicRooms: got %s, want %s", publicRooms.Chunk[0].Name, "CHEESE")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if publicRooms.Chunk[0].NumJoinedMembers != 37 {
 | 
				
			||||||
 | 
							t.Fatalf("PublicRooms: got %d, want %d", publicRooms.Chunk[0].NumJoinedMembers, 37)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func mockClient(fn func(*http.Request) (*http.Response, error)) *Client {
 | 
					func mockClient(fn func(*http.Request) (*http.Response, error)) *Client {
 | 
				
			||||||
	mrt := MockRoundTripper{
 | 
						mrt := MockRoundTripper{
 | 
				
			||||||
		RT: fn,
 | 
							RT: fn,
 | 
				
			||||||
| 
						 | 
					@ -101,5 +150,8 @@ type MockRoundTripper struct {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (t MockRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
 | 
					func (t MockRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
 | 
				
			||||||
 | 
						if req.Header.Get("Authorization") == "" {
 | 
				
			||||||
 | 
							panic("no auth")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return t.RT(req)
 | 
						return t.RT(req)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										59
									
								
								events.go
									
										
									
									
									
								
							
							
						
						
									
										59
									
								
								events.go
									
										
									
									
									
								
							| 
						 | 
					@ -13,8 +13,10 @@ type Event struct {
 | 
				
			||||||
	Timestamp   int64                  `json:"origin_server_ts"`       // The unix timestamp when this message was sent by the origin server
 | 
						Timestamp   int64                  `json:"origin_server_ts"`       // The unix timestamp when this message was sent by the origin server
 | 
				
			||||||
	ID          string                 `json:"event_id"`               // The unique ID of this event
 | 
						ID          string                 `json:"event_id"`               // The unique ID of this event
 | 
				
			||||||
	RoomID      string                 `json:"room_id"`                // The room the event was sent to. May be nil (e.g. for presence)
 | 
						RoomID      string                 `json:"room_id"`                // The room the event was sent to. May be nil (e.g. for presence)
 | 
				
			||||||
	Content   map[string]interface{} `json:"content"`             // The JSON content of the event.
 | 
					 | 
				
			||||||
	Redacts     string                 `json:"redacts,omitempty"`      // The event ID that was redacted if a m.room.redaction event
 | 
						Redacts     string                 `json:"redacts,omitempty"`      // The event ID that was redacted if a m.room.redaction event
 | 
				
			||||||
 | 
						Unsigned    map[string]interface{} `json:"unsigned"`               // The unsigned portions of the event, such as age and prev_content
 | 
				
			||||||
 | 
						Content     map[string]interface{} `json:"content"`                // The JSON content of the event.
 | 
				
			||||||
 | 
						PrevContent map[string]interface{} `json:"prev_content,omitempty"` // The JSON prev_content of the event.
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Body returns the value of the "body" key in the event content if it is
 | 
					// Body returns the value of the "body" key in the event content if it is
 | 
				
			||||||
| 
						 | 
					@ -43,6 +45,16 @@ func (event *Event) MessageType() (msgtype string, ok bool) {
 | 
				
			||||||
type TextMessage struct {
 | 
					type TextMessage struct {
 | 
				
			||||||
	MsgType       string `json:"msgtype"`
 | 
						MsgType       string `json:"msgtype"`
 | 
				
			||||||
	Body          string `json:"body"`
 | 
						Body          string `json:"body"`
 | 
				
			||||||
 | 
						FormattedBody string `json:"formatted_body"`
 | 
				
			||||||
 | 
						Format        string `json:"format"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ThumbnailInfo contains info about an thumbnail image - http://matrix.org/docs/spec/client_server/r0.2.0.html#m-image
 | 
				
			||||||
 | 
					type ThumbnailInfo struct {
 | 
				
			||||||
 | 
						Height   uint   `json:"h,omitempty"`
 | 
				
			||||||
 | 
						Width    uint   `json:"w,omitempty"`
 | 
				
			||||||
 | 
						Mimetype string `json:"mimetype,omitempty"`
 | 
				
			||||||
 | 
						Size     uint   `json:"size,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ImageInfo contains info about an image - http://matrix.org/docs/spec/client_server/r0.2.0.html#m-image
 | 
					// ImageInfo contains info about an image - http://matrix.org/docs/spec/client_server/r0.2.0.html#m-image
 | 
				
			||||||
| 
						 | 
					@ -51,12 +63,14 @@ type ImageInfo struct {
 | 
				
			||||||
	Width         uint          `json:"w,omitempty"`
 | 
						Width         uint          `json:"w,omitempty"`
 | 
				
			||||||
	Mimetype      string        `json:"mimetype,omitempty"`
 | 
						Mimetype      string        `json:"mimetype,omitempty"`
 | 
				
			||||||
	Size          uint          `json:"size,omitempty"`
 | 
						Size          uint          `json:"size,omitempty"`
 | 
				
			||||||
 | 
						ThumbnailInfo ThumbnailInfo `json:"thumbnail_info,omitempty"`
 | 
				
			||||||
 | 
						ThumbnailURL  string        `json:"thumbnail_url,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// VideoInfo contains info about a video - http://matrix.org/docs/spec/client_server/r0.2.0.html#m-video
 | 
					// VideoInfo contains info about a video - http://matrix.org/docs/spec/client_server/r0.2.0.html#m-video
 | 
				
			||||||
type VideoInfo struct {
 | 
					type VideoInfo struct {
 | 
				
			||||||
	Mimetype      string        `json:"mimetype,omitempty"`
 | 
						Mimetype      string        `json:"mimetype,omitempty"`
 | 
				
			||||||
	ThumbnailInfo ImageInfo `json:"thumbnail_info"`
 | 
						ThumbnailInfo ThumbnailInfo `json:"thumbnail_info"`
 | 
				
			||||||
	ThumbnailURL  string        `json:"thumbnail_url,omitempty"`
 | 
						ThumbnailURL  string        `json:"thumbnail_url,omitempty"`
 | 
				
			||||||
	Height        uint          `json:"h,omitempty"`
 | 
						Height        uint          `json:"h,omitempty"`
 | 
				
			||||||
	Width         uint          `json:"w,omitempty"`
 | 
						Width         uint          `json:"w,omitempty"`
 | 
				
			||||||
| 
						 | 
					@ -88,6 +102,47 @@ type HTMLMessage struct {
 | 
				
			||||||
	FormattedBody string `json:"formatted_body"`
 | 
						FormattedBody string `json:"formatted_body"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// FileInfo contains info about an file - http://matrix.org/docs/spec/client_server/r0.2.0.html#m-file
 | 
				
			||||||
 | 
					type FileInfo struct {
 | 
				
			||||||
 | 
						Mimetype string `json:"mimetype,omitempty"`
 | 
				
			||||||
 | 
						Size     uint   `json:"size,omitempty"` //filesize in bytes
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// FileMessage is an m.file event - http://matrix.org/docs/spec/client_server/r0.2.0.html#m-file
 | 
				
			||||||
 | 
					type FileMessage struct {
 | 
				
			||||||
 | 
						MsgType       string    `json:"msgtype"`
 | 
				
			||||||
 | 
						Body          string    `json:"body"`
 | 
				
			||||||
 | 
						URL           string    `json:"url"`
 | 
				
			||||||
 | 
						Filename      string    `json:"filename"`
 | 
				
			||||||
 | 
						Info          FileInfo  `json:"info,omitempty"`
 | 
				
			||||||
 | 
						ThumbnailURL  string    `json:"thumbnail_url,omitempty"`
 | 
				
			||||||
 | 
						ThumbnailInfo ImageInfo `json:"thumbnail_info,omitempty"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// LocationMessage is an m.location event - http://matrix.org/docs/spec/client_server/r0.2.0.html#m-location
 | 
				
			||||||
 | 
					type LocationMessage struct {
 | 
				
			||||||
 | 
						MsgType       string    `json:"msgtype"`
 | 
				
			||||||
 | 
						Body          string    `json:"body"`
 | 
				
			||||||
 | 
						GeoURI        string    `json:"geo_uri"`
 | 
				
			||||||
 | 
						ThumbnailURL  string    `json:"thumbnail_url,omitempty"`
 | 
				
			||||||
 | 
						ThumbnailInfo ImageInfo `json:"thumbnail_info,omitempty"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// AudioInfo contains info about an file - http://matrix.org/docs/spec/client_server/r0.2.0.html#m-audio
 | 
				
			||||||
 | 
					type AudioInfo struct {
 | 
				
			||||||
 | 
						Mimetype string `json:"mimetype,omitempty"`
 | 
				
			||||||
 | 
						Size     uint   `json:"size,omitempty"`     //filesize in bytes
 | 
				
			||||||
 | 
						Duration uint   `json:"duration,omitempty"` //audio duration in ms
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// AudioMessage is an m.audio event - http://matrix.org/docs/spec/client_server/r0.2.0.html#m-audio
 | 
				
			||||||
 | 
					type AudioMessage struct {
 | 
				
			||||||
 | 
						MsgType string    `json:"msgtype"`
 | 
				
			||||||
 | 
						Body    string    `json:"body"`
 | 
				
			||||||
 | 
						URL     string    `json:"url"`
 | 
				
			||||||
 | 
						Info    AudioInfo `json:"info,omitempty"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var htmlRegex = regexp.MustCompile("<[^<]+?>")
 | 
					var htmlRegex = regexp.MustCompile("<[^<]+?>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetHTMLMessage returns an HTMLMessage with the body set to a stripped version of the provided HTML, in addition
 | 
					// GetHTMLMessage returns an HTMLMessage with the body set to a stripped version of the provided HTML, in addition
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										110
									
								
								events_test.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								events_test.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,110 @@
 | 
				
			||||||
 | 
					package gomatrix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// example events from docs
 | 
				
			||||||
 | 
					var testEvents = map[string]string{
 | 
				
			||||||
 | 
						"withFields": `{
 | 
				
			||||||
 | 
					        "content": {
 | 
				
			||||||
 | 
					            "body": "eventbody123",
 | 
				
			||||||
 | 
					            "msgtype": "m.text",
 | 
				
			||||||
 | 
					            "format": "org.matrix.custom.html",
 | 
				
			||||||
 | 
					            "formatted_body": "<b>This is an example text message</b>"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "type": "m.room.message",
 | 
				
			||||||
 | 
					        "event_id": "$143273582443PhrSn:example.org",
 | 
				
			||||||
 | 
					        "room_id": "!726s6s6q:example.com",
 | 
				
			||||||
 | 
					        "sender": "@example:example.org",
 | 
				
			||||||
 | 
					        "origin_server_ts": 1432735824653,
 | 
				
			||||||
 | 
					        "unsigned": {
 | 
				
			||||||
 | 
					            "age": 1234
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }`,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"withoutFields": `{
 | 
				
			||||||
 | 
					        "content": {
 | 
				
			||||||
 | 
					            "avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF",
 | 
				
			||||||
 | 
					            "displayname": "Alice Margatroid",
 | 
				
			||||||
 | 
					            "membership": "join"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "event_id": "$143273582443PhrSn:example.org",
 | 
				
			||||||
 | 
					        "origin_server_ts": 1432735824653,
 | 
				
			||||||
 | 
					        "room_id": "!jEsUZKDJdhlrceRyVU:example.org",
 | 
				
			||||||
 | 
					        "sender": "@example:example.org",
 | 
				
			||||||
 | 
					        "state_key": "@alice:example.org",
 | 
				
			||||||
 | 
					        "type": "m.room.member",
 | 
				
			||||||
 | 
					        "unsigned": {
 | 
				
			||||||
 | 
					            "age": 1234
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }`,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestEventWithBody(t *testing.T) {
 | 
				
			||||||
 | 
						var e Event
 | 
				
			||||||
 | 
						err := json.NewDecoder(strings.NewReader(testEvents["withFields"])).Decode(&e)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("TestFetchEventBody: Something went wrong while parsing: %s", testEvents["withFields"])
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						body, ok := e.Body()
 | 
				
			||||||
 | 
						if !ok || body != "eventbody123" {
 | 
				
			||||||
 | 
							t.Fatal("TestEventWithBody: Failed to fetch value of 'body' key in event content")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestEventWithoutBody(t *testing.T) {
 | 
				
			||||||
 | 
						var e Event
 | 
				
			||||||
 | 
						err := json.NewDecoder(strings.NewReader(testEvents["withoutFields"])).Decode(&e)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("TestEventWithoutBody: Something went wrong while parsing: %s", testEvents["withFields"])
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						body, ok := e.Body()
 | 
				
			||||||
 | 
						if ok || body != "" {
 | 
				
			||||||
 | 
							t.Fatal("TestEventWithoutBody: Failed on 'Event.Body' call for event without a 'body' key")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestEventWithMessageType(t *testing.T) {
 | 
				
			||||||
 | 
						var e Event
 | 
				
			||||||
 | 
						err := json.NewDecoder(strings.NewReader(testEvents["withFields"])).Decode(&e)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("TestEventWithMessageType: Something went wrong while parsing: %s", testEvents["withFields"])
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						msgtype, ok := e.MessageType()
 | 
				
			||||||
 | 
						if !ok || msgtype != "m.text" {
 | 
				
			||||||
 | 
							t.Fatal("TestEventWithMessageType: Failed to fetch value of 'msgtype' key in event content")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestEventWithoutMessageType(t *testing.T) {
 | 
				
			||||||
 | 
						var e Event
 | 
				
			||||||
 | 
						err := json.NewDecoder(strings.NewReader(testEvents["withoutFields"])).Decode(&e)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("TestEventWithMessageType: Something went wrong while parsing: %s", testEvents["withFields"])
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						msgtype, ok := e.MessageType()
 | 
				
			||||||
 | 
						if ok || msgtype != "" {
 | 
				
			||||||
 | 
							t.Fatal("TestEventWithoutBody: Failed on 'Event.Body' call for event without a 'msgtype' key")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var testHTML = `<div>a<h1>bc</h1>d<p>e<i>fg</i>hi</p>j<p>k<br/>l<b>m</b>no</p>p<small>q</small>rs</div>`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestGetHTMLMessage(t *testing.T) {
 | 
				
			||||||
 | 
						msg := GetHTMLMessage("m.text", testHTML)
 | 
				
			||||||
 | 
						if expected := "abcdefghijklmnopqrs"; msg.Body != expected {
 | 
				
			||||||
 | 
							t.Fatalf("TestGetHTMLMessage: got '%s', expected '%s'", msg.Body, expected)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if msg.FormattedBody != testHTML {
 | 
				
			||||||
 | 
							t.Fatalf("TestGetHTMLMessage: got '%s', expected '%s'", msg.FormattedBody, testHTML)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if msg.MsgType != "m.text" {
 | 
				
			||||||
 | 
							t.Fatalf("TestGetHTMLMessage: got '%s', expected 'm.text'", msg.FormattedBody)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if expected := "org.matrix.custom.html"; msg.Format != expected {
 | 
				
			||||||
 | 
							t.Fatalf("TestGetHTMLMessage: got '%s', expected '%s'", msg.Format, expected)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										3
									
								
								go.mod
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								go.mod
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,3 @@
 | 
				
			||||||
 | 
					module github.com/matrix-org/gomatrix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					go 1.12
 | 
				
			||||||
| 
						 | 
					@ -2,9 +2,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set -eu
 | 
					set -eu
 | 
				
			||||||
 | 
					
 | 
				
			||||||
golint
 | 
					 | 
				
			||||||
misspell --error .
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# gofmt doesn't exit with an error code if the files don't match the expected
 | 
					# gofmt doesn't exit with an error code if the files don't match the expected
 | 
				
			||||||
# format. So we have to run it and see if it outputs anything.
 | 
					# format. So we have to run it and see if it outputs anything.
 | 
				
			||||||
if gofmt -l -s . 2>&1 | read
 | 
					if gofmt -l -s . 2>&1 | read
 | 
				
			||||||
| 
						 | 
					@ -18,9 +15,5 @@ then
 | 
				
			||||||
    exit 1
 | 
					    exit 1
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ineffassign .
 | 
					golangci-lint run
 | 
				
			||||||
 | 
					go test -timeout 5s . ./...
 | 
				
			||||||
go fmt
 | 
					 | 
				
			||||||
go tool vet --all --shadow .
 | 
					 | 
				
			||||||
gocyclo -over 12 .
 | 
					 | 
				
			||||||
go test -timeout 5s -test.v
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										69
									
								
								identifier.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								identifier.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,69 @@
 | 
				
			||||||
 | 
					package gomatrix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Identifier is the interface for https://matrix.org/docs/spec/client_server/r0.6.0#identifier-types
 | 
				
			||||||
 | 
					type Identifier interface {
 | 
				
			||||||
 | 
						// Returns the identifier type
 | 
				
			||||||
 | 
						// https://matrix.org/docs/spec/client_server/r0.6.0#identifier-types
 | 
				
			||||||
 | 
						Type() string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// UserIdentifier is the Identifier for https://matrix.org/docs/spec/client_server/r0.6.0#matrix-user-id
 | 
				
			||||||
 | 
					type UserIdentifier struct {
 | 
				
			||||||
 | 
						IDType string `json:"type"` // Set by NewUserIdentifer
 | 
				
			||||||
 | 
						User   string `json:"user"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Type implements the Identifier interface
 | 
				
			||||||
 | 
					func (i UserIdentifier) Type() string {
 | 
				
			||||||
 | 
						return "m.id.user"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewUserIdentifier creates a new UserIdentifier with IDType set to "m.id.user"
 | 
				
			||||||
 | 
					func NewUserIdentifier(user string) UserIdentifier {
 | 
				
			||||||
 | 
						return UserIdentifier{
 | 
				
			||||||
 | 
							IDType: "m.id.user",
 | 
				
			||||||
 | 
							User:   user,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ThirdpartyIdentifier is the Identifier for https://matrix.org/docs/spec/client_server/r0.6.0#third-party-id
 | 
				
			||||||
 | 
					type ThirdpartyIdentifier struct {
 | 
				
			||||||
 | 
						IDType  string `json:"type"` // Set by NewThirdpartyIdentifier
 | 
				
			||||||
 | 
						Medium  string `json:"medium"`
 | 
				
			||||||
 | 
						Address string `json:"address"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Type implements the Identifier interface
 | 
				
			||||||
 | 
					func (i ThirdpartyIdentifier) Type() string {
 | 
				
			||||||
 | 
						return "m.id.thirdparty"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewThirdpartyIdentifier creates a new UserIdentifier with IDType set to "m.id.user"
 | 
				
			||||||
 | 
					func NewThirdpartyIdentifier(medium, address string) ThirdpartyIdentifier {
 | 
				
			||||||
 | 
						return ThirdpartyIdentifier{
 | 
				
			||||||
 | 
							IDType:  "m.id.thirdparty",
 | 
				
			||||||
 | 
							Medium:  medium,
 | 
				
			||||||
 | 
							Address: address,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PhoneIdentifier is the Identifier for https://matrix.org/docs/spec/client_server/r0.6.0#phone-number
 | 
				
			||||||
 | 
					type PhoneIdentifier struct {
 | 
				
			||||||
 | 
						IDType  string `json:"type"` // Set by NewPhoneIdentifier
 | 
				
			||||||
 | 
						Country string `json:"country"`
 | 
				
			||||||
 | 
						Phone   string `json:"phone"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Type implements the Identifier interface
 | 
				
			||||||
 | 
					func (i PhoneIdentifier) Type() string {
 | 
				
			||||||
 | 
						return "m.id.phone"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewPhoneIdentifier creates a new UserIdentifier with IDType set to "m.id.user"
 | 
				
			||||||
 | 
					func NewPhoneIdentifier(country, phone string) PhoneIdentifier {
 | 
				
			||||||
 | 
						return PhoneIdentifier{
 | 
				
			||||||
 | 
							IDType:  "m.id.phone",
 | 
				
			||||||
 | 
							Country: country,
 | 
				
			||||||
 | 
							Phone:   phone,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -10,9 +10,10 @@ type ReqRegister struct {
 | 
				
			||||||
	Auth                     interface{} `json:"auth,omitempty"`
 | 
						Auth                     interface{} `json:"auth,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ReqLogin is the JSON request for http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-login
 | 
					// ReqLogin is the JSON request for http://matrix.org/docs/spec/client_server/r0.6.0.html#post-matrix-client-r0-login
 | 
				
			||||||
type ReqLogin struct {
 | 
					type ReqLogin struct {
 | 
				
			||||||
	Type                     string     `json:"type"`
 | 
						Type                     string     `json:"type"`
 | 
				
			||||||
 | 
						Identifier               Identifier `json:"identifier,omitempty"`
 | 
				
			||||||
	Password                 string     `json:"password,omitempty"`
 | 
						Password                 string     `json:"password,omitempty"`
 | 
				
			||||||
	Medium                   string     `json:"medium,omitempty"`
 | 
						Medium                   string     `json:"medium,omitempty"`
 | 
				
			||||||
	User                     string     `json:"user,omitempty"`
 | 
						User                     string     `json:"user,omitempty"`
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										39
									
								
								responses.go
									
										
									
									
									
								
							
							
						
						
									
										39
									
								
								responses.go
									
										
									
									
									
								
							| 
						 | 
					@ -22,6 +22,14 @@ type RespVersions struct {
 | 
				
			||||||
	Versions []string `json:"versions"`
 | 
						Versions []string `json:"versions"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RespPublicRooms is the JSON response for http://matrix.org/speculator/spec/HEAD/client_server/unstable.html#get-matrix-client-unstable-publicrooms
 | 
				
			||||||
 | 
					type RespPublicRooms struct {
 | 
				
			||||||
 | 
						TotalRoomCountEstimate int          `json:"total_room_count_estimate"`
 | 
				
			||||||
 | 
						PrevBatch              string       `json:"prev_batch"`
 | 
				
			||||||
 | 
						NextBatch              string       `json:"next_batch"`
 | 
				
			||||||
 | 
						Chunk                  []PublicRoom `json:"chunk"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RespJoinRoom is the JSON response for http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-rooms-roomid-join
 | 
					// RespJoinRoom is the JSON response for http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-rooms-roomid-join
 | 
				
			||||||
type RespJoinRoom struct {
 | 
					type RespJoinRoom struct {
 | 
				
			||||||
	RoomID string `json:"room_id"`
 | 
						RoomID string `json:"room_id"`
 | 
				
			||||||
| 
						 | 
					@ -84,7 +92,7 @@ type RespUserInteractive struct {
 | 
				
			||||||
		Stages []string `json:"stages"`
 | 
							Stages []string `json:"stages"`
 | 
				
			||||||
	} `json:"flows"`
 | 
						} `json:"flows"`
 | 
				
			||||||
	Params    map[string]interface{} `json:"params"`
 | 
						Params    map[string]interface{} `json:"params"`
 | 
				
			||||||
	Session   string                 `json:"string"`
 | 
						Session   string                 `json:"session"`
 | 
				
			||||||
	Completed []string               `json:"completed"`
 | 
						Completed []string               `json:"completed"`
 | 
				
			||||||
	ErrCode   string                 `json:"errcode"`
 | 
						ErrCode   string                 `json:"errcode"`
 | 
				
			||||||
	Error     string                 `json:"error"`
 | 
						Error     string                 `json:"error"`
 | 
				
			||||||
| 
						 | 
					@ -105,6 +113,14 @@ type RespUserDisplayName struct {
 | 
				
			||||||
	DisplayName string `json:"displayname"`
 | 
						DisplayName string `json:"displayname"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RespUserStatus is the JSON response for https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-presence-userid-status
 | 
				
			||||||
 | 
					type RespUserStatus struct {
 | 
				
			||||||
 | 
						Presence        string `json:"presence"`
 | 
				
			||||||
 | 
						StatusMsg       string `json:"status_msg"`
 | 
				
			||||||
 | 
						LastActiveAgo   int    `json:"last_active_ago"`
 | 
				
			||||||
 | 
						CurrentlyActive bool   `json:"currently_active"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RespRegister is the JSON response for http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-register
 | 
					// RespRegister is the JSON response for http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-register
 | 
				
			||||||
type RespRegister struct {
 | 
					type RespRegister struct {
 | 
				
			||||||
	AccessToken  string `json:"access_token"`
 | 
						AccessToken  string `json:"access_token"`
 | 
				
			||||||
| 
						 | 
					@ -114,17 +130,31 @@ type RespRegister struct {
 | 
				
			||||||
	UserID       string `json:"user_id"`
 | 
						UserID       string `json:"user_id"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RespLogin is the JSON response for http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-login
 | 
					// RespLogin is the JSON response for http://matrix.org/docs/spec/client_server/r0.6.0.html#post-matrix-client-r0-login
 | 
				
			||||||
type RespLogin struct {
 | 
					type RespLogin struct {
 | 
				
			||||||
	AccessToken string               `json:"access_token"`
 | 
						AccessToken string               `json:"access_token"`
 | 
				
			||||||
	DeviceID    string               `json:"device_id"`
 | 
						DeviceID    string               `json:"device_id"`
 | 
				
			||||||
	HomeServer  string               `json:"home_server"`
 | 
						HomeServer  string               `json:"home_server"`
 | 
				
			||||||
	UserID      string               `json:"user_id"`
 | 
						UserID      string               `json:"user_id"`
 | 
				
			||||||
 | 
						WellKnown   DiscoveryInformation `json:"well_known"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RespLogout is the JSON response for http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-logout
 | 
					// DiscoveryInformation is the JSON Response for https://matrix.org/docs/spec/client_server/r0.6.0#get-well-known-matrix-client and a part of the JSON Response for https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-login
 | 
				
			||||||
 | 
					type DiscoveryInformation struct {
 | 
				
			||||||
 | 
						Homeserver struct {
 | 
				
			||||||
 | 
							BaseURL string `json:"base_url"`
 | 
				
			||||||
 | 
						} `json:"m.homeserver"`
 | 
				
			||||||
 | 
						IdentityServer struct {
 | 
				
			||||||
 | 
							BaseURL string `json:"base_url"`
 | 
				
			||||||
 | 
						} `json:"m.identitiy_server"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RespLogout is the JSON response for http://matrix.org/docs/spec/client_server/r0.6.0.html#post-matrix-client-r0-logout
 | 
				
			||||||
type RespLogout struct{}
 | 
					type RespLogout struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RespLogoutAll is the JSON response for https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-logout-all
 | 
				
			||||||
 | 
					type RespLogoutAll struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RespCreateRoom is the JSON response for https://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-createroom
 | 
					// RespCreateRoom is the JSON response for https://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-createroom
 | 
				
			||||||
type RespCreateRoom struct {
 | 
					type RespCreateRoom struct {
 | 
				
			||||||
	RoomID string `json:"room_id"`
 | 
						RoomID string `json:"room_id"`
 | 
				
			||||||
| 
						 | 
					@ -159,6 +189,9 @@ type RespSync struct {
 | 
				
			||||||
				Limited   bool    `json:"limited"`
 | 
									Limited   bool    `json:"limited"`
 | 
				
			||||||
				PrevBatch string  `json:"prev_batch"`
 | 
									PrevBatch string  `json:"prev_batch"`
 | 
				
			||||||
			} `json:"timeline"`
 | 
								} `json:"timeline"`
 | 
				
			||||||
 | 
								Ephemeral struct {
 | 
				
			||||||
 | 
									Events []Event `json:"events"`
 | 
				
			||||||
 | 
								} `json:"ephemeral"`
 | 
				
			||||||
		} `json:"join"`
 | 
							} `json:"join"`
 | 
				
			||||||
		Invite map[string]struct {
 | 
							Invite map[string]struct {
 | 
				
			||||||
			State struct {
 | 
								State struct {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										17
									
								
								room.go
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								room.go
									
										
									
									
									
								
							| 
						 | 
					@ -6,6 +6,19 @@ type Room struct {
 | 
				
			||||||
	State map[string]map[string]*Event
 | 
						State map[string]map[string]*Event
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PublicRoom represents the information about a public room obtainable from the room directory
 | 
				
			||||||
 | 
					type PublicRoom struct {
 | 
				
			||||||
 | 
						CanonicalAlias   string   `json:"canonical_alias"`
 | 
				
			||||||
 | 
						Name             string   `json:"name"`
 | 
				
			||||||
 | 
						WorldReadable    bool     `json:"world_readable"`
 | 
				
			||||||
 | 
						Topic            string   `json:"topic"`
 | 
				
			||||||
 | 
						NumJoinedMembers int      `json:"num_joined_members"`
 | 
				
			||||||
 | 
						AvatarURL        string   `json:"avatar_url"`
 | 
				
			||||||
 | 
						RoomID           string   `json:"room_id"`
 | 
				
			||||||
 | 
						GuestCanJoin     bool     `json:"guest_can_join"`
 | 
				
			||||||
 | 
						Aliases          []string `json:"aliases"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// UpdateState updates the room's current state with the given Event. This will clobber events based
 | 
					// UpdateState updates the room's current state with the given Event. This will clobber events based
 | 
				
			||||||
// on the type/state_key combination.
 | 
					// on the type/state_key combination.
 | 
				
			||||||
func (room Room) UpdateState(event *Event) {
 | 
					func (room Room) UpdateState(event *Event) {
 | 
				
			||||||
| 
						 | 
					@ -18,8 +31,8 @@ func (room Room) UpdateState(event *Event) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetStateEvent returns the state event for the given type/state_key combo, or nil.
 | 
					// GetStateEvent returns the state event for the given type/state_key combo, or nil.
 | 
				
			||||||
func (room Room) GetStateEvent(eventType string, stateKey string) *Event {
 | 
					func (room Room) GetStateEvent(eventType string, stateKey string) *Event {
 | 
				
			||||||
	stateEventMap, _ := room.State[eventType]
 | 
						stateEventMap := room.State[eventType]
 | 
				
			||||||
	event, _ := stateEventMap[stateKey]
 | 
						event := stateEventMap[stateKey]
 | 
				
			||||||
	return event
 | 
						return event
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										4
									
								
								sync.go
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								sync.go
									
										
									
									
									
								
							| 
						 | 
					@ -64,6 +64,10 @@ func (s *DefaultSyncer) ProcessResponse(res *RespSync, since string) (err error)
 | 
				
			||||||
			event.RoomID = roomID
 | 
								event.RoomID = roomID
 | 
				
			||||||
			s.notifyListeners(&event)
 | 
								s.notifyListeners(&event)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							for _, event := range roomData.Ephemeral.Events {
 | 
				
			||||||
 | 
								event.RoomID = roomID
 | 
				
			||||||
 | 
								s.notifyListeners(&event)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for roomID, roomData := range res.Rooms.Invite {
 | 
						for roomID, roomData := range res.Rooms.Invite {
 | 
				
			||||||
		room := s.getOrCreateRoom(roomID)
 | 
							room := s.getOrCreateRoom(roomID)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										26
									
								
								tags.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								tags.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,26 @@
 | 
				
			||||||
 | 
					// Copyright 2019 Sumukha PK
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package gomatrix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TagContent contains the data for an m.tag message type
 | 
				
			||||||
 | 
					// https://matrix.org/docs/spec/client_server/r0.4.0.html#m-tag
 | 
				
			||||||
 | 
					type TagContent struct {
 | 
				
			||||||
 | 
						Tags map[string]TagProperties `json:"tags"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TagProperties contains the properties of a Tag
 | 
				
			||||||
 | 
					type TagProperties struct {
 | 
				
			||||||
 | 
						Order float32 `json:"order,omitempty"` // Empty values must be neglected
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue