Files&images Mattermost->Matrix works
This commit is contained in:
parent
92d380aa86
commit
ddd5936fb1
9 changed files with 198 additions and 12 deletions
|
@ -249,6 +249,43 @@ func (a *Account) eventInternal(event *Event) error {
|
|||
typ = "m.emote"
|
||||
}
|
||||
|
||||
return mx.SendMessageAs(mx_room_id, typ, event.Text, mx_user_id)
|
||||
err = mx.SendMessageAs(mx_room_id, typ, event.Text, mx_user_id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if event.Attachements != nil {
|
||||
for _, file := range event.Attachements {
|
||||
mxfile, err := mx.UploadMedia(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
content := map[string]interface{} {
|
||||
"body": mxfile.Filename(),
|
||||
"filename": mxfile.Filename(),
|
||||
"url": fmt.Sprintf("mxc://%s/%s", mxfile.MxcServer, mxfile.MxcMediaId),
|
||||
}
|
||||
if sz := mxfile.ImageSize(); sz != nil {
|
||||
content["msgtype"] = "m.image"
|
||||
content["info"] = map[string]interface{} {
|
||||
"mimetype": mxfile.Mimetype(),
|
||||
"size": mxfile.Size(),
|
||||
"width": sz.Width,
|
||||
"height": sz.Height,
|
||||
}
|
||||
} else {
|
||||
content["msgtype"] = "m.file"
|
||||
content["info"] = map[string]interface{} {
|
||||
"mimetype": mxfile.Mimetype(),
|
||||
"size": mxfile.Size(),
|
||||
}
|
||||
}
|
||||
err = mx.SendAs(mx_room_id, "m.room.message", content, mx_user_id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,15 +41,18 @@ func Start(r *mxlib.Registration, c *Config) (chan error, error) {
|
|||
if mxe, ok := err.(*mxlib.MxError); !ok || mxe.ErrCode != "M_USER_IN_USE" {
|
||||
return nil, err
|
||||
}
|
||||
err = mx.ProfileDisplayname(ezbrMxId(), fmt.Sprintf("Easybridge (%s)", EASYBRIDGE_SYSTEM_PROTOCOL))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = mx.ProfileAvatar(ezbrMxId(), &connector.FileMediaObject{
|
||||
Path: "easybridge.jpg",
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if err == nil {
|
||||
// If Easybridge account was created, update avatar and display name
|
||||
err = mx.ProfileAvatar(ezbrMxId(), &connector.FileMediaObject{
|
||||
Path: "easybridge.jpg",
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = mx.ProfileDisplayname(ezbrMxId(), fmt.Sprintf("Easybridge (%s)", EASYBRIDGE_SYSTEM_PROTOCOL))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
router := mux.NewRouter()
|
||||
|
|
|
@ -115,7 +115,7 @@ type Event struct {
|
|||
Text string
|
||||
|
||||
// Attached files such as images
|
||||
Attachements map[string]MediaObject
|
||||
Attachements []MediaObject
|
||||
}
|
||||
|
||||
type UserInfo struct {
|
||||
|
@ -134,6 +134,9 @@ type MediaObject interface {
|
|||
Size() int64
|
||||
Mimetype() string
|
||||
|
||||
// Returns the size of an image if it is an image, otherwise nil
|
||||
ImageSize() *ImageSize
|
||||
|
||||
// Read: must always be implemented
|
||||
Read() (io.ReadCloser, error)
|
||||
|
||||
|
@ -141,3 +144,8 @@ type MediaObject interface {
|
|||
// If so, Read() is the only way to retrieve the object
|
||||
URL() string
|
||||
}
|
||||
|
||||
type ImageSize struct {
|
||||
Width int
|
||||
Height int
|
||||
}
|
||||
|
|
|
@ -345,6 +345,30 @@ func (mm *Mattermost) handlePosted(msg *model.WebSocketEvent) error {
|
|||
msg_ev.Type = EVENT_ACTION
|
||||
}
|
||||
|
||||
// Handle files
|
||||
if post.FileIds != nil && len(post.FileIds) > 0 {
|
||||
msg_ev.Attachements = []MediaObject{}
|
||||
for _, file := range post.Metadata.Files {
|
||||
blob, resp := mm.conn.Client.GetFile(file.Id)
|
||||
if resp.Error != nil {
|
||||
return resp.Error
|
||||
}
|
||||
media_object := &BlobMediaObject{
|
||||
ObjectFilename: file.Name,
|
||||
ObjectSize: file.Size,
|
||||
ObjectMimetype: file.MimeType,
|
||||
ObjectData: blob,
|
||||
}
|
||||
if file.Width > 0 {
|
||||
media_object.ObjectImageSize = &ImageSize{
|
||||
Width: file.Width,
|
||||
Height: file.Height,
|
||||
}
|
||||
}
|
||||
msg_ev.Attachements = append(msg_ev.Attachements, media_object)
|
||||
}
|
||||
}
|
||||
|
||||
// Dispatch as PM or as room message
|
||||
if len(strings.Split(channel_name, "__")) == 2 {
|
||||
// Private message, no need to find room id
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package connector
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
|
@ -41,6 +42,11 @@ func (m *FileMediaObject) Mimetype() string {
|
|||
return http.DetectContentType(buffer)
|
||||
}
|
||||
|
||||
func (m *FileMediaObject) ImageSize() *ImageSize {
|
||||
// TODO but not really usefull
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *FileMediaObject) Read() (io.ReadCloser, error) {
|
||||
return os.Open(m.Path)
|
||||
}
|
||||
|
@ -48,3 +54,82 @@ func (m *FileMediaObject) Read() (io.ReadCloser, error) {
|
|||
func (m *FileMediaObject) URL() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// ----
|
||||
|
||||
type UrlMediaObject struct {
|
||||
ObjectFilename string
|
||||
ObjectSize int64
|
||||
ObjectMimetype string
|
||||
ObjectURL string
|
||||
ObjectImageSize *ImageSize
|
||||
}
|
||||
|
||||
func (m *UrlMediaObject) Filename() string {
|
||||
return m.ObjectFilename
|
||||
}
|
||||
|
||||
func (m *UrlMediaObject) Size() int64 {
|
||||
return m.ObjectSize
|
||||
}
|
||||
|
||||
func (m *UrlMediaObject) Mimetype() string {
|
||||
return m.ObjectMimetype
|
||||
}
|
||||
|
||||
func (m *UrlMediaObject) ImageSize() *ImageSize {
|
||||
return m.ObjectImageSize
|
||||
}
|
||||
|
||||
func (m *UrlMediaObject) Read() (io.ReadCloser, error) {
|
||||
resp, err := http.Get(m.ObjectURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.Body, nil
|
||||
}
|
||||
|
||||
func (m *UrlMediaObject) URL() string {
|
||||
return m.ObjectURL
|
||||
}
|
||||
|
||||
// ----
|
||||
|
||||
type BlobMediaObject struct {
|
||||
ObjectFilename string
|
||||
ObjectSize int64
|
||||
ObjectMimetype string
|
||||
ObjectImageSize *ImageSize
|
||||
ObjectData []byte
|
||||
}
|
||||
|
||||
func (m *BlobMediaObject) Filename() string {
|
||||
return m.ObjectFilename
|
||||
}
|
||||
|
||||
func (m *BlobMediaObject) Size() int64 {
|
||||
return m.ObjectSize
|
||||
}
|
||||
|
||||
func (m *BlobMediaObject) Mimetype() string {
|
||||
return m.ObjectMimetype
|
||||
}
|
||||
|
||||
func (m *BlobMediaObject) ImageSize() *ImageSize {
|
||||
return m.ObjectImageSize
|
||||
}
|
||||
|
||||
func (m *BlobMediaObject) Read() (io.ReadCloser, error) {
|
||||
return nullCloseReader{bytes.NewBuffer(m.ObjectData)}, nil
|
||||
}
|
||||
|
||||
func (m *BlobMediaObject) URL() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
type nullCloseReader struct {
|
||||
io.Reader
|
||||
}
|
||||
func (ncr nullCloseReader) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
|
6
go.mod
6
go.mod
|
@ -4,12 +4,16 @@ go 1.13
|
|||
|
||||
require (
|
||||
github.com/42wim/matterbridge v1.16.5
|
||||
github.com/blang/semver v3.5.1+incompatible // indirect
|
||||
github.com/dyatlov/go-opengraph v0.0.0-20180429202543-816b6608b3c8 // indirect
|
||||
github.com/go-ldap/ldap v3.0.3+incompatible // indirect
|
||||
github.com/gorilla/mux v1.7.4
|
||||
github.com/jinzhu/gorm v1.9.12
|
||||
github.com/lrstanley/girc v0.0.0-20190801035559-4fc93959e1a7
|
||||
github.com/matterbridge/go-xmpp v0.0.0-20180529212104-cd19799fba91
|
||||
github.com/mattermost/mattermost-server v5.5.0+incompatible
|
||||
github.com/mattermost/mattermost-server v5.11.1+incompatible
|
||||
github.com/mattn/go-xmpp v0.0.0-20200128155807-a86b6abcb3ad
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect
|
||||
gopkg.in/yaml.v2 v2.2.8
|
||||
)
|
||||
|
|
12
go.sum
12
go.sum
|
@ -20,6 +20,8 @@ github.com/alexcesaro/log v0.0.0-20150915221235-61e686294e58/go.mod h1:YNfsMyWSs
|
|||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
|
||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/bwmarrin/discordgo v0.20.2/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVOwN61zSZ0r4Q=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
|
@ -35,10 +37,14 @@ github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xb
|
|||
github.com/dfordsoft/golib v0.0.0-20180902042739-76ee6ab99bec/go.mod h1:UGa5M2Sz/Uh13AMse4+RELKCDw7kqgqlTjeGae+7vUY=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/dyatlov/go-opengraph v0.0.0-20180429202543-816b6608b3c8 h1:6muCmMJat6z7qptVrIf/+OWPxsjAfvhw5/6t+FwEkgg=
|
||||
github.com/dyatlov/go-opengraph v0.0.0-20180429202543-816b6608b3c8/go.mod h1:nYia/MIs9OyvXXYboPmNOj0gVWo97Wx0sde+ZuKkoM4=
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-ldap/ldap v3.0.3+incompatible h1:HTeSZO8hWMS1Rgb2Ziku6b8a7qRIZZMHjsvuZyatzwk=
|
||||
github.com/go-ldap/ldap v3.0.3+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
|
||||
|
@ -116,6 +122,8 @@ github.com/matterbridge/logrus-prefixed-formatter v0.0.0-20180806162718-01618749
|
|||
github.com/matterbridge/logrus-prefixed-formatter v0.0.0-20180806162718-01618749af61/go.mod h1:iXGEotOvwI1R1SjLxRc+BF5rUORTMtE0iMZBT2lxqAU=
|
||||
github.com/mattermost/mattermost-server v5.5.0+incompatible h1:0wcLGgYtd+YImtLDPf2AOfpBHxbU4suATx+6XKw1XbU=
|
||||
github.com/mattermost/mattermost-server v5.5.0+incompatible/go.mod h1:5L6MjAec+XXQwMIt791Ganu45GKsSiM+I0tLR9wUj8Y=
|
||||
github.com/mattermost/mattermost-server v5.11.1+incompatible h1:LPzKY0+2Tic/ik67qIg6VrydRCgxNXZQXOeaiJ2rMBY=
|
||||
github.com/mattermost/mattermost-server v5.11.1+incompatible/go.mod h1:5L6MjAec+XXQwMIt791Ganu45GKsSiM+I0tLR9wUj8Y=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
||||
|
@ -225,6 +233,7 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r
|
|||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -246,6 +255,7 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8 h1:JA8d3MPx/IToSyXZG/RhwYEtfrKO1Fxrqe8KrkiLXKM=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
@ -260,6 +270,8 @@ google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoA
|
|||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM=
|
||||
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
|
|
|
@ -280,6 +280,11 @@ func (mx *Client) RoomTopicAs(room string, topic string, as_user string) error {
|
|||
}
|
||||
|
||||
func (mx *Client) UploadMedia(m connector.MediaObject) (*MediaObject, error) {
|
||||
// Return early if this is already a Matrix media object
|
||||
if mxm, ok := m.(*MediaObject); ok {
|
||||
return mxm, nil
|
||||
}
|
||||
|
||||
reader, err := m.Read()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -308,6 +313,7 @@ func (mx *Client) UploadMedia(m connector.MediaObject) (*MediaObject, error) {
|
|||
filename: m.Filename(),
|
||||
size: m.Size(),
|
||||
mimetype: m.Mimetype(),
|
||||
imageSize: m.ImageSize(),
|
||||
MxcServer: mxc[0],
|
||||
MxcMediaId: mxc[1],
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
"fmt"
|
||||
"net/url"
|
||||
"net/http"
|
||||
|
||||
"git.deuxfleurs.fr/Deuxfleurs/easybridge/connector"
|
||||
)
|
||||
|
||||
type MediaObject struct {
|
||||
|
@ -12,6 +14,7 @@ type MediaObject struct {
|
|||
filename string
|
||||
size int64
|
||||
mimetype string
|
||||
imageSize *connector.ImageSize
|
||||
MxcServer string
|
||||
MxcMediaId string
|
||||
}
|
||||
|
@ -28,6 +31,10 @@ func (m *MediaObject) Mimetype() string {
|
|||
return m.mimetype
|
||||
}
|
||||
|
||||
func (m *MediaObject) ImageSize() *connector.ImageSize {
|
||||
return m.imageSize
|
||||
}
|
||||
|
||||
func (m *MediaObject) Read() (io.ReadCloser, error) {
|
||||
req, err := http.NewRequest("GET", m.URL(), nil)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in a new issue