2016-08-14 21:48:51 +02:00
|
|
|
package bmattermost
|
|
|
|
|
|
|
|
import (
|
2017-07-15 16:49:47 +02:00
|
|
|
"errors"
|
2017-08-30 14:01:17 +02:00
|
|
|
"fmt"
|
2021-10-16 23:11:51 +02:00
|
|
|
"strings"
|
2022-02-06 18:26:30 +01:00
|
|
|
"sync"
|
2018-06-09 12:47:40 +02:00
|
|
|
|
2018-02-27 00:33:21 +01:00
|
|
|
"github.com/42wim/matterbridge/bridge"
|
2016-08-14 21:48:51 +02:00
|
|
|
"github.com/42wim/matterbridge/bridge/config"
|
2018-02-03 01:11:11 +01:00
|
|
|
"github.com/42wim/matterbridge/bridge/helper"
|
2016-08-14 21:48:51 +02:00
|
|
|
"github.com/42wim/matterbridge/matterclient"
|
|
|
|
"github.com/42wim/matterbridge/matterhook"
|
2021-10-16 23:11:51 +02:00
|
|
|
matterclient6 "github.com/matterbridge/matterclient"
|
2018-05-27 21:50:00 +02:00
|
|
|
"github.com/rs/xid"
|
2016-08-14 21:48:51 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
type Bmattermost struct {
|
2018-02-23 23:07:23 +01:00
|
|
|
mh *matterhook.Client
|
|
|
|
mc *matterclient.MMClient
|
2021-10-16 23:11:51 +02:00
|
|
|
mc6 *matterclient6.Client
|
|
|
|
v6 bool
|
2018-05-27 21:50:00 +02:00
|
|
|
uuid string
|
2018-02-24 23:22:15 +01:00
|
|
|
TeamID string
|
2018-03-04 23:52:14 +01:00
|
|
|
*bridge.Config
|
2022-02-06 18:26:30 +01:00
|
|
|
avatarMap map[string]string
|
|
|
|
channelsMutex sync.RWMutex
|
|
|
|
channelInfoMap map[string]*config.ChannelInfo
|
2016-08-14 21:48:51 +02:00
|
|
|
}
|
|
|
|
|
2018-11-13 20:40:15 +01:00
|
|
|
const mattermostPlugin = "mattermost.plugin"
|
|
|
|
|
2018-03-04 23:52:14 +01:00
|
|
|
func New(cfg *bridge.Config) bridge.Bridger {
|
2022-02-06 18:26:30 +01:00
|
|
|
b := &Bmattermost{
|
|
|
|
Config: cfg,
|
|
|
|
avatarMap: make(map[string]string),
|
|
|
|
channelInfoMap: make(map[string]*config.ChannelInfo),
|
|
|
|
}
|
2021-10-16 23:11:51 +02:00
|
|
|
|
|
|
|
b.v6 = b.GetBool("v6")
|
2018-05-27 21:50:00 +02:00
|
|
|
b.uuid = xid.New().String()
|
2021-10-16 23:11:51 +02:00
|
|
|
|
2016-08-15 23:16:07 +02:00
|
|
|
return b
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Bmattermost) Command(cmd string) string {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Bmattermost) Connect() error {
|
2018-11-13 20:40:15 +01:00
|
|
|
if b.Account == mattermostPlugin {
|
2018-11-11 22:42:33 +01:00
|
|
|
return nil
|
|
|
|
}
|
2021-10-16 23:11:51 +02:00
|
|
|
|
|
|
|
if strings.HasPrefix(b.getVersion(), "6.") {
|
|
|
|
if !b.v6 {
|
|
|
|
b.v6 = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-04 23:52:14 +01:00
|
|
|
if b.GetString("WebhookBindAddress") != "" {
|
2018-12-01 00:49:08 +01:00
|
|
|
if err := b.doConnectWebhookBind(); err != nil {
|
|
|
|
return err
|
2017-07-15 16:49:47 +02:00
|
|
|
}
|
|
|
|
go b.handleMatter()
|
|
|
|
return nil
|
|
|
|
}
|
2018-11-08 22:01:29 +01:00
|
|
|
switch {
|
|
|
|
case b.GetString("WebhookURL") != "":
|
2018-12-01 00:49:08 +01:00
|
|
|
if err := b.doConnectWebhookURL(); err != nil {
|
|
|
|
return err
|
2017-07-15 16:49:47 +02:00
|
|
|
}
|
2018-12-01 00:49:08 +01:00
|
|
|
go b.handleMatter()
|
2017-07-15 16:49:47 +02:00
|
|
|
return nil
|
2018-11-08 22:01:29 +01:00
|
|
|
case b.GetString("Token") != "":
|
2018-02-27 00:33:21 +01:00
|
|
|
b.Log.Info("Connecting using token (sending and receiving)")
|
2021-10-16 23:11:51 +02:00
|
|
|
b.Log.Infof("Using mattermost v6 methods: %t", b.v6)
|
|
|
|
|
|
|
|
if b.v6 {
|
|
|
|
err := b.apiLogin6()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
err := b.apiLogin()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-08-23 22:49:42 +02:00
|
|
|
}
|
|
|
|
go b.handleMatter()
|
2018-11-08 22:01:29 +01:00
|
|
|
case b.GetString("Login") != "":
|
2018-02-27 00:33:21 +01:00
|
|
|
b.Log.Info("Connecting using login/password (sending and receiving)")
|
2021-10-16 23:11:51 +02:00
|
|
|
b.Log.Infof("Using mattermost v6 methods: %t", b.v6)
|
|
|
|
|
|
|
|
if b.v6 {
|
|
|
|
err := b.apiLogin6()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
err := b.apiLogin()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2016-08-14 21:48:51 +02:00
|
|
|
}
|
2017-07-15 16:49:47 +02:00
|
|
|
go b.handleMatter()
|
|
|
|
}
|
2018-12-01 00:49:08 +01:00
|
|
|
if b.GetString("WebhookBindAddress") == "" && b.GetString("WebhookURL") == "" &&
|
|
|
|
b.GetString("Login") == "" && b.GetString("Token") == "" {
|
2018-02-24 23:22:15 +01:00
|
|
|
return errors.New("no connection method found. See that you have WebhookBindAddress, WebhookURL or Token/Login/Password/Server/Team configured")
|
2016-08-14 21:48:51 +02:00
|
|
|
}
|
2016-08-15 23:16:07 +02:00
|
|
|
return nil
|
2016-08-14 21:48:51 +02:00
|
|
|
}
|
|
|
|
|
2017-02-14 21:12:02 +01:00
|
|
|
func (b *Bmattermost) Disconnect() error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-08-12 14:51:41 +02:00
|
|
|
func (b *Bmattermost) JoinChannel(channel config.ChannelInfo) error {
|
2018-11-13 20:40:15 +01:00
|
|
|
if b.Account == mattermostPlugin {
|
2018-11-11 22:42:33 +01:00
|
|
|
return nil
|
|
|
|
}
|
2022-02-06 18:26:30 +01:00
|
|
|
|
|
|
|
b.channelsMutex.Lock()
|
|
|
|
b.channelInfoMap[channel.ID] = &channel
|
|
|
|
b.channelsMutex.Unlock()
|
|
|
|
|
2016-09-20 12:20:44 +02:00
|
|
|
// we can only join channels using the API
|
2018-03-04 23:52:14 +01:00
|
|
|
if b.GetString("WebhookURL") == "" && b.GetString("WebhookBindAddress") == "" {
|
2022-02-06 18:26:30 +01:00
|
|
|
id := b.getChannelID(channel.Name)
|
2017-08-30 14:01:17 +02:00
|
|
|
if id == "" {
|
|
|
|
return fmt.Errorf("Could not find channel ID for channel %s", channel.Name)
|
|
|
|
}
|
2021-10-16 23:11:51 +02:00
|
|
|
|
|
|
|
if b.mc6 != nil {
|
|
|
|
return b.mc6.JoinChannel(id) // nolint:wrapcheck
|
|
|
|
}
|
|
|
|
|
2017-08-30 14:01:17 +02:00
|
|
|
return b.mc.JoinChannel(id)
|
2016-09-20 12:20:44 +02:00
|
|
|
}
|
2022-02-06 18:26:30 +01:00
|
|
|
|
2016-09-20 12:20:44 +02:00
|
|
|
return nil
|
2016-09-18 19:21:15 +02:00
|
|
|
}
|
|
|
|
|
2017-08-27 22:59:37 +02:00
|
|
|
func (b *Bmattermost) Send(msg config.Message) (string, error) {
|
2018-11-13 20:40:15 +01:00
|
|
|
if b.Account == mattermostPlugin {
|
2018-11-11 22:42:33 +01:00
|
|
|
return "", nil
|
|
|
|
}
|
2018-02-28 22:23:29 +01:00
|
|
|
b.Log.Debugf("=> Receiving %#v", msg)
|
2018-02-23 23:07:23 +01:00
|
|
|
|
|
|
|
// Make a action /me of the message
|
2018-11-15 20:43:43 +01:00
|
|
|
if msg.Event == config.EventUserAction {
|
2017-07-30 17:48:23 +02:00
|
|
|
msg.Text = "*" + msg.Text + "*"
|
|
|
|
}
|
2016-08-14 21:48:51 +02:00
|
|
|
|
2018-02-20 00:54:35 +01:00
|
|
|
// map the file SHA to our user (caches the avatar)
|
2018-11-15 20:43:43 +01:00
|
|
|
if msg.Event == config.EventAvatarDownload {
|
2018-02-23 23:07:23 +01:00
|
|
|
return b.cacheAvatar(&msg)
|
2018-02-20 00:54:35 +01:00
|
|
|
}
|
|
|
|
|
2018-02-23 23:07:23 +01:00
|
|
|
// Use webhook to send the message
|
2018-03-04 23:52:14 +01:00
|
|
|
if b.GetString("WebhookURL") != "" {
|
2018-02-23 23:07:23 +01:00
|
|
|
return b.sendWebhook(msg)
|
2016-08-14 21:48:51 +02:00
|
|
|
}
|
2018-02-23 23:07:23 +01:00
|
|
|
|
|
|
|
// Delete message
|
2018-11-15 20:43:43 +01:00
|
|
|
if msg.Event == config.EventMsgDelete {
|
2017-09-11 22:45:15 +02:00
|
|
|
if msg.ID == "" {
|
|
|
|
return "", nil
|
|
|
|
}
|
2021-10-16 23:11:51 +02:00
|
|
|
if b.mc6 != nil {
|
|
|
|
return msg.ID, b.mc6.DeleteMessage(msg.ID) // nolint:wrapcheck
|
|
|
|
}
|
|
|
|
|
2017-09-11 22:45:15 +02:00
|
|
|
return msg.ID, b.mc.DeleteMessage(msg.ID)
|
|
|
|
}
|
2018-02-23 23:07:23 +01:00
|
|
|
|
2019-04-19 23:31:45 +02:00
|
|
|
// Handle prefix hint for unthreaded messages.
|
2020-12-31 19:01:57 +01:00
|
|
|
if msg.ParentNotFound() {
|
2019-04-19 23:31:45 +02:00
|
|
|
msg.ParentID = ""
|
|
|
|
msg.Text = fmt.Sprintf("[thread]: %s", msg.Text)
|
|
|
|
}
|
|
|
|
|
2020-12-31 16:59:47 +01:00
|
|
|
// we only can reply to the root of the thread, not to a specific ID (like discord for example does)
|
|
|
|
if msg.ParentID != "" {
|
2021-10-16 23:11:51 +02:00
|
|
|
if b.mc6 != nil {
|
|
|
|
post, _, err := b.mc6.Client.GetPost(msg.ParentID, "")
|
|
|
|
if err != nil {
|
|
|
|
b.Log.Errorf("getting post %s failed: %s", msg.ParentID, err)
|
|
|
|
}
|
2022-01-10 00:37:09 +01:00
|
|
|
if post.RootId != "" {
|
|
|
|
msg.ParentID = post.RootId
|
|
|
|
}
|
2021-10-16 23:11:51 +02:00
|
|
|
} else {
|
|
|
|
post, res := b.mc.Client.GetPost(msg.ParentID, "")
|
|
|
|
if res.Error != nil {
|
|
|
|
b.Log.Errorf("getting post %s failed: %s", msg.ParentID, res.Error.DetailedError)
|
|
|
|
}
|
2022-01-10 00:37:09 +01:00
|
|
|
if post.RootId != "" {
|
|
|
|
msg.ParentID = post.RootId
|
|
|
|
}
|
2020-12-31 16:59:47 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-23 23:07:23 +01:00
|
|
|
// Upload a file if it exists
|
2017-09-21 22:35:21 +02:00
|
|
|
if msg.Extra != nil {
|
2018-02-03 01:11:11 +01:00
|
|
|
for _, rmsg := range helper.HandleExtra(&msg, b.General) {
|
2021-10-16 23:11:51 +02:00
|
|
|
if b.mc6 != nil {
|
2022-02-06 18:26:30 +01:00
|
|
|
if _, err := b.mc6.PostMessage(b.getChannelID(rmsg.Channel), rmsg.Username+rmsg.Text, msg.ParentID); err != nil {
|
2021-10-16 23:11:51 +02:00
|
|
|
b.Log.Errorf("PostMessage failed: %s", err)
|
|
|
|
}
|
|
|
|
} else {
|
2022-02-06 18:26:30 +01:00
|
|
|
if _, err := b.mc.PostMessage(b.getChannelID(rmsg.Channel), rmsg.Username+rmsg.Text, msg.ParentID); err != nil {
|
2021-10-16 23:11:51 +02:00
|
|
|
b.Log.Errorf("PostMessage failed: %s", err)
|
|
|
|
}
|
2018-12-01 00:49:08 +01:00
|
|
|
}
|
2018-02-03 01:11:11 +01:00
|
|
|
}
|
2017-09-21 23:15:04 +02:00
|
|
|
if len(msg.Extra["file"]) > 0 {
|
2018-02-23 23:07:23 +01:00
|
|
|
return b.handleUploadFile(&msg)
|
2017-09-21 22:35:21 +02:00
|
|
|
}
|
|
|
|
}
|
2018-02-23 23:07:23 +01:00
|
|
|
|
|
|
|
// Prepend nick if configured
|
2018-03-04 23:52:14 +01:00
|
|
|
if b.GetBool("PrefixMessagesWithNick") {
|
2018-02-23 23:07:23 +01:00
|
|
|
msg.Text = msg.Username + msg.Text
|
|
|
|
}
|
|
|
|
|
|
|
|
// Edit message if we have an ID
|
2017-08-28 00:33:17 +02:00
|
|
|
if msg.ID != "" {
|
2021-10-16 23:11:51 +02:00
|
|
|
if b.mc6 != nil {
|
|
|
|
return b.mc6.EditMessage(msg.ID, msg.Text) // nolint:wrapcheck
|
|
|
|
}
|
|
|
|
|
2018-02-23 23:07:23 +01:00
|
|
|
return b.mc.EditMessage(msg.ID, msg.Text)
|
2017-08-28 00:33:17 +02:00
|
|
|
}
|
2018-02-23 23:07:23 +01:00
|
|
|
|
|
|
|
// Post normal message
|
2021-10-16 23:11:51 +02:00
|
|
|
if b.mc6 != nil {
|
2022-02-06 18:26:30 +01:00
|
|
|
return b.mc6.PostMessage(b.getChannelID(msg.Channel), msg.Text, msg.ParentID) // nolint:wrapcheck
|
2021-10-16 23:11:51 +02:00
|
|
|
}
|
|
|
|
|
2022-02-06 18:26:30 +01:00
|
|
|
return b.mc.PostMessage(b.getChannelID(msg.Channel), msg.Text, msg.ParentID)
|
2016-08-14 21:48:51 +02:00
|
|
|
}
|