mirror of
				https://github.com/matrix-org/gomatrix
				synced 2025-11-03 22:08:04 +00:00 
			
		
		
		
	Add responses/room types. Add buildURL functions with examples
This commit is contained in:
		
							parent
							
								
									97f4e98e1d
								
							
						
					
					
						commit
						527c6568c9
					
				
					 4 changed files with 160 additions and 4 deletions
				
			
		
							
								
								
									
										51
									
								
								client.go
									
										
									
									
									
								
							
							
						
						
									
										51
									
								
								client.go
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,8 +1,12 @@
 | 
			
		|||
// Package gomatrix implements the Matrix Client-Server API.
 | 
			
		||||
//
 | 
			
		||||
// Specification can be found at http://matrix.org/docs/spec/client_server/r0.2.0.html
 | 
			
		||||
package gomatrix
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"path"
 | 
			
		||||
	"sync"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -20,11 +24,49 @@ type Client struct {
 | 
			
		|||
	// TODO: Worker and Rooms
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BuildURL builds a URL with the Client's homserver/prefix/access_token set already.
 | 
			
		||||
func (cli *Client) BuildURL(urlPath ...string) string {
 | 
			
		||||
	ps := []string{cli.Prefix}
 | 
			
		||||
	for _, p := range urlPath {
 | 
			
		||||
		ps = append(ps, p)
 | 
			
		||||
	}
 | 
			
		||||
	return cli.BuildBaseURL(ps...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BuildBaseURL builds a URL with the Client's homeserver/access_token set already. You must
 | 
			
		||||
// supply the prefix in the path.
 | 
			
		||||
func (cli *Client) BuildBaseURL(urlPath ...string) string {
 | 
			
		||||
	// copy the URL. Purposefully ignore error as the input is from a valid URL already
 | 
			
		||||
	hsURL, _ := url.Parse(cli.HomeserverURL.String())
 | 
			
		||||
	parts := []string{hsURL.Path}
 | 
			
		||||
	parts = append(parts, urlPath...)
 | 
			
		||||
	hsURL.Path = path.Join(parts...)
 | 
			
		||||
	query := hsURL.Query()
 | 
			
		||||
	query.Set("access_token", cli.AccessToken)
 | 
			
		||||
	hsURL.RawQuery = query.Encode()
 | 
			
		||||
	return hsURL.String()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BuildURLWithQuery builds a URL with query paramters in addition to the Client's homeserver/prefix/access_token set already.
 | 
			
		||||
func (cli *Client) BuildURLWithQuery(urlPath []string, urlQuery map[string]string) string {
 | 
			
		||||
	u, _ := url.Parse(cli.BuildURL(urlPath...))
 | 
			
		||||
	q := u.Query()
 | 
			
		||||
	for k, v := range urlQuery {
 | 
			
		||||
		q.Set(k, v)
 | 
			
		||||
	}
 | 
			
		||||
	u.RawQuery = q.Encode()
 | 
			
		||||
	return u.String()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewClient creates a new Matrix Client ready for syncing
 | 
			
		||||
func NewClient(httpClient *http.Client, homeserverURL *url.URL, accessToken, userID string) *Client {
 | 
			
		||||
func NewClient(homeserverURL, userID, accessToken string) (*Client, error) {
 | 
			
		||||
	hsURL, err := url.Parse(homeserverURL)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	cli := Client{
 | 
			
		||||
		AccessToken:   accessToken,
 | 
			
		||||
		HomeserverURL: homeserverURL,
 | 
			
		||||
		HomeserverURL: hsURL,
 | 
			
		||||
		UserID:        userID,
 | 
			
		||||
		Prefix:        "/_matrix/client/r0",
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -36,7 +78,8 @@ func NewClient(httpClient *http.Client, homeserverURL *url.URL, accessToken, use
 | 
			
		|||
	// "load" nothing. The client will work with this storer: it just won't remember the filter
 | 
			
		||||
	// ID across restarts and hence request a new one. In practice, a database backend should be used.
 | 
			
		||||
	cli.FilterStorer = NopFilterStore{}
 | 
			
		||||
	cli.Client = httpClient
 | 
			
		||||
	// By default, use the default HTTP client.
 | 
			
		||||
	cli.Client = http.DefaultClient
 | 
			
		||||
 | 
			
		||||
	return &cli
 | 
			
		||||
	return &cli, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										28
									
								
								client_test.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								client_test.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,28 @@
 | 
			
		|||
package gomatrix
 | 
			
		||||
 | 
			
		||||
import "fmt"
 | 
			
		||||
 | 
			
		||||
func ExampleBuildURLWithQuery() {
 | 
			
		||||
	cli, _ := NewClient("https://matrix.org", "@example:matrix.org", "abcdef123456")
 | 
			
		||||
	out := cli.BuildURLWithQuery([]string{"sync"}, map[string]string{
 | 
			
		||||
		"filter_id": "5",
 | 
			
		||||
	})
 | 
			
		||||
	fmt.Println(out)
 | 
			
		||||
	// Output: https://matrix.org/_matrix/client/r0/sync?access_token=abcdef123456&filter_id=5
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ExampleBuildURL() {
 | 
			
		||||
	userID := "@example:matrix.org"
 | 
			
		||||
	cli, _ := NewClient("https://matrix.org", userID, "abcdef123456")
 | 
			
		||||
	out := cli.BuildURL("user", userID, "filter")
 | 
			
		||||
	fmt.Println(out)
 | 
			
		||||
	// Output: https://matrix.org/_matrix/client/r0/user/@example:matrix.org/filter?access_token=abcdef123456
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ExampleBuildBaseURL() {
 | 
			
		||||
	userID := "@example:matrix.org"
 | 
			
		||||
	cli, _ := NewClient("https://matrix.org", userID, "abcdef123456")
 | 
			
		||||
	out := cli.BuildBaseURL("_matrix", "client", "r0", "directory", "room", "#matrix:matrix.org")
 | 
			
		||||
	fmt.Println(out)
 | 
			
		||||
	// Output: https://matrix.org/_matrix/client/r0/directory/room/%23matrix:matrix.org?access_token=abcdef123456
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										44
									
								
								responses.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								responses.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,44 @@
 | 
			
		|||
package gomatrix
 | 
			
		||||
 | 
			
		||||
// RespCreateFilter is the JSON response for http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-user-userid-filter
 | 
			
		||||
type RespCreateFilter struct {
 | 
			
		||||
	FilterID string `json:"filter_id"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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 {
 | 
			
		||||
	RoomID string `json:"room_id"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RespSendEvent is the JSON response for http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-send-eventtype-txnid
 | 
			
		||||
type RespSendEvent struct {
 | 
			
		||||
	EventID string `json:"event_id"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RespSync is the JSON response for http://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-sync
 | 
			
		||||
type RespSync struct {
 | 
			
		||||
	NextBatch   string `json:"next_batch"`
 | 
			
		||||
	AccountData struct {
 | 
			
		||||
		Events []Event `json:"events"`
 | 
			
		||||
	} `json:"account_data"`
 | 
			
		||||
	Presence struct {
 | 
			
		||||
		Events []Event `json:"events"`
 | 
			
		||||
	} `json:"presence"`
 | 
			
		||||
	Rooms struct {
 | 
			
		||||
		Join map[string]struct {
 | 
			
		||||
			State struct {
 | 
			
		||||
				Events []Event `json:"events"`
 | 
			
		||||
			} `json:"state"`
 | 
			
		||||
			Timeline struct {
 | 
			
		||||
				Events    []Event `json:"events"`
 | 
			
		||||
				Limited   bool    `json:"limited"`
 | 
			
		||||
				PrevBatch string  `json:"prev_batch"`
 | 
			
		||||
			} `json:"timeline"`
 | 
			
		||||
		} `json:"join"`
 | 
			
		||||
		Invite map[string]struct {
 | 
			
		||||
			State struct {
 | 
			
		||||
				Events []Event
 | 
			
		||||
			} `json:"invite_state"`
 | 
			
		||||
		} `json:"invite"`
 | 
			
		||||
	} `json:"rooms"`
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										41
									
								
								room.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								room.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,41 @@
 | 
			
		|||
package gomatrix
 | 
			
		||||
 | 
			
		||||
// Room represents a single Matrix room.
 | 
			
		||||
type Room struct {
 | 
			
		||||
	ID    string
 | 
			
		||||
	State map[string]map[string]*Event
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UpdateState updates the room's current state with the given Event. This will clobber events based
 | 
			
		||||
// on the type/state_key combination.
 | 
			
		||||
func (room Room) UpdateState(event *Event) {
 | 
			
		||||
	_, exists := room.State[event.Type]
 | 
			
		||||
	if !exists {
 | 
			
		||||
		room.State[event.Type] = make(map[string]*Event)
 | 
			
		||||
	}
 | 
			
		||||
	room.State[event.Type][event.StateKey] = event
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetStateEvent returns the state event for the given type/state_key combo, or nil.
 | 
			
		||||
func (room Room) GetStateEvent(eventType string, stateKey string) *Event {
 | 
			
		||||
	stateEventMap, _ := room.State[eventType]
 | 
			
		||||
	event, _ := stateEventMap[stateKey]
 | 
			
		||||
	return event
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetMembershipState returns the membership state of the given user ID in this room. If there is
 | 
			
		||||
// no entry for this member, 'leave' is returned for consistency with left users.
 | 
			
		||||
func (room Room) GetMembershipState(userID string) string {
 | 
			
		||||
	state := "leave"
 | 
			
		||||
	event := room.GetStateEvent("m.room.member", userID)
 | 
			
		||||
	if event != nil {
 | 
			
		||||
		membershipState, found := event.Content["membership"]
 | 
			
		||||
		if found {
 | 
			
		||||
			mState, isString := membershipState.(string)
 | 
			
		||||
			if isString {
 | 
			
		||||
				state = mState
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return state
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue