diff --git a/client.go b/client.go index 8ff3247..8be359a 100644 --- a/client.go +++ b/client.go @@ -13,6 +13,7 @@ import ( "net/url" "path" "strconv" + "strings" "sync" "time" ) @@ -450,6 +451,20 @@ func (cli *Client) SendText(roomID, text string) (*RespSendEvent, error) { TextMessage{"m.text", text}) } +// SendFile sends an m.room.message event into the given room with a msgtype of m.file +// See https://matrix.org/docs/spec/client_server/r0.2.0.html#m-file +// FIXME add thumbnail support +func (cli *Client) SendFile(roomID, body, url, filename string, info FileInfo, thumbInfo, thumbURL interface{}) (*RespSendEvent, error) { + return cli.SendMessageEvent(roomID, "m.room.message", + FileMessage{ + MsgType: "m.file", + Body: body, + URL: url, + FileName: filename, + Info: info, + }) +} + // SendImage sends an m.room.message event into the given room with a msgtype of m.image // See https://matrix.org/docs/spec/client_server/r0.2.0.html#m-image func (cli *Client) SendImage(roomID, body, url string) (*RespSendEvent, error) { @@ -515,7 +530,7 @@ func (cli *Client) ForgetRoom(roomID string) (resp *RespForgetRoom, err error) { // 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) { u := cli.BuildURL("rooms", roomID, "invite") - _, err = cli.MakeRequest("POST", u, struct{}{}, &resp) + _, err = cli.MakeRequest("POST", u, req, &resp) return } @@ -576,6 +591,28 @@ func (cli *Client) UploadLink(link string) (*RespMediaUpload, error) { return cli.UploadToContentRepo(res.Body, res.Header.Get("Content-Type"), res.ContentLength) } +// Download download a mxc url. Used to get sent file/photos/etc from the matrix server +func (cli *Client) Download(url string) (string, []byte, error) { + path := strings.Replace(url, "mxc://", "", 1) + req, _ := http.NewRequest("GET", cli.BuildBaseURL("_matrix/media/r0/download/"+path), nil) + + res, err := cli.Client.Do(req) + if err != nil { + fmt.Println("Error while downloading", url, "-", err) + return "", nil, err + } + defer res.Body.Close() + + contents, err := ioutil.ReadAll(res.Body) + filename := res.Header["Content-Disposition"][0] + if err != nil { + fmt.Println("Error while downloading", url, "-", err) + return "", nil, err + } + + return filename, contents, err +} + // UploadToContentRepo uploads the given bytes to the content repository and returns an MXC URI. // See http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-media-r0-upload func (cli *Client) UploadToContentRepo(content io.Reader, contentType string, contentLength int64) (*RespMediaUpload, error) { diff --git a/events.go b/events.go index bc7b651..92c1d4d 100644 --- a/events.go +++ b/events.go @@ -10,7 +10,7 @@ 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 int `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 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. @@ -44,6 +44,12 @@ type TextMessage struct { Body string `json:"body"` } +// FileInfo contains info about an image - 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"` +} + // ImageInfo contains info about an image - http://matrix.org/docs/spec/client_server/r0.2.0.html#m-image type ImageInfo struct { Height uint `json:"h,omitempty"` @@ -71,6 +77,15 @@ type VideoMessage struct { Info VideoInfo `json:"info"` } +// FileMessage is an m.file event +type FileMessage struct { + MsgType string `json:"msgtype"` + Body string `json:"body"` + URL string `json:"url"` + FileName string `json:"filename"` + Info FileInfo `json:"info"` +} + // ImageMessage is an m.image event type ImageMessage struct { MsgType string `json:"msgtype"` diff --git a/responses.go b/responses.go index 1b9b066..2485da6 100644 --- a/responses.go +++ b/responses.go @@ -163,6 +163,7 @@ type RespSync struct { } `json:"rooms"` } +// RespTurnServer was written by someone else who later turned on the automatic commit checker so no-one could commit without writing this comment lol type RespTurnServer struct { Username string `json:"username"` Password string `json:"password"`