Thumbnail

rani/matterbridge.git

Clone URL: https://git.buni.party/rani/matterbridge.git

Viewing file on branch master

1package bmattermost
2
3import (
4 "context"
5
6 "github.com/matterbridge-org/matterbridge/bridge/config"
7 "github.com/matterbridge-org/matterbridge/bridge/helper"
8 "github.com/matterbridge/matterclient"
9 "github.com/mattermost/mattermost/server/public/model"
10)
11
12// handleDownloadAvatar downloads the avatar of userid from channel
13// sends a EVENT_AVATAR_DOWNLOAD message to the gateway if successful.
14// logs an error message if it fails
15func (b *Bmattermost) handleDownloadAvatar(userid string, channel string) {
16 rmsg := config.Message{
17 Username: "system",
18 Text: "avatar",
19 Channel: channel,
20 Account: b.Account,
21 UserID: userid,
22 Event: config.EventAvatarDownload,
23 Extra: make(map[string][]interface{}),
24 }
25 if _, ok := b.avatarMap[userid]; !ok {
26 var (
27 data []byte
28 err error
29 )
30 data, _, err = b.mc.Client.GetProfileImage(context.TODO(), userid, "")
31 if err != nil {
32 b.Log.Errorf("ProfileImage download failed for %#v %s", userid, err)
33 return
34 }
35
36 err = helper.HandleDownloadSize(b.Log, &rmsg, userid+".png", int64(len(data)), b.General)
37 if err != nil {
38 b.Log.Error(err)
39 return
40 }
41 helper.HandleDownloadData(b.Log, &rmsg, userid+".png", rmsg.Text, "", &data, b.General)
42 b.Remote <- rmsg
43 }
44}
45
46//nolint:wrapcheck
47func (b *Bmattermost) handleDownloadFile(rmsg *config.Message, id string) error {
48 url, _, _ := b.mc.Client.GetFileLink(context.TODO(), id)
49 finfo, _, err := b.mc.Client.GetFileInfo(context.TODO(), id)
50 if err != nil {
51 return err
52 }
53 err = helper.HandleDownloadSize(b.Log, rmsg, finfo.Name, finfo.Size, b.General)
54 if err != nil {
55 return err
56 }
57 data, _, err := b.mc.Client.DownloadFile(context.TODO(), id, true)
58 if err != nil {
59 return err
60 }
61 helper.HandleDownloadData(b.Log, rmsg, finfo.Name, rmsg.Text, url, &data, b.General)
62 return nil
63}
64
65func (b *Bmattermost) handleMatter() {
66 messages := make(chan *config.Message)
67 if b.GetString("WebhookBindAddress") != "" {
68 b.Log.Debugf("Choosing webhooks based receiving")
69 go b.handleMatterHook(messages)
70 } else {
71 if b.GetString("Token") != "" {
72 b.Log.Debugf("Choosing token based receiving")
73 } else {
74 b.Log.Debugf("Choosing login/password based receiving")
75 }
76 // if for some reason we only want to sent stuff to mattermost but not receive, return
77 if b.GetString("WebhookBindAddress") == "" && b.GetString("WebhookURL") != "" && b.GetString("Token") == "" && b.GetString("Login") == "" {
78 b.Log.Debugf("No WebhookBindAddress specified, only WebhookURL. You will not receive messages from mattermost, only sending is possible.")
79 }
80 go b.handleMatterClient(messages)
81 }
82 var ok bool
83 for message := range messages {
84 message.Avatar = helper.GetAvatar(b.avatarMap, message.UserID, b.General)
85 message.Account = b.Account
86 message.Text, ok = b.replaceAction(message.Text)
87 if ok {
88 message.Event = config.EventUserAction
89 }
90 b.Log.Debugf("<= Sending message from %s on %s to gateway", message.Username, b.Account)
91 b.Log.Debugf("<= Message is %#v", message)
92 b.Remote <- *message
93 }
94}
95
96//nolint:cyclop
97func (b *Bmattermost) handleMatterClient(messages chan *config.Message) {
98 for message := range b.mc.MessageChan {
99 b.Log.Debugf("%#v %#v", message.Raw.GetData(), message.Raw.EventType())
100
101 if b.skipMessage(message) {
102 b.Log.Debugf("Skipped message: %#v", message)
103 continue
104 }
105
106 channelName := b.getChannelName(message.Post.ChannelId)
107 if channelName == "" {
108 channelName = message.Channel
109 }
110
111 // only download avatars if we have a place to upload them (configured mediaserver)
112 if b.General.MediaDownloadPath != "" {
113 b.handleDownloadAvatar(message.UserID, channelName)
114 }
115
116 b.Log.Debugf("== Receiving event %#v", message)
117
118 rmsg := &config.Message{
119 Username: message.Username,
120 UserID: message.UserID,
121 Channel: channelName,
122 Text: message.Text,
123 ID: message.Post.Id,
124 ParentID: message.Post.RootId, // ParentID is obsolete with mattermost
125 Extra: make(map[string][]interface{}),
126 }
127
128 // handle mattermost post properties (override username and attachments)
129 b.handleProps(rmsg, message)
130
131 // create a text for bridges that don't support native editing
132 if message.Raw.EventType() == model.WebsocketEventPostEdited && !b.GetBool("EditDisable") {
133 rmsg.Text = message.Text + b.GetString("EditSuffix")
134 }
135
136 if message.Raw.EventType() == model.WebsocketEventPostDeleted {
137 rmsg.Event = config.EventMsgDelete
138 }
139
140 for _, id := range message.Post.FileIds {
141 err := b.handleDownloadFile(rmsg, id)
142 if err != nil {
143 b.Log.Errorf("download failed: %s", err)
144 }
145 }
146
147 // Use nickname instead of username if defined
148 if !b.GetBool("useusername") {
149 if nick := b.mc.GetNickName(rmsg.UserID); nick != "" {
150 rmsg.Username = nick
151 }
152 }
153
154 messages <- rmsg
155 }
156}
157
158func (b *Bmattermost) handleMatterHook(messages chan *config.Message) {
159 for {
160 message := b.mh.Receive()
161 b.Log.Debugf("Receiving from matterhook %#v", message)
162
163 messages <- &config.Message{
164 UserID: message.UserID,
165 Username: message.UserName,
166 Text: message.Text,
167 Channel: message.ChannelName,
168 }
169 }
170}
171
172func (b *Bmattermost) handleUploadFile(msg *config.Message) (string, error) {
173 var err error
174 var res, id string
175 channelID := b.getChannelID(msg.Channel)
176 for _, f := range msg.Extra["file"] {
177 fi := f.(config.FileInfo)
178 id, err = b.mc.UploadFile(*fi.Data, channelID, fi.Name)
179 if err != nil {
180 return "", err
181 }
182 msg.Text = fi.Comment
183 if b.GetBool("PrefixMessagesWithNick") {
184 msg.Text = msg.Username + msg.Text
185 }
186 res, err = b.mc.PostMessageWithFiles(channelID, msg.Text, msg.ParentID, []string{id})
187 }
188 return res, err
189}
190
191//nolint:forcetypeassert
192func (b *Bmattermost) handleProps(rmsg *config.Message, message *matterclient.Message) {
193 props := message.Post.Props
194 if props == nil {
195 return
196 }
197 if _, ok := props["override_username"].(string); ok {
198 rmsg.Username = props["override_username"].(string)
199 }
200 if _, ok := props["attachments"].([]interface{}); ok {
201 rmsg.Extra["attachments"] = props["attachments"].([]interface{})
202 if rmsg.Text != "" {
203 return
204 }
205
206 for _, attachment := range rmsg.Extra["attachments"] {
207 attach := attachment.(map[string]interface{})
208 if attach["text"].(string) != "" {
209 rmsg.Text += attach["text"].(string)
210 continue
211 }
212 if attach["fallback"].(string) != "" {
213 rmsg.Text += attach["fallback"].(string)
214 }
215 }
216 }
217}
218