aboutsummaryrefslogtreecommitdiff
path: root/connector/mattermost
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2020-02-21 18:08:40 +0100
committerAlex Auvolat <alex@adnab.me>2020-02-21 18:08:40 +0100
commitfd768a10be36ec31f674fa291fcbe77b78a2855c (patch)
treebb9e736bfc9425e1ce5ee22379e8d46470af4d18 /connector/mattermost
parentddd5936fb1f92432123a9a30d1d3a1fa644a4f8e (diff)
downloadeasybridge-fd768a10be36ec31f674fa291fcbe77b78a2855c.tar.gz
easybridge-fd768a10be36ec31f674fa291fcbe77b78a2855c.zip
Mattermost media objects in both ways + user/team profile pictures from MM to Matrix
Diffstat (limited to 'connector/mattermost')
-rw-r--r--connector/mattermost/mattermost.go146
1 files changed, 116 insertions, 30 deletions
diff --git a/connector/mattermost/mattermost.go b/connector/mattermost/mattermost.go
index 330026a..73ea66b 100644
--- a/connector/mattermost/mattermost.go
+++ b/connector/mattermost/mattermost.go
@@ -1,10 +1,12 @@
package mattermost
import (
+ "net/http"
"fmt"
_ "os"
"strings"
"time"
+ "io/ioutil"
"encoding/json"
"github.com/mattermost/mattermost-server/model"
@@ -210,9 +212,6 @@ func (mm *Mattermost) Leave(roomId RoomID) {
}
func (mm *Mattermost) Send(event *Event) error {
- // TODO: attachements
- // TODO: verify private messages work
-
post := &model.Post{
Message: event.Text,
}
@@ -248,8 +247,30 @@ func (mm *Mattermost) Send(event *Event) error {
return fmt.Errorf("Invalid target")
}
+ if event.Attachments != nil {
+ post.FileIds = []string{}
+ for _, file := range event.Attachments {
+ rdr, err := file.Read()
+ if err != nil {
+ return err
+ }
+ defer rdr.Close()
+ data, err := ioutil.ReadAll(rdr)
+ if err != nil {
+ return err
+ }
+ up_file, err := mm.conn.UploadFile(data, post.ChannelId, file.Filename())
+ if err != nil {
+ log.Warnf("UploadFile error: %s", err)
+ return err
+ }
+ post.FileIds = append(post.FileIds, up_file)
+ }
+ }
+
_, resp := mm.conn.Client.CreatePost(post)
if resp.Error != nil {
+ log.Warnf("CreatePost error: %s", resp.Error)
return resp.Error
}
return nil
@@ -277,16 +298,58 @@ func (mm *Mattermost) handleConnected() {
if len(strings.Split(ch.Name, "__")) == 2 {
continue // This is a DM channel
}
+
id := mm.reverseRoomId(ch.Id)
- chName := ch.DisplayName
- if teamName := mm.conn.GetTeamName(ch.TeamId); teamName != "" {
- chName = teamName + " / " + chName
- }
mm.handler.Joined(id)
- mm.handler.RoomInfoUpdated(id, UserID(""), &RoomInfo{
- Name: chName,
+
+ // Update room info
+ room_info := &RoomInfo{
+ Name: ch.DisplayName,
Topic: ch.Header,
- })
+ }
+ for _, t := range mm.conn.OtherTeams {
+ if t.Id == ch.TeamId {
+ if t.Team.DisplayName != "" {
+ room_info.Name = t.Team.DisplayName + " / " + room_info.Name
+ } else {
+ room_info.Name = t.Team.Name + " / " + room_info.Name
+ }
+ // TODO: cache last update time so we don't do this needlessly
+ if t.Team.LastTeamIconUpdate > 0 {
+ team_img, resp := mm.conn.Client.GetTeamIcon(t.Id, "")
+ if resp.Error == nil {
+ room_info.Picture = &BlobMediaObject{
+ ObjectFilename: t.Team.Name,
+ ObjectMimetype: http.DetectContentType(team_img),
+ ObjectData: team_img,
+ }
+ } else {
+ log.Warnf("Could not get team image: %s", resp.Error)
+ }
+ }
+ break
+ }
+ }
+ mm.handler.RoomInfoUpdated(id, UserID(""), room_info)
+
+ // Update member list
+ members, resp := mm.conn.Client.GetChannelMembers(ch.Id, 0, 1000, "")
+ if resp.Error == nil {
+ for _, mem := range *members {
+ if mem.UserId == mm.conn.User.Id {
+ continue
+ }
+ user := mm.conn.GetUser(mem.UserId)
+ if user != nil {
+ mm.ensureJoined(user, id)
+ mm.updateUserInfo(user)
+ } else {
+ log.Warnf("Could not find joined user: %s", mem.UserId)
+ }
+ }
+ } else {
+ log.Warnf("Could not get channel members: %s", resp.Error)
+ }
}
}
@@ -306,6 +369,45 @@ func (mm *Mattermost) handleLoop(msgCh chan *matterclient.Message, quitCh chan b
}
}
+func (mm *Mattermost) updateUserInfo(user *model.User) {
+ userId := UserID(fmt.Sprintf("%s@%s", user.Username, mm.server))
+ userDisp := user.GetDisplayName(model.SHOW_NICKNAME_FULLNAME)
+
+ if lastdn, ok := mm.userdisplaynamemap[userId]; !ok || lastdn != userDisp {
+ ui := &UserInfo{
+ DisplayName: userDisp,
+ }
+ if user.LastPictureUpdate > 0 {
+ // TODO: cache last update time so we don't do this needlessly
+ img, resp := mm.conn.Client.GetProfileImage(user.Id, "")
+ if resp.Error == nil {
+ ui.Avatar = &BlobMediaObject{
+ ObjectFilename: user.Username,
+ ObjectMimetype: http.DetectContentType(img),
+ ObjectData: img,
+ }
+ } else {
+ log.Warnf("Could not get profile picture: %s", resp.Error)
+ }
+ mm.handler.UserInfoUpdated(userId, ui)
+ mm.userdisplaynamemap[userId] = userDisp
+ }
+ }
+}
+
+func (mm *Mattermost) ensureJoined(user *model.User, roomId RoomID) {
+ userId := UserID(fmt.Sprintf("%s@%s", user.Username, mm.server))
+ cache_key := fmt.Sprintf("%s / %s", userId, roomId)
+ if _, ok := mm.sentjoinedmap[cache_key]; !ok {
+ mm.handler.Event(&Event{
+ Author: userId,
+ Room: roomId,
+ Type: EVENT_JOIN,
+ })
+ mm.sentjoinedmap[cache_key] = true
+ }
+}
+
func (mm *Mattermost) handlePosted(msg *model.WebSocketEvent) error {
channel_name := msg.Data["channel_name"].(string)
post_str := msg.Data["post"].(string)
@@ -326,14 +428,7 @@ func (mm *Mattermost) handlePosted(msg *model.WebSocketEvent) error {
return fmt.Errorf("Invalid user")
}
userId := UserID(fmt.Sprintf("%s@%s", user.Username, mm.server))
-
- userDisp := user.GetDisplayName(model.SHOW_NICKNAME_FULLNAME)
- if lastdn, ok := mm.userdisplaynamemap[userId]; !ok || lastdn != userDisp {
- mm.handler.UserInfoUpdated(userId, &UserInfo{
- DisplayName: userDisp,
- })
- mm.userdisplaynamemap[userId] = userDisp
- }
+ mm.updateUserInfo(user)
// Build message event
msg_ev := &Event{
@@ -347,7 +442,7 @@ func (mm *Mattermost) handlePosted(msg *model.WebSocketEvent) error {
// Handle files
if post.FileIds != nil && len(post.FileIds) > 0 {
- msg_ev.Attachements = []MediaObject{}
+ msg_ev.Attachments = []MediaObject{}
for _, file := range post.Metadata.Files {
blob, resp := mm.conn.Client.GetFile(file.Id)
if resp.Error != nil {
@@ -355,7 +450,6 @@ func (mm *Mattermost) handlePosted(msg *model.WebSocketEvent) error {
}
media_object := &BlobMediaObject{
ObjectFilename: file.Name,
- ObjectSize: file.Size,
ObjectMimetype: file.MimeType,
ObjectData: blob,
}
@@ -365,7 +459,7 @@ func (mm *Mattermost) handlePosted(msg *model.WebSocketEvent) error {
Height: file.Height,
}
}
- msg_ev.Attachements = append(msg_ev.Attachements, media_object)
+ msg_ev.Attachments = append(msg_ev.Attachments, media_object)
}
}
@@ -384,15 +478,7 @@ func (mm *Mattermost) handlePosted(msg *model.WebSocketEvent) error {
return fmt.Errorf("Invalid channel id")
}
- cache_key := fmt.Sprintf("%s / %s", userId, roomId)
- if _, ok := mm.sentjoinedmap[cache_key]; !ok {
- mm.handler.Event(&Event{
- Author: userId,
- Room: roomId,
- Type: EVENT_JOIN,
- })
- mm.sentjoinedmap[cache_key] = true
- }
+ mm.ensureJoined(user, roomId)
if post.Type == "system_header_change" {
new_header := post.Props["new_header"].(string)