sdnclient

package module
v0.1.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 6, 2023 License: Apache-2.0 Imports: 17 Imported by: 0

README

sendingnetwork-bot

A Golang SDN client.

Install

go get github.com/sending-network/sendingnetwork-bot

Usage

Prepare a configuration file

Provide server endpoint, wallet address and private key in config.yaml:

endpoint: ""
wallet_address: ""
private_key: ""

You can use an existing wallet account, or generate a new account by running:

go run tools/generate_wallet_account.go
Create an instance of Client

After reading the configuration file, create an instance of Client

package main

import (
	"os"
	
	sdnclient "github.com/sending-network/sendingnetwork-bot"
	"gopkg.in/yaml.v3"
)

func main() {
    configData, _ := os.ReadFile("config.yaml")
    config := sdnclient.Config{}
    _ = yaml.Unmarshal(configData, &config)
    cli, _ := sdnclient.NewClient(&config)
}
Call API functions
// create new room
respCreateRoom, _ := cli.CreateRoom(&sdnclient.ReqCreateRoom{
	Name:   "TestRoom",
})

// invite user to the room
respInviteUser, _ := cli.InviteUser(respCreateRoom.RoomID, &sdnclient.ReqInviteUser{
    UserID: userID,
})

// logout to invalidate access token
respLogout, _ := cli.Logout()

Examples

See more use cases in examples directory.

License

Apache 2.0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetDIDList

func GetDIDList(ctx context.Context, hostname, address string) ([]string, error)

func Login

func Login(endpoint, address string, privateKey *ecdsa.PrivateKey) (accessToken, userID string, err error)

Login client login

func SaveDID

func SaveDID(ctx context.Context, hostname, did, signature, operation, address, updated string) error

Types

type ChildRoomInfo added in v0.1.2

type ChildRoomInfo struct {
	RoomID string `json:"room_id"`
	Name   string `json:"name"`
}

type Client

type Client struct {
	UserID        string
	AccessToken   string
	Endpoint      string
	WalletAddress string
	PrivateKey    *ecdsa.PrivateKey

	PathPrefix string
	Syncer     Syncer
	Store      Storer
	// contains filtered or unexported fields
}

Client represents a SDN client

func NewClient

func NewClient(config *Config) (*Client, error)

NewClient create a new SDN client with the given configuration

func (*Client) BuildURL

func (cli *Client) BuildURL(urlPath ...string) string

BuildURL builds a URL to send request to

func (*Client) BuildURLWithQuery added in v0.1.2

func (cli *Client) BuildURLWithQuery(urlPath []string, urlQuery map[string]string) string

BuildURLWithQuery builds a URL with query parameters

func (*Client) CreateFilter added in v0.1.2

func (cli *Client) CreateFilter(filter json.RawMessage) (resp *RespCreateFilter, err error)

CreateFilter .

func (*Client) CreateRoom

func (cli *Client) CreateRoom(req *ReqCreateRoom) (resp *RespCreateRoom, err error)

CreateRoom creates a new SDN room

func (*Client) GetAvatarURL

func (cli *Client) GetAvatarURL() (avatarUrl string, err error)

GetAvatarURL gets the client's avatar URL.

func (*Client) GetDisplayName

func (cli *Client) GetDisplayName() (resp *RespUserDisplayName, err error)

GetDisplayName returns the client's display name.

func (*Client) GetJoinedRooms added in v0.1.2

func (cli *Client) GetJoinedRooms() (resp *RespJoinedRooms, err error)

GetJoinedRooms GetJoinedRooms

func (*Client) GetRoomsInSquad added in v0.1.2

func (cli *Client) GetRoomsInSquad(squadID string) (resp []ChildRoomInfo, err error)

GetRoomsInSquad .

func (*Client) GetStateEvent added in v0.1.2

func (cli *Client) GetStateEvent(roomID, eventType, stateKey string) (resp map[string]interface{}, err error)

GetStateEvent get a state event from a room.

func (*Client) InviteUser

func (cli *Client) InviteUser(roomID string, req *ReqInviteUser) (resp *RespInviteUser, err error)

InviteUser invites a user to a room

func (*Client) JoinRoom

func (cli *Client) JoinRoom(roomIDorAlias string) (resp *RespJoinRoom, err error)

JoinRoom joins the client to a room ID or alias

func (*Client) JoinedMembers

func (cli *Client) JoinedMembers(roomID string) (resp *RespJoinedMembers, err error)

