Thumbnail

rani/matterbridge.git

Clone URL: https://git.buni.party/rani/matterbridge.git

commit 9f890edb18919e4d46a14c1b83f0f5aa31235768 Author: Wim <wim@42.be> Date: Sun Feb 10 17:00:11 2019 +0000 Refactor and update RocketChat bridge * Add support for editing/deleting messages * Add support for uploading files * Add support for avatars * Use the Rocket.Chat.Go.SDK * Use the rest and streaming api diff --git a/bridge/rocketchat/handlers.go b/bridge/rocketchat/handlers.go new file mode 100644 index 0000000..b44ea46 --- /dev/null +++ b/bridge/rocketchat/handlers.go @@ -00 +169 @@ +package brocketchat + +import ( + "github.com/42wim/matterbridge/bridge/config" +) + +func (b *Brocketchat) handleRocket() { + messages := make(chan *config.Message) + if b.GetString("WebhookBindAddress") != "" { + b.Log.Debugf("Choosing webhooks based receiving") + go b.handleRocketHook(messages) + } else { + b.Log.Debugf("Choosing login/password based receiving") + go b.handleRocketClient(messages) + } + for message := range messages { + message.Account = b.Account + b.Log.Debugf("<= Sending message from %s on %s to gateway", message.Username, b.Account) + b.Log.Debugf("<= Message is %#v", message) + b.Remote <- *message + } +} + +func (b *Brocketchat) handleRocketHook(messages chan *config.Message) { + for { + message := b.rh.Receive() + b.Log.Debugf("Receiving from rockethook %#v", message) + // do not loop + if message.UserName == b.GetString("Nick") { + continue + } + messages <- &config.Message{ + UserID: message.UserID, + Username: message.UserName, + Text: message.Text, + Channel: message.ChannelName, + } + } +} + +func (b *Brocketchat) handleRocketClient(messages chan *config.Message) { + for message := range b.messageChan { + b.Log.Debugf("message %#v", message) + m := message + if b.skipMessage(&m) { + b.Log.Debugf("Skipped message: %#v", message) + continue + } + + rmsg := &config.Message{Text: message.Msg, + Username: message.User.UserName, + Channel: b.getChannelName(message.RoomID), + Account: b.Account, + UserID: message.User.ID, + ID: message.ID, + } + messages <- rmsg + } +} + +func (b *Brocketchat) handleUploadFile(msg *config.Message) error { + for _, f := range msg.Extra["file"] { + fi := f.(config.FileInfo) + if err := b.uploadFile(&fi, b.getChannelID(msg.Channel)); err != nil { + return err + } + } + return nil +} diff --git a/bridge/rocketchat/helpers.go b/bridge/rocketchat/helpers.go new file mode 100644 index 0000000..c6bd2dd --- /dev/null +++ b/bridge/rocketchat/helpers.go @@ -00 +1198 @@ +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")} + 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 { + 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 + } + 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 +} diff --git a/bridge/rocketchat/rocketchat.go b/bridge/rocketchat/rocketchat.go index 1dbc7be..82b6627 100644 --- a/bridge/rocketchat/rocketchat.go +++ b/bridge/rocketchat/rocketchat.go @@ -121 +137 @@  package brocketchat    import ( + "errors" + "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" + "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   *bridge.Config + messageChan chan models.Message + channelMap map[string]string + user *models.User + sync.RWMutex  }    func New(cfg *bridge.Config) bridge.Bridger { - return &Brocketchat{Config: cfg} + b := &Brocketchat{Config: cfg} + b.messageChan = make(chan models.Message) + b.channelMap = make(map[string]string) + b.Log.Debugf("enabling rocketchat") + return b  }    func (b *Brocketchat) Command(cmd string) string { @@ -2370 +39118 @@ func (b *Brocketchat) Command(cmd string) string {  }    func (b *Brocketchat) Connect() error { - b.Log.Info("Connecting webhooks") - 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")}) - go b.handleRocketHook() + 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(channel.Name) + if err != nil { + return err + } + b.Lock() + b.channelMap[id] = channel.Name + b.Unlock() + mychannel := &models.Channel{ID: id, Name: 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) { - // ignore delete messages + channel := &models.Channel{ID: b.getChannelID(msg.Channel), Name: msg.Channel} + + // Delete message   if msg.Event == config.EventMsgDelete { - return "", nil + if msg.ID == "" { + return "", nil + } + return msg.ID, b.c.DeleteMessage(&models.Message{ID: msg.ID})   } - b.Log.Debugf("=> Receiving %#v", msg) + + // 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) { - rmsg := rmsg // scopelint - iconURL := config.GetIconURL(&rmsg, b.GetString("iconurl")) - matterMessage := matterhook.OMessage{IconURL: iconURL, Channel: rmsg.Channel, UserName: rmsg.Username, Text: rmsg.Text} - b.mh.Send(matterMessage) + 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 { - for _, f := range msg.Extra["file"] { - fi := f.(config.FileInfo) - if fi.URL != "" { - msg.Text += fi.URL - } - } + return "", b.handleUploadFile(&msg)   }   }   - iconURL := config.GetIconURL(&msg, b.GetString("iconurl")) - matterMessage := matterhook.OMessage{IconURL: iconURL} - matterMessage.Channel = msg.Channel - matterMessage.UserName = msg.Username - matterMessage.Type = "" - matterMessage.Text = msg.Text - err := b.mh.Send(matterMessage) - if err != nil { - b.Log.Info(err) - return "", err + smsg := &models.Message{ + RoomID: channel.ID, + Msg: msg.Text, + PostMessage: models.PostMessage{ + Avatar: msg.Avatar, + Alias: msg.Username, + },   } - return "", nil -}   -func (b *Brocketchat) handleRocketHook() { - for { - message := b.rh.Receive() - b.Log.Debugf("Receiving from rockethook %#v", message) - // do not loop - if message.UserName == b.GetString("Nick") { - continue - } - b.Log.Debugf("<= Sending message from %s on %s to gateway", message.UserName, b.Account) - b.Remote <- config.Message{Text: message.Text, Username: message.UserName, Channel: message.ChannelName, Account: b.Account, UserID: message.UserID} + rmsg, err := b.c.SendMessage(smsg) + if rmsg == nil { + return "", err   } + return rmsg.ID, err  } diff --git a/go.mod b/go.mod index 1f8cb17..1320b25 100644 --- a/go.mod +++ b/go.mod @@ -36 +37 @@ module github.com/42wim/matterbridge  require (   github.com/42wim/go-gitter v0.0.0-20170828205020-017310c2d557   github.com/BurntSushi/toml v0.0.0-20170318202913-d94612f9fc14 // indirect + github.com/Jeffail/gabs v1.1.1 // indirect   github.com/Philipp15b/go-steam v1.0.1-0.20180818081528-681bd9573329   github.com/bwmarrin/discordgo v0.19.0   github.com/dfordsoft/golib v0.0.0-20180902042739-76ee6ab99bec @@ -106 +117 @@ require (   github.com/go-telegram-bot-api/telegram-bot-api v4.6.5-0.20181225215658-ec221ba9ea45+incompatible   github.com/golang/protobuf v0.0.0-20170613224224-e325f446bebc // indirect   github.com/google/gops v0.3.5 + github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4 // indirect   github.com/gopherjs/gopherjs v0.0.0-20180628210949-0892b62f0d9f // indirect   github.com/gorilla/schema v1.0.2   github.com/gorilla/websocket v1.4.0 @@ -236 +257 @@ require (   github.com/lrstanley/girc v0.0.0-20190102153329-c1e59a02f488   github.com/lusis/go-slackbot v0.0.0-20180109053408-401027ccfef5 // indirect   github.com/lusis/slack-test v0.0.0-20180109053238-3c758769bfa6 // indirect + github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d   github.com/matterbridge/go-xmpp v0.0.0-20180529212104-cd19799fba91   github.com/matterbridge/gomatrix v0.0.0-20190102230110-6f9631ca6dea   github.com/matterbridge/gozulipbot v0.0.0-20180507190239-b6bb12d33544 @@ -316 +347 @@ require (   github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect   github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474 // indirect   github.com/mrexodia/wray v0.0.0-20160318003008-78a2c1f284ff // indirect + github.com/nelsonken/gomf v0.0.0-20180504123937-a9dd2f9deae9   github.com/nicksnyder/go-i18n v1.4.0 // indirect   github.com/nlopes/slack v0.5.0   github.com/onsi/ginkgo v1.6.0 // indirect diff --git a/go.sum b/go.sum index c5aca26..e10bbb3 100644 --- a/go.sum +++ b/go.sum @@ -26 +28 @@ github.com/42wim/go-gitter v0.0.0-20170828205020-017310c2d557 h1:IZtuWGfzQnKnCSu  github.com/42wim/go-gitter v0.0.0-20170828205020-017310c2d557/go.mod h1:jL0YSXMs/txjtGJ4PWrmETOk6KUHMDPMshgQZlTeB3Y=  github.com/BurntSushi/toml v0.0.0-20170318202913-d94612f9fc14 h1:v/zr4ns/4sSahF9KBm4Uc933bLsEEv7LuT63CJ019yo=  github.com/BurntSushi/toml v0.0.0-20170318202913-d94612f9fc14/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Jeffail/gabs v1.1.1 h1:V0uzR08Hj22EX8+8QMhyI9sX2hwRu+/RJhJUmnwda/E= +github.com/Jeffail/gabs v1.1.1/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc=  github.com/Philipp15b/go-steam v1.0.1-0.20180818081528-681bd9573329 h1:xZBoq249G9MSt+XuY7sVQzcfONJ6IQuwpCK+KAaOpnY=  github.com/Philipp15b/go-steam v1.0.1-0.20180818081528-681bd9573329/go.mod h1:HuVM+sZFzumUdKPWiz+IlCMb4RdsKdT3T+nQBKL+sYg=  github.com/alexcesaro/log v0.0.0-20150915221235-61e686294e58 h1:MkpmYfld/S8kXqTYI68DfL8/hHXjHogL120Dy00TIxc= @@ -276 +298 @@ github.com/golang/protobuf v0.0.0-20170613224224-e325f446bebc h1:wdhDSKrkYy24mcf  github.com/golang/protobuf v0.0.0-20170613224224-e325f446bebc/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=  github.com/google/gops v0.3.5 h1:SIWvPLiYvy5vMwjxB3rVFTE4QBhUFj2KKWr3Xm7CKhw=  github.com/google/gops v0.3.5/go.mod h1:pMQgrscwEK/aUSW1IFSaBPbJX82FPHWaSoJw1axQfD0= +github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4 h1:4EZlYQIiyecYJlUbVkFXCXHz1QPhVXcHnQKAzBTPfQo= +github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4/go.mod h1:lEO7XoHJ/xNRBCxrn4h/CEB67h0kW1B0t4ooP2yrjUA=  github.com/gopherjs/gopherjs v0.0.0-20180628210949-0892b62f0d9f h1:FDM3EtwZLyhW48YRiyqjivNlNZjAObv4xt4NnJaU+NQ=  github.com/gopherjs/gopherjs v0.0.0-20180628210949-0892b62f0d9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=  github.com/gorilla/schema v1.0.2 h1:sAgNfOcNYvdDSrzGHVy9nzCQahG+qmsg+nE8dK85QRA= @@ -666 +708 @@ github.com/lusis/slack-test v0.0.0-20180109053238-3c758769bfa6 h1:iOAVXzZyXtW408  github.com/lusis/slack-test v0.0.0-20180109053238-3c758769bfa6/go.mod h1:sFlOUpQL1YcjhFVXhg1CG8ZASEs/Mf1oVb6H75JL/zg=  github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=  github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d h1:F+Sr+C0ojSlYQ37BLylQtSFmyQULe3jbAygcyXQ9mVs= +github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d/go.mod h1:c6MxwqHD+0HvtAJjsHMIdPCiAwGiQwPRPTp69ACMg8A=  github.com/matterbridge/go-xmpp v0.0.0-20180529212104-cd19799fba91 h1:KzDEcy8eDbTx881giW8a6llsAck3e2bJvMyKvh1IK+k=  github.com/matterbridge/go-xmpp v0.0.0-20180529212104-cd19799fba91/go.mod h1:ECDRehsR9TYTKCAsRS8/wLeOk6UUqDydw47ln7wG41Q=  github.com/matterbridge/gomatrix v0.0.0-20190102230110-6f9631ca6dea h1:kaADGqpK4gGO2BpzEyJrBxq2Jc57Rsar4i2EUxcACUc= @@ -886 +948 @@ github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474 h1:oKIteT  github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8=  github.com/mrexodia/wray v0.0.0-20160318003008-78a2c1f284ff h1:HLGD5/9UxxfEuO9DtP8gnTmNtMxbPyhYltfxsITel8g=  github.com/mrexodia/wray v0.0.0-20160318003008-78a2c1f284ff/go.mod h1:B8jLfIIPn2sKyWr0D7cL2v7tnrDD5z291s2Zypdu89E= +github.com/nelsonken/gomf v0.0.0-20180504123937-a9dd2f9deae9 h1:mp6tU1r0xLostUGLkTspf/9/AiHuVD7ptyXhySkDEsE= +github.com/nelsonken/gomf v0.0.0-20180504123937-a9dd2f9deae9/go.mod h1:A5SRAcpTemjGgIuBq6Kic2yHcoeUFWUinOAlMP/i9xo=  github.com/nicksnyder/go-i18n v1.4.0 h1:AgLl+Yq7kg5OYlzCgu9cKTZOyI4tD/NgukKqLqC8E+I=  github.com/nicksnyder/go-i18n v1.4.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q=  github.com/nlopes/slack v0.5.0 h1:NbIae8Kd0NpqaEI3iUrsuS0KbcEDhzhc939jLW5fNm0= diff --git a/matterbridge.toml.sample b/matterbridge.toml.sample index 42d20af..77f5b51 100644 --- a/matterbridge.toml.sample +++ b/matterbridge.toml.sample @@ -8936 +89321 @@ ShowTopicChange=false  #REQUIRED    [rocketchat.rockme] +#The rocketchat hostname. (prefix it with http or https) +#REQUIRED (when not using webhooks) +Server="https://yourrocketchatserver.domain.com:443" + +#login/pass of your bot. +#Use a dedicated user for this and not your own! +#REQUIRED (when not using webhooks) +Login="yourlogin" +Password="yourpass" + +#### Settings for webhook matterbridge. +#USE DEDICATED BOT USER WHEN POSSIBLE! This allows you to use advanced features like message editing/deleting and uploads +#You don't need to configure this, if you have configured the settings +#above. +  #Url is your incoming webhook url as specified in rocketchat  #Read #https://rocket.chat/docs/administrator-guides/integrations/#how-to-create-a-new-incoming-webhook  #See administration - integrations - new integration - incoming webhook @@ -9176 +9328 @@ NoTLS=false  #OPTIONAL (default false)  SkipTLSVerify=true   +#### End settings for webhook matterbridge. +  ## RELOADABLE SETTINGS  ## Settings below can be reloaded by editing the file