42wim/matterbridge

View on GitHub
bridge/rocketchat/rocketchat.go

Summary

Maintainability
A
1 hr
Test Coverage
package brocketchat

import (
    "errors"
    "strings"
    "sync"

    "github.com/42wim/matterbridge/bridge"
    "github.com/42wim/matterbridge/bridge/config"
    "github.com/42wim/matterbridge/bridge/helper"
    "github.com/42wim/matterbridge/hook/rockethook"
    "github.com/42wim/matterbridge/matterhook"
    lru "github.com/hashicorp/golang-lru"
    "github.com/matterbridge/Rocket.Chat.Go.SDK/models"
    "github.com/matterbridge/Rocket.Chat.Go.SDK/realtime"
    "github.com/matterbridge/Rocket.Chat.Go.SDK/rest"
)

type Brocketchat struct {
    mh    *matterhook.Client
    rh    *rockethook.Client
    c     *realtime.Client
    r     *rest.Client
    cache *lru.Cache
    *bridge.Config
    messageChan chan models.Message
    channelMap  map[string]string
    user        *models.User
    sync.RWMutex
}

const (
    sUserJoined       = "uj"
    sUserLeft         = "ul"
    sRoomChangedTopic = "room_changed_topic"
)

func New(cfg *bridge.Config) bridge.Bridger {
    newCache, err := lru.New(100)
    if err != nil {
        cfg.Log.Fatalf("Could not create LRU cache for rocketchat bridge: %v", err)
    }
    b := &Brocketchat{
        Config:      cfg,
        messageChan: make(chan models.Message),
        channelMap:  make(map[string]string),
        cache:       newCache,
    }
    b.Log.Debugf("enabling rocketchat")
    return b
}

func (b *Brocketchat) Command(cmd string) string {
    return ""
}

func (b *Brocketchat) Connect() error {
    if b.GetString("WebhookBindAddress") != "" {
        if err := b.doConnectWebhookBind(); err != nil {
            return err
        }
        go b.handleRocket()
        return nil
    }
    switch {
    case b.GetString("WebhookURL") != "":
        if err := b.doConnectWebhookURL(); err != nil {
            return err
        }
        go b.handleRocket()
        return nil
    case b.GetString("Login") != "":
        b.Log.Info("Connecting using login/password (sending and receiving)")
        err := b.apiLogin()
        if err != nil {
            return err
        }
        go b.handleRocket()
    }
    if b.GetString("WebhookBindAddress") == "" && b.GetString("WebhookURL") == "" &&
        b.GetString("Login") == "" {
        return errors.New("no connection method found. See that you have WebhookBindAddress, WebhookURL or Login/Password/Server configured")
    }
    return nil
}

func (b *Brocketchat) Disconnect() error {
    return nil
}

func (b *Brocketchat) JoinChannel(channel config.ChannelInfo) error {
    if b.c == nil {
        return nil
    }
    id, err := b.c.GetChannelId(strings.TrimPrefix(channel.Name, "#"))
    if err != nil {
        return err
    }
    b.Lock()
    b.channelMap[id] = channel.Name
    b.Unlock()
    mychannel := &models.Channel{ID: id, Name: strings.TrimPrefix(channel.Name, "#")}
    if err := b.c.JoinChannel(id); err != nil {
        return err
    }
    if err := b.c.SubscribeToMessageStream(mychannel, b.messageChan); err != nil {
        return err
    }
    return nil
}

func (b *Brocketchat) Send(msg config.Message) (string, error) {
    // strip the # if people has set this
    msg.Channel = strings.TrimPrefix(msg.Channel, "#")
    channel := &models.Channel{ID: b.getChannelID(msg.Channel), Name: msg.Channel}

    // Make a action /me of the message
    if msg.Event == config.EventUserAction {
        msg.Text = "_" + msg.Text + "_"
    }

    // Delete message
    if msg.Event == config.EventMsgDelete {
        if msg.ID == "" {
            return "", nil
        }
        return msg.ID, b.c.DeleteMessage(&models.Message{ID: msg.ID})
    }

    // Use webhook to send the message
    if b.GetString("WebhookURL") != "" {
        return "", b.sendWebhook(&msg)
    }

    // Prepend nick if configured
    if b.GetBool("PrefixMessagesWithNick") {
        msg.Text = msg.Username + msg.Text
    }

    // Edit message if we have an ID
    if msg.ID != "" {
        return msg.ID, b.c.EditMessage(&models.Message{ID: msg.ID, Msg: msg.Text, RoomID: b.getChannelID(msg.Channel)})
    }

    // Upload a file if it exists
    if msg.Extra != nil {
        for _, rmsg := range helper.HandleExtra(&msg, b.General) {
            // strip the # if people has set this
            rmsg.Channel = strings.TrimPrefix(rmsg.Channel, "#")
            smsg := &models.Message{
                RoomID: b.getChannelID(rmsg.Channel),
                Msg:    rmsg.Username + rmsg.Text,
                PostMessage: models.PostMessage{
                    Avatar: rmsg.Avatar,
                    Alias:  rmsg.Username,
                },
            }
            if _, err := b.c.SendMessage(smsg); err != nil {
                b.Log.Errorf("SendMessage failed: %s", err)
            }
        }
        if len(msg.Extra["file"]) > 0 {
            return "", b.handleUploadFile(&msg)
        }
    }

    smsg := &models.Message{
        RoomID: channel.ID,
        Msg:    msg.Text,
        PostMessage: models.PostMessage{
            Avatar: msg.Avatar,
            Alias:  msg.Username,
        },
    }

    rmsg, err := b.c.SendMessage(smsg)
    if rmsg == nil {
        return "", err
    }
    return rmsg.ID, err
}