JoinedMembers returns a map of joined room members

func (*Client) KickUser

func (cli *Client) KickUser(roomID string, req *ReqKickUser) (resp *RespKickUser, err error)

KickUser kicks a user from a room

func (*Client) LeaveRoom

func (cli *Client) LeaveRoom(roomID string) (resp *RespLeaveRoom, err error)

LeaveRoom leaves the given room

func (*Client) Logout

func (cli *Client) Logout() (resp *RespLogout, err error)

Logout the current user.

func (*Client) MakeRequest

func (cli *Client) MakeRequest(method string, httpURL string, reqBody interface{}, resBody interface{}) error

MakeRequest makes a JSON HTTP request to the given URL

func (*Client) PutRoomInSquad added in v0.1.2

func (cli *Client) PutRoomInSquad(squadID, roomID string, reqBody json.RawMessage) (resp *RespSendEvent, err error)

PutRoomInSquad .

func (*Client) SendFormattedText added in v0.1.2

func (cli *Client) SendFormattedText(roomID, text, formattedText string) (*RespSendEvent, error)

SendFormattedText sends an m.room.message event into the given room with a msgtype of m.text, supports a subset of HTML for formatting.

func (*Client) SendImage added in v0.1.2

func (cli *Client) SendImage(roomID, body, url string) (*RespSendEvent, error)

SendImage sends an m.room.message event into the given room with a msgtype of m.image

func (*Client) SendMessageEvent added in v0.1.2

func (cli *Client) SendMessageEvent(roomID string, eventType string, contentJSON interface{}) (resp *RespSendEvent, err error)

SendMessageEvent sends a message event into a room. contentJSON should be a pointer to something that can be encoded as JSON using json.Marshal.

func (*Client) SendNotice added in v0.1.2

func (cli *Client) SendNotice(roomID, text string) (*RespSendEvent, error)

SendNotice sends an m.room.message event into the given room with a msgtype of m.notice

func (*Client) SendStateEvent

func (cli *Client) SendStateEvent(roomID, eventType, stateKey string, contentJSON interface{}) (resp *RespSendEvent, err error)

SendStateEvent sends a state event into a room. contentJSON should be a pointer to something that can be encoded as JSON using json.Marshal.

func (*Client) SendText added in v0.1.2

func (cli *Client) SendText(roomID, text string) (*RespSendEvent, error)

SendText sends an m.room.message event into the given room with a msgtype of m.text

func (*Client) SendVideo added in v0.1.2

func (cli *Client) SendVideo(roomID, body, url string) (*RespSendEvent, error)

SendVideo sends an m.room.message event into the given room with a msgtype of m.video

func (*Client) SetAvatarURL

func (cli *Client) SetAvatarURL(url string) (err error)

SetAvatarURL sets the client's avatar URL.

func (*Client) SetDisplayName

func (cli *Client) SetDisplayName(displayName string) (err error)

SetDisplayName sets the client's profile display name.

func (*Client) StopSync added in v0.1.2

func (cli *Client) StopSync()

StopSync stops the ongoing sync started by Sync.

func (*Client) Sync added in v0.1.2

func (cli *Client) Sync() error

Sync starts syncing with the provided server. If Sync() is called twice then the first sync will be stopped and the error will be nil.

This function will block until a fatal /sync error occurs, so it should almost always be started as a new goroutine. Fatal sync errors can be caused by:

  • The failure to create a filter.
  • Client.Syncer.OnFailedSync returning an error in response to a failed sync.
  • Client.Syncer.ProcessResponse returning an error.

If you wish to continue retrying in spite of these fatal errors, call Sync() again.

func (*Client) SyncRequest added in v0.1.2

func (cli *Client) SyncRequest(timeout int, since, filterID string, fullState bool, setPresence string) (resp *RespSync, err error)

SyncRequest makes an sync request

type Config

type Config struct {
	Endpoint      string `yaml:"endpoint"`
	WalletAddress string `yaml:"wallet_address"`
	PrivateKey    string `yaml:"private_key"`
	UserID        string `yaml:"user_id"`
	AccessToken   string `yaml:"access_token"`
}

Config represents a configuration for client

type CreateDIDResponse

type CreateDIDResponse struct {
	DID     string `json:"did"`
	Message string `json:"message"`
	Updated string `json:"updated"`
}

func CreateDID

func CreateDID(ctx context.Context, hostname, address string) (*CreateDIDResponse, error)

type DIDListResponse

