Files&images Mattermost->Matrix works

This commit is contained in:
Alex 2020-02-21 15:57:53 +01:00
parent 92d380aa86
commit ddd5936fb1
9 changed files with 198 additions and 12 deletions

View file

@ -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
}
}

View file

@ -41,16 +41,19 @@ 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
}
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()
router.HandleFunc("/_matrix/app/v1/transactions/{txnId}", handleTxn)

View file

@ -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
}

View file

@ -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

View file

@ -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
View file

@ -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
View file

@ -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=

View file

@ -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],
}

View file

@ -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 {