42wim/matterbridge

View on GitHub
bridge/rocketchat/helpers.go

Summary

Maintainability
A
0 mins
Test Coverage
package brocketchat

import (
    "context"
    "io/ioutil"
    "mime"
    "net/http"
    "net/url"
    "strings"
    "time"

    "github.com/42wim/matterbridge/bridge/config"
    "github.com/42wim/matterbridge/bridge/helper"
    "github.com/42wim/matterbridge/hook/rockethook"
    "github.com/42wim/matterbridge/matterhook"
    "github.com/matterbridge/Rocket.Chat.Go.SDK/models"
    "github.com/matterbridge/Rocket.Chat.Go.SDK/realtime"
    "github.com/matterbridge/Rocket.Chat.Go.SDK/rest"
    "github.com/nelsonken/gomf"
)

func (b *Brocketchat) doConnectWebhookBind() error {
    switch {
    case b.GetString("WebhookURL") != "":
        b.Log.Info("Connecting using webhookurl (sending) and webhookbindaddress (receiving)")
        b.mh = matterhook.New(b.GetString("WebhookURL"),
            matterhook.Config{InsecureSkipVerify: b.GetBool("SkipTLSVerify"),
                DisableServer: true})
        b.rh = rockethook.New(b.GetString("WebhookURL"), rockethook.Config{BindAddress: b.GetString("WebhookBindAddress")})
    case b.GetString("Login") != "":
        b.Log.Info("Connecting using login/password (sending)")
        err := b.apiLogin()
        if err != nil {
            return err
        }
    default:
        b.Log.Info("Connecting using webhookbindaddress (receiving)")
        b.rh = rockethook.New(b.GetString("WebhookURL"), rockethook.Config{BindAddress: b.GetString("WebhookBindAddress")})
    }
    return nil
}

func (b *Brocketchat) doConnectWebhookURL() error {
    b.Log.Info("Connecting using webhookurl (sending)")
    b.mh = matterhook.New(b.GetString("WebhookURL"),
        matterhook.Config{InsecureSkipVerify: b.GetBool("SkipTLSVerify"),
            DisableServer: true})
    if b.GetString("Login") != "" {
        b.Log.Info("Connecting using login/password (receiving)")
        err := b.apiLogin()
        if err != nil {
            return err
        }
    }
    return nil
}

func (b *Brocketchat) apiLogin() error {
    b.Log.Debugf("handling apiLogin()")
    credentials := &models.UserCredentials{Email: b.GetString("login"), Password: b.GetString("password")}
    if b.GetString("Token") != "" {
        credentials = &models.UserCredentials{ID: b.GetString("Login"), Token: b.GetString("Token")}
    }
    myURL, err := url.Parse(b.GetString("server"))
    if err != nil {
        return err
    }
    client, err := realtime.NewClient(myURL, b.GetBool("debug"))
    b.c = client
    if err != nil {
        return err
    }
    restclient := rest.NewClient(myURL, b.GetBool("debug"))
    user, err := b.c.Login(credentials)
    if err != nil {
        return err
    }
    b.user = user
    b.r = restclient
    err = b.r.Login(credentials)
    if err != nil {
        return err
    }
    b.Log.Info("Connection succeeded")
    return nil
}

func (b *Brocketchat) getChannelName(id string) string {
    b.RLock()
    defer b.RUnlock()
    if name, ok := b.channelMap[id]; ok {
        return name
    }
    return ""
}

func (b *Brocketchat) getChannelID(name string) string {
    b.RLock()
    defer b.RUnlock()
    for k, v := range b.channelMap {
        if v == name || v == "#"+name {
            return k
        }
    }
    return ""
}

func (b *Brocketchat) skipMessage(message *models.Message) bool {
    return message.User.ID == b.user.ID
}

func (b *Brocketchat) uploadFile(fi *config.FileInfo, channel string) error {
    fb := gomf.New()
    if err := fb.WriteField("description", fi.Comment); err != nil {
        return err
    }
    sp := strings.Split(fi.Name, ".")
    mtype := mime.TypeByExtension("." + sp[len(sp)-1])
    if !strings.Contains(mtype, "image") && !strings.Contains(mtype, "video") {
        return nil
    }
    if err := fb.WriteFile("file", fi.Name, mtype, *fi.Data); err != nil {
        return err
    }
    req, err := fb.GetHTTPRequest(context.TODO(), b.GetString("server")+"/api/v1/rooms.upload/"+channel)
    if err != nil {
        return err
    }
    req.Header.Add("X-Auth-Token", b.user.Token)
    req.Header.Add("X-User-Id", b.user.ID)
    client := &http.Client{
        Timeout: time.Second * 5,
    }
    resp, err := client.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return err
    }
    if resp.StatusCode != 200 {
        b.Log.Errorf("failed: %#v", string(body))
    }
    return nil
}

// sendWebhook uses the configured WebhookURL to send the message
func (b *Brocketchat) sendWebhook(msg *config.Message) error {
    // skip events
    if msg.Event != "" {
        return nil
    }

    if b.GetBool("PrefixMessagesWithNick") {
        msg.Text = msg.Username + msg.Text
    }
    if msg.Extra != nil {
        // this sends a message only if we received a config.EVENT_FILE_FAILURE_SIZE
        for _, rmsg := range helper.HandleExtra(msg, b.General) {
            rmsg := rmsg // scopelint
            iconURL := config.GetIconURL(&rmsg, b.GetString("iconurl"))
            matterMessage := matterhook.OMessage{
                IconURL:  iconURL,
                Channel:  rmsg.Channel,
                UserName: rmsg.Username,
                Text:     rmsg.Text,
                Props:    make(map[string]interface{}),
            }
            if err := b.mh.Send(matterMessage); err != nil {
                b.Log.Errorf("sendWebhook failed: %s ", err)
            }
        }

        // webhook doesn't support file uploads, so we add the url manually
        if len(msg.Extra["file"]) > 0 {
            for _, f := range msg.Extra["file"] {
                fi := f.(config.FileInfo)
                if fi.URL != "" {
                    msg.Text += fi.URL
                }
            }
        }
    }
    iconURL := config.GetIconURL(msg, b.GetString("iconurl"))
    matterMessage := matterhook.OMessage{
        IconURL:  iconURL,
        Channel:  msg.Channel,
        UserName: msg.Username,
        Text:     msg.Text,
    }
    if msg.Avatar != "" {
        matterMessage.IconURL = msg.Avatar
    }
    err := b.mh.Send(matterMessage)
    if err != nil {
        b.Log.Info(err)
        return err
    }
    return nil
}