type DIDListResponse struct {
	Data []string `json:"data"`
}

type DIDLoginRequest

type DIDLoginRequest struct {
	Type         string          `json:"type"`
	RandomServer string          `json:"random_server"`
	Updated      string          `json:"updated"`
	Identifier   LoginIdentifier `json:"identifier"`
	DeviceId     string          `json:"device_id"`
}

type DIDLoginResponse

type DIDLoginResponse struct {
	AccessToken string `json:"access_token"`
	UserId      string `json:"user_id"`
	DeviceId    string `json:"device_id"`
}

func DIDLogin

func DIDLogin(ctx context.Context, hostname, address string, preLoginResp *PreLoginResponse, token, deviceId string) (*DIDLoginResponse, error)

type DefaultSyncer added in v0.1.2

type DefaultSyncer struct {
	UserID string
	Store  Storer
	// contains filtered or unexported fields
}

DefaultSyncer is the default syncing implementation. You can either write your own syncer, or selectively replace parts of this default syncer (e.g. the ProcessResponse method). The default syncer uses the observer pattern to notify callers about incoming events. See DefaultSyncer.OnEventType for more information.

func NewDefaultSyncer added in v0.1.2

func NewDefaultSyncer(userID string, store Storer) *DefaultSyncer

NewDefaultSyncer returns an instantiated DefaultSyncer

func (*DefaultSyncer) GetFilterJSON added in v0.1.2

func (s *DefaultSyncer) GetFilterJSON(userID string) json.RawMessage

GetFilterJSON returns a filter with a timeline limit of 50.

func (*DefaultSyncer) OnEventType added in v0.1.2

func (s *DefaultSyncer) OnEventType(eventType string, callback OnEventListener)

OnEventType allows callers to be notified when there are new events for the given event type. There are no duplicate checks.

func (*DefaultSyncer) OnFailedSync added in v0.1.2

func (s *DefaultSyncer) OnFailedSync(res *RespSync, err error) (time.Duration, error)

OnFailedSync always returns a 10 second wait period between failed /syncs, never a fatal error.

func (*DefaultSyncer) ProcessResponse added in v0.1.2

func (s *DefaultSyncer) ProcessResponse(res *RespSync, since string) (err error)

ProcessResponse processes the /sync response in a way suitable for bots. "Suitable for bots" means a stream of unrepeating events. Returns a fatal error if a listener panics.

type Event

type Event struct {
	StateKey    *string                `json:"state_key,omitempty"`    // The state key for the event. Only present on State Events.
	Sender      string                 `json:"sender"`                 // The user ID of the sender of the event
	Type        string                 `json:"type"`                   // The event type
	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
	RoomID      string                 `json:"room_id"`                // The room the event was sent to. May be nil (e.g. for presence)
	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.
}

Event represents a single SDN event

func (*Event) Body

func (event *Event) Body() (body string, ok bool)

Body returns the value of the "body" key in the event content if it is present and is a string.

func (*Event) MessageType

func (event *Event) MessageType() (msgtype string, ok bool)

MessageType returns the value of the "msgtype" key in the event content if it is present and is a string.

type HTTPError

type HTTPError struct {
	Contents     []byte
	WrappedError error
	Message      string
	Code         int
}

HTTPError An HTTP Error response, which may wrap an underlying native Go Error.

func (HTTPError) Error

func (e HTTPError) Error() string

type ImageInfo added in v0.1.2

type ImageInfo struct {
	Height        uint          `json:"h,omitempty"`
	Width         uint          `json:"w,omitempty"`
	Mimetype      string        `json:"mimetype,omitempty"`
	Size          uint          `json:"size,omitempty"`
	ThumbnailInfo ThumbnailInfo `json:"thumbnail_info,omitempty"`
	ThumbnailURL  string        `json:"thumbnail_url,omitempty"`
}

ImageInfo contains info about an image

type ImageMessage added in v0.1.2

type ImageMessage struct {
	MsgType string    `json:"msgtype"`
	Body    string    `json:"body"`
	URL     string    `json:"url"`
	Info    ImageInfo `json:"info"`
}

ImageMessage is an m.image event

type InMemoryStore added in v0.1.2

type InMemoryStore struct {
	Filters   map[string]string
	NextBatch map[string]string
	Rooms     map[string]*Room
}

InMemoryStore implements the Storer interface.

Everything is persisted in-memory as maps. It is not safe to load/save filter IDs or next batch tokens on any goroutine other than the syncing goroutine: the one which called Client.Sync().

