summaryrefslogtreecommitdiffstats
path: root/gateway
diff options
context:
space:
mode:
authorWim <wim@42.be>2016-09-18 19:21:15 +0200
committerWim <wim@42.be>2016-09-18 19:21:15 +0200
commit7baf386edea4c71919b257d99ca7f7e07897c412 (patch)
tree5a6f7f0f506c3ab2d15d91548b1d0479bb8fb1ba /gateway
parent6e410b096ef15e976f6a2d28f3412fe9e457f95a (diff)
downloadmatterbridge-msglm-7baf386edea4c71919b257d99ca7f7e07897c412.tar.gz
matterbridge-msglm-7baf386edea4c71919b257d99ca7f7e07897c412.tar.bz2
matterbridge-msglm-7baf386edea4c71919b257d99ca7f7e07897c412.zip
Refactor for more flexibility
* Move from gcfg to toml configuration because gcfg was too restrictive * Implemented gateway which has support multiple in and out bridges. * Allow for bridging the same bridges, which means eg you can now bridge between multiple mattermosts. * Support multiple gateways
Diffstat (limited to 'gateway')
-rw-r--r--gateway/gateway.go135
1 files changed, 135 insertions, 0 deletions
diff --git a/gateway/gateway.go b/gateway/gateway.go
new file mode 100644
index 00000000..54440d69
--- /dev/null
+++ b/gateway/gateway.go
@@ -0,0 +1,135 @@
+package gateway
+
+import (
+ "github.com/42wim/matterbridge/bridge"
+ "github.com/42wim/matterbridge/bridge/config"
+ log "github.com/Sirupsen/logrus"
+ "strings"
+)
+
+type Gateway struct {
+ *config.Config
+ MyConfig *config.Gateway
+ Bridges []bridge.Bridge
+ ChannelsOut map[string][]string
+ ChannelsIn map[string][]string
+ ignoreNicks map[string][]string
+ Name string
+}
+
+func New(cfg *config.Config, gateway *config.Gateway) error {
+ c := make(chan config.Message)
+ gw := &Gateway{}
+ gw.Name = gateway.Name
+ gw.Config = cfg
+ gw.MyConfig = gateway
+ for _, br := range gateway.In {
+ gw.Bridges = append(gw.Bridges, bridge.New(cfg, &br, c))
+ }
+ gw.mapChannels()
+ gw.mapIgnores()
+ for _, br := range gw.Bridges {
+ br.Connect()
+ for _, channel := range gw.ChannelsOut[br.FullOrigin()] {
+ br.JoinChannel(channel)
+ }
+ }
+ gw.handleReceive(c)
+ return nil
+}
+
+func (gw *Gateway) handleReceive(c chan config.Message) {
+ for {
+ select {
+ case msg := <-c:
+ for _, br := range gw.Bridges {
+ gw.handleMessage(msg, br)
+ }
+ }
+ }
+}
+
+func (gw *Gateway) mapChannels() error {
+ m := make(map[string][]string)
+ for _, br := range gw.MyConfig.Out {
+ m[br.Account] = append(m[br.Account], br.Channel)
+ }
+ gw.ChannelsOut = m
+ m = nil
+ m = make(map[string][]string)
+ for _, br := range gw.MyConfig.In {
+ m[br.Account] = append(m[br.Account], br.Channel)
+ }
+ gw.ChannelsIn = m
+ return nil
+}
+
+func (gw *Gateway) mapIgnores() {
+ m := make(map[string][]string)
+ for _, br := range gw.MyConfig.In {
+ accInfo := strings.Split(br.Account, ".")
+ m[br.Account] = strings.Fields(gw.Config.IRC[accInfo[1]].IgnoreNicks)
+ }
+ gw.ignoreNicks = m
+}
+
+func (gw *Gateway) getDestChannel(msg *config.Message, dest string) []string {
+ return gw.ChannelsOut[dest]
+}
+
+func (gw *Gateway) handleMessage(msg config.Message, dest bridge.Bridge) {
+ if gw.ignoreMessage(&msg) {
+ return
+ }
+ channels := gw.getDestChannel(&msg, dest.FullOrigin())
+ for _, channel := range channels {
+ // do not send the message to the bridge we come from if also the channel is the same
+ if msg.FullOrigin == dest.FullOrigin() && msg.Channel == channel {
+ log.Debug("continue", msg.Protocol, msg.Origin, dest.Protocol(), dest.Origin())
+ continue
+ }
+ msg.Channel = channel
+ if msg.Channel == "" {
+ log.Debug("empty channel")
+ return
+ }
+ gw.modifyMessage(&msg, dest)
+ log.Debugf("sending %#v from %s to %s", msg, msg.Origin, dest.Origin())
+ dest.Send(msg)
+ }
+}
+
+func (gw *Gateway) ignoreMessage(msg *config.Message) bool {
+ // should we discard messages ?
+ for _, entry := range gw.ignoreNicks[msg.FullOrigin] {
+ if msg.Username == entry {
+ return true
+ }
+ }
+ return false
+}
+
+func setNickFormat(msg *config.Message, format string) {
+ if format == "" {
+ msg.Username = msg.Protocol + "." + msg.Origin + "-" + msg.Username + ": "
+ return
+ }
+ msg.Username = strings.Replace(format, "{NICK}", msg.Username, -1)
+ msg.Username = strings.Replace(msg.Username, "{BRIDGE}", msg.Origin, -1)
+ msg.Username = strings.Replace(msg.Username, "{PROTOCOL}", msg.Protocol, -1)
+}
+
+func (gw *Gateway) modifyMessage(msg *config.Message, dest bridge.Bridge) {
+ switch dest.Protocol() {
+ case "irc":
+ setNickFormat(msg, gw.Config.IRC[dest.Origin()].RemoteNickFormat)
+ case "gitter":
+ setNickFormat(msg, gw.Config.Gitter[dest.Origin()].RemoteNickFormat)
+ case "xmpp":
+ setNickFormat(msg, gw.Config.Xmpp[dest.Origin()].RemoteNickFormat)
+ case "mattermost":
+ setNickFormat(msg, gw.Config.Mattermost[dest.Origin()].RemoteNickFormat)
+ case "slack":
+ setNickFormat(msg, gw.Config.Slack[dest.Origin()].RemoteNickFormat)
+ }
+}