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 "errors"
6 "fmt"
7 "strings"
8 "sync"
9
10 "github.com/matterbridge-org/matterbridge/bridge"
11 "github.com/matterbridge-org/matterbridge/bridge/config"
12 "github.com/matterbridge-org/matterbridge/bridge/helper"
13 "github.com/matterbridge-org/matterbridge/matterhook"
14 "github.com/matterbridge/matterclient"
15 "github.com/rs/xid"
16)
17
18type Bmattermost struct {
19 mh *matterhook.Client
20 mc *matterclient.Client
21 v6 bool
22 uuid string
23 TeamID string
24 *bridge.Config
25 avatarMap map[string]string
26 channelsMutex sync.RWMutex
27 channelInfoMap map[string]*config.ChannelInfo
28}
29
30const mattermostPlugin = "mattermost.plugin"
31
32func New(cfg *bridge.Config) bridge.Bridger {
33 b := &Bmattermost{
34 Config: cfg,
35 avatarMap: make(map[string]string),
36 channelInfoMap: make(map[string]*config.ChannelInfo),
37 }
38
39 b.v6 = b.GetBool("v6")
40 b.uuid = xid.New().String()
41
42 return b
43}
44
45func (b *Bmattermost) Command(cmd string) string {
46 return ""
47}
48
49func (b *Bmattermost) Connect() error {
50 if b.Account == mattermostPlugin {
51 return nil
52 }
53
54 if strings.HasPrefix(b.getVersion(), "6.") || strings.HasPrefix(b.getVersion(), "7.") {
55 if !b.v6 {
56 b.v6 = true
57 }
58 }
59
60 if b.GetString("WebhookBindAddress") != "" {
61 if err := b.doConnectWebhookBind(); err != nil {
62 return err
63 }
64 go b.handleMatter()
65 return nil
66 }
67 switch {
68 case b.GetString("WebhookURL") != "":
69 if err := b.doConnectWebhookURL(); err != nil {
70 return err
71 }
72 go b.handleMatter()
73 return nil
74 case b.GetString("Token") != "":
75 b.Log.Info("Connecting using token (sending and receiving)")
76 err := b.apiLogin()
77 if err != nil {
78 return err
79 }
80 go b.handleMatter()
81 case b.GetString("Login") != "":
82 b.Log.Info("Connecting using login/password (sending and receiving)")
83 b.Log.Infof("Using mattermost v6 methods: %t", b.v6)
84 err := b.apiLogin()
85 if err != nil {
86 return err
87 }
88 go b.handleMatter()
89 }
90 if b.GetString("WebhookBindAddress") == "" && b.GetString("WebhookURL") == "" &&
91 b.GetString("Login") == "" && b.GetString("Token") == "" {
92 return errors.New("no connection method found. See that you have WebhookBindAddress, WebhookURL or Token/Login/Password/Server/Team configured")
93 }
94 return nil
95}
96
97func (b *Bmattermost) Disconnect() error {
98 return nil
99}
100
101func (b *Bmattermost) JoinChannel(channel config.ChannelInfo) error {
102 if b.Account == mattermostPlugin {
103 return nil
104 }
105
106 b.channelsMutex.Lock()
107 b.channelInfoMap[channel.ID] = &channel
108 b.channelsMutex.Unlock()
109
110 // we can only join channels using the API
111 if b.GetString("WebhookURL") == "" && b.GetString("WebhookBindAddress") == "" {
112 id := b.getChannelID(channel.Name)
113 if id == "" {
114 return fmt.Errorf("Could not find channel ID for channel %s", channel.Name)
115 }
116
117 return b.mc.JoinChannel(id)
118 }
119
120 return nil
121}
122
123func (b *Bmattermost) Send(msg config.Message) (string, error) {
124 if b.Account == mattermostPlugin {
125 return "", nil
126 }
127 b.Log.Debugf("=> Receiving %#v", msg)
128
129 // Make a action /me of the message
130 if msg.Event == config.EventUserAction {
131 msg.Text = "*" + msg.Text + "*"
132 }
133
134 // map the file SHA to our user (caches the avatar)
135 if msg.Event == config.EventAvatarDownload {
136 return b.cacheAvatar(&msg)
137 }
138
139 // Use webhook to send the message
140 if b.GetString("WebhookURL") != "" {
141 return b.sendWebhook(msg)
142 }
143
144 // Delete message
145 if msg.Event == config.EventMsgDelete {
146 if msg.ID == "" {
147 return "", nil
148 }
149
150 return msg.ID, b.mc.DeleteMessage(msg.ID)
151 }
152
153 // Handle prefix hint for unthreaded messages.
154 if msg.ParentNotFound() {
155 msg.ParentID = ""
156 msg.Text = fmt.Sprintf("[thread]: %s", msg.Text)
157 }
158
159 // we only can reply to the root of the thread, not to a specific ID (like discord for example does)
160 if msg.ParentID != "" {
161 post, _, err := b.mc.Client.GetPost(context.TODO(), msg.ParentID, "")
162 if err != nil {
163 b.Log.Errorf("getting post %s failed: %s", msg.ParentID, err)
164 }
165 if post != nil && post.RootId != "" {
166 msg.ParentID = post.RootId
167 }
168 }
169
170 // Upload a file if it exists
171 if msg.Extra != nil {
172 for _, rmsg := range helper.HandleExtra(&msg, b.General) {
173 if _, err := b.mc.PostMessage(b.getChannelID(rmsg.Channel), rmsg.Username+rmsg.Text, msg.ParentID); err != nil {
174 b.Log.Errorf("PostMessage failed: %s", err)
175 }
176 }
177 if len(msg.Extra["file"]) > 0 {
178 return b.handleUploadFile(&msg)
179 }
180 }
181
182 // Prepend nick if configured
183 if b.GetBool("PrefixMessagesWithNick") {
184 msg.Text = msg.Username + msg.Text
185 }
186
187 // Edit message if we have an ID
188 if msg.ID != "" {
189 return b.mc.EditMessage(msg.ID, msg.Text)
190 }
191
192 // Post normal message
193 return b.mc.PostMessage(b.getChannelID(msg.Channel), msg.Text, msg.ParentID)
194}
195