func NewInMemoryStore added in v0.1.2

func NewInMemoryStore() *InMemoryStore

NewInMemoryStore constructs a new InMemoryStore.

func (*InMemoryStore) LoadFilterID added in v0.1.2

func (s *InMemoryStore) LoadFilterID(userID string) string

LoadFilterID from memory.

func (*InMemoryStore) LoadNextBatch added in v0.1.2

func (s *InMemoryStore) LoadNextBatch(userID string) string

LoadNextBatch from memory.

func (*InMemoryStore) LoadRoom added in v0.1.2

func (s *InMemoryStore) LoadRoom(roomID string) *Room

LoadRoom from memory.

func (*InMemoryStore) SaveFilterID added in v0.1.2

func (s *InMemoryStore) SaveFilterID(userID, filterID string)

SaveFilterID to memory.

func (*InMemoryStore) SaveNextBatch added in v0.1.2

func (s *InMemoryStore) SaveNextBatch(userID, nextBatchToken string)

SaveNextBatch to memory.

func (*InMemoryStore) SaveRoom added in v0.1.2

func (s *InMemoryStore) SaveRoom(room *Room)

SaveRoom to memory.

type LoginIdentifier

type LoginIdentifier struct {
	DID     string `json:"did"`
	Address string `json:"address"`
	Message string `json:"message"`
	Token   string `json:"token"`
}

type OnEventListener added in v0.1.2

type OnEventListener func(*Event)

OnEventListener can be used with DefaultSyncer.OnEventType to be informed of incoming events.

type PreLoginResponse

type PreLoginResponse struct {
	DID          string `json:"did"`
	Message      string `json:"message"`
	RandomServer string `json:"random_server"`
	Updated      string `json:"updated"`
}

func PreLogin

func PreLogin(ctx context.Context, hostname, address, did string) (*PreLoginResponse, error)

type PublicRoom added in v0.1.2

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"`
}

PublicRoom represents the information about a public room obtainable from the room directory

type ReqCreateRoom

type ReqCreateRoom struct {
	Name            string                 `json:"name,omitempty"`
	RoomAliasName   string                 `json:"room_alias_name,omitempty"`
	Topic           string                 `json:"topic,omitempty"`
	Invite          []string               `json:"invite,omitempty"`
	CreationContent map[string]interface{} `json:"creation_content,omitempty"`
	InitialState    []Event                `json:"initial_state,omitempty"`
	Preset          string                 `json:"preset,omitempty"`
	Visibility      string                 `json:"visibility,omitempty"`
	IsDirect        bool                   `json:"is_direct,omitempty"`
	RoomVersion     string                 `json:"room_version,omitempty"`
}

ReqCreateRoom is the JSON request for create room

type ReqInvite3PID

type ReqInvite3PID struct {
	IDServer string `json:"id_server"`
	Medium   string `json:"medium"`
	Address  string `json:"address"`
}

ReqInvite3PID is the JSON request invite 3pid

type ReqInviteUser

type ReqInviteUser struct {
	UserID string `json:"user_id"`
}

ReqInviteUser is the JSON request for invite user

type ReqKickUser

type ReqKickUser struct {
	Reason string `json:"reason,omitempty"`
	UserID string `json:"user_id"`
}

ReqKickUser is the JSON request for kick user

type RespCreateFilter added in v0.1.2

type RespCreateFilter struct {
	FilterID string `json:"filter_id"`
}

type RespCreateRoom

type RespCreateRoom struct {
	RoomID string `json:"room_id"`
}

RespCreateRoom is the JSON response for CreateRoom

type RespError

type RespError struct {
	ErrCode string `json:"errcode"`
	Err     string `json:"error"`
}

RespError is the standard JSON error response from SDN node servers

func (RespError) Error

func (e RespError) Error() string

Error returns the errcode and error message.

type RespInviteUser

type RespInviteUser struct{}

RespInviteUser is the JSON response for InviteUser

type RespJoinRoom

type RespJoinRoom struct {
	RoomID string `json:"room_id"`
}

RespJoinRoom is the JSON response for JoinRoom

type RespJoinedMembers

type RespJoinedMembers struct {
	Joined map[string]struct {
		DisplayName string `json:"display_name"`
		AvatarURL   string `json:"avatar_url"`
	} `json:"joined"`
}

RespJoinedMembers is the JSON response for JoinedMembers

type RespJoinedRooms

