matterbridge/bridge/mattermost/mattermost.go

195 lines
4.5 KiB
Go
Raw Normal View History

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