type RespJoinedRooms struct {
	JoinedRooms []string `json:"joined_rooms"`
}

RespJoinedRooms is the JSON response for JoinedRooms

type RespKickUser

type RespKickUser struct{}

RespKickUser is the JSON response for KickUser

type RespLeaveRoom

type RespLeaveRoom struct{}

RespLeaveRoom is the JSON response for LeaveRoom

type RespLogout

type RespLogout struct{}

RespLogout is the JSON response for Logout

type RespSendEvent

type RespSendEvent struct {
	EventID string `json:"event_id"`
}

RespSendEvent is the JSON response for SendEvent

type RespSync added in v0.1.2

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 {
		Leave 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:"leave"`
		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"`
			Ephemeral struct {
				Events []Event `json:"events"`
			} `json:"ephemeral"`
		} `json:"join"`
		Invite map[string]struct {
			State struct {
				Events []Event
			} `json:"invite_state"`
		} `json:"invite"`
	} `json:"rooms"`
}

RespSync is the JSON response for sync

type RespUserDisplayName

type RespUserDisplayName struct {
	DisplayName string `json:"displayname"`
}

RespUserDisplayName is the JSON response for GetDisplayName

type Room added in v0.1.2

type Room struct {
	ID    string
	State map[string]map[string]*Event
}

Room represents a single room.

func NewRoom added in v0.1.2

func NewRoom(roomID string) *Room

NewRoom creates a new Room with the given ID

func (Room) GetMembershipState added in v0.1.2

func (room Room) GetMembershipState(userID string) string

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) GetStateEvent added in v0.1.2

func (room Room) GetStateEvent(eventType string, stateKey string) *Event

GetStateEvent returns the state event for the given type/state_key combo, or nil.

func (Room) UpdateState added in v0.1.2

func (room Room) UpdateState(event *Event)

UpdateState updates the room's current state with the given Event. This will clobber events based on the type/state_key combination.

type Storer added in v0.1.2

type Storer interface {
	SaveFilterID(userID, filterID string)
	LoadFilterID(userID string) string
	SaveNextBatch(userID, nextBatchToken string)
	LoadNextBatch(userID string) string
	SaveRoom(room *Room)
	LoadRoom(roomID string) *Room
}

Storer is an interface which must be satisfied to store client data.

You can either write a struct which persists this data to disk, or you can use the provided "InMemoryStore" which just keeps data around in-memory which is lost on restarts.

type Syncer added in v0.1.2

type Syncer interface {
	// ProcessResponse Process the /sync response. The since parameter is the since= value that was used to produce the response.
	// This is useful for detecting the very first sync (since=""). If an error is return, Syncing will be stopped permanently.
	ProcessResponse(resp *RespSync, since string) error
	// OnFailedSync returns either the time to wait before retrying or an error to stop syncing permanently.
	OnFailedSync(res *RespSync, err error) (time.Duration, error)
	// GetFilterJSON for the given user ID. NOT the filter ID.
	GetFilterJSON(userID string) json.RawMessage
}

Syncer represents an interface that must be satisfied in order to do /sync requests on a client.

type TextMessage added in v0.1.2

type TextMessage struct {
	MsgType       string `json:"msgtype"`
	Body          string `json:"body"`
	FormattedBody string `json:"formatted_body"`
	Format        string `json:"format"`
}

TextMessage is the contents of a formatted message event.

type ThumbnailInfo added in v0.1.2

type ThumbnailInfo struct {
	Height   uint   `json:"h,omitempty"`
	Width    uint   `json:"w,omitempty"`
	Mimetype string `json:"mimetype,omitempty"`
	Size     uint   `json:"size,omitempty"`
}

type VideoInfo added in v0.1.2

type VideoInfo struct {
	Mimetype      string        `json:"mimetype,omitempty"`
	ThumbnailInfo ThumbnailInfo `json:"thumbnail_info"`
	ThumbnailURL  string        `json:"thumbnail_url,omitempty"`
	Height        uint          `json:"h,omitempty"`
	Width         uint          `json:"w,omitempty"`
	Duration      uint          `json:"duration,omitempty"`
	Size          uint          `json:"size,omitempty"`
}

VideoInfo contains info about a video

type VideoMessage added in v0.1.2

type VideoMessage struct {
	MsgType string    `json:"msgtype"`
	Body    string    `json:"body"`
	URL     string    `json:"url"`
	Info    VideoInfo `json:"info"`
}

VideoMessage is an m.video

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL