Thumbnail

rani/matterbridge.git

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

commit 5131ecc511e9856a6646d4b3bd2f4c14df85a300 Author: Wim <wim@42.be> Date: Sun Nov 13 23:06:37 2016 +0000 Refactor diff --git a/bridge/bridge.go b/bridge/bridge.go index 3d53224..4a422c7 100644 --- a/bridge/bridge.go +++ b/bridge/bridge.go @@ -1135 +1150 @@ import (   "strings"  )   -type Bridge interface { +type Bridger interface {   Send(msg config.Message) error - Name() string   Connect() error - FullOrigin() string - Origin() string - Protocol() string   JoinChannel(channel string) error  }   -func New(cfg *config.Config, bridge *config.Bridge, c chan config.Message) Bridge { +type Bridge struct { + Config config.Protocol + Bridger + Name string + Account string + Protocol string +} + +func New(cfg *config.Config, bridge *config.Bridge, c chan config.Message) *Bridge { + b := new(Bridge)   accInfo := strings.Split(bridge.Account, ".")   protocol := accInfo[0]   name := accInfo[1] + b.Name = name + b.Protocol = protocol + b.Account = bridge.Account +   // override config from environment   config.OverrideCfgFromEnv(cfg, protocol, name)   switch protocol {   case "mattermost": - return bmattermost.New(cfg.Mattermost[name], name, c) + b.Config = cfg.Mattermost[name] + b.Bridger = bmattermost.New(cfg.Mattermost[name], bridge.Account, c)   case "irc": - return birc.New(cfg.IRC[name], name, c) + b.Config = cfg.IRC[name] + b.Bridger = birc.New(cfg.IRC[name], bridge.Account, c)   case "gitter": - return bgitter.New(cfg.Gitter[name], name, c) + b.Config = cfg.Gitter[name] + b.Bridger = bgitter.New(cfg.Gitter[name], bridge.Account, c)   case "slack": - return bslack.New(cfg.Slack[name], name, c) + b.Config = cfg.Slack[name] + b.Bridger = bslack.New(cfg.Slack[name], bridge.Account, c)   case "xmpp": - return bxmpp.New(cfg.Xmpp[name], name, c) + b.Config = cfg.Xmpp[name] + b.Bridger = bxmpp.New(cfg.Xmpp[name], bridge.Account, c)   case "discord": - return bdiscord.New(cfg.Discord[name], name, c) + b.Config = cfg.Discord[name] + b.Bridger = bdiscord.New(cfg.Discord[name], bridge.Account, c)   } - return nil + return b  } diff --git a/bridge/config/config.go b/bridge/config/config.go index 1575bff..c577e34 100644 --- a/bridge/config/config.go +++ b/bridge/config/config.go @@ -913 +911 @@ import (  )    type Message struct { - Text string - Channel string - Username string - Origin string - FullOrigin string - Protocol string - Avatar string + Text string + Channel string + Username string + Avatar string + Account string  }    type Protocol struct { @@ -12616 +12411 @@ func OverrideCfgFromEnv(cfg *Config, protocol string, account string) {    func GetIconURL(msg *Message, cfg *Protocol) string {   iconURL := cfg.IconURL + info := strings.Split(msg.Account, ".") + protocol := info[0] + name := info[1]   iconURL = strings.Replace(iconURL, "{NICK}", msg.Username, -1) - iconURL = strings.Replace(iconURL, "{BRIDGE}", msg.Origin, -1) - iconURL = strings.Replace(iconURL, "{PROTOCOL}", msg.Protocol, -1) + iconURL = strings.Replace(iconURL, "{BRIDGE}", name, -1) + iconURL = strings.Replace(iconURL, "{PROTOCOL}", protocol, -1)   return iconURL  } - -func GetNick(msg *Message, cfg *Protocol) string { - nick := cfg.RemoteNickFormat - nick = strings.Replace(nick, "{NICK}", msg.Username, -1) - nick = strings.Replace(nick, "{BRIDGE}", msg.Origin, -1) - nick = strings.Replace(nick, "{PROTOCOL}", msg.Protocol, -1) - return nick -} diff --git a/bridge/discord/discord.go b/bridge/discord/discord.go index 62bc85c..4497ce3 100644 --- a/bridge/discord/discord.go +++ b/bridge/discord/discord.go @@ -118 +117 @@ type bdiscord struct {   c *discordgo.Session   Config *config.Protocol   Remote chan config.Message - protocol string - origin string + Account string   Channels []*discordgo.Channel   Nick string   UseChannelID bool @@ -2512 +2411 @@ func init() {   flog = log.WithFields(log.Fields{"module": protocol})  }   -func New(cfg config.Protocol, origin string, c chan config.Message) *bdiscord { +func New(cfg config.Protocol, account string, c chan config.Message) *bdiscord {   b := &bdiscord{}   b.Config = &cfg   b.Remote = c - b.protocol = protocol - b.origin = origin + b.Account = account   return b  }   @@ -7210 +706 @@ func (b *bdiscord) Connect() error {   return nil  }   -func (b *bdiscord) FullOrigin() string { - return b.protocol + "." + b.origin -} -  func (b *bdiscord) JoinChannel(channel string) error {   idcheck := strings.Split(channel, "ID:")   if len(idcheck) > 1 { @@ -8418 +786 @@ func (b *bdiscord) JoinChannel(channel string) error {   return nil  }   -func (b *bdiscord) Name() string { - return b.protocol + "." + b.origin -} - -func (b *bdiscord) Protocol() string { - return b.protocol -} - -func (b *bdiscord) Origin() string { - return b.origin -} -  func (b *bdiscord) Send(msg config.Message) error {   flog.Debugf("Receiving %#v", msg)   channelID := b.getChannelID(msg.Channel) @@ -1038 +857 @@ func (b *bdiscord) Send(msg config.Message) error {   flog.Errorf("Could not find channelID for %v", msg.Channel)   return nil   } - nick := config.GetNick(&msg, b.Config) - b.c.ChannelMessageSend(channelID, nick+msg.Text) + b.c.ChannelMessageSend(channelID, msg.Username+msg.Text)   return nil  }   @@ -12113 +10213 @@ func (b *bdiscord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreat   if m.Content == "" {   return   } - flog.Debugf("Sending message from %s on %s to gateway", m.Author.Username, b.FullOrigin()) + flog.Debugf("Sending message from %s on %s to gateway", m.Author.Username, b.Account)   channelName := b.getChannelName(m.ChannelID)   if b.UseChannelID {   channelName = "ID:" + m.ChannelID   }   b.Remote <- config.Message{Username: m.Author.Username, Text: m.ContentWithMentionsReplaced(), Channel: channelName, - Origin: b.origin, Protocol: b.protocol, FullOrigin: b.FullOrigin(), Avatar: "https://cdn.discordapp.com/avatars/" + m.Author.ID + "/" + m.Author.Avatar + ".jpg"} + Account: b.Account, Avatar: "https://cdn.discordapp.com/avatars/" + m.Author.ID + "/" + m.Author.Avatar + ".jpg"}  }    func (b *bdiscord) getChannelID(name string) string { diff --git a/bridge/gitter/gitter.go b/bridge/gitter/gitter.go index 176b6ce..95375b1 100644 --- a/bridge/gitter/gitter.go +++ b/bridge/gitter/gitter.go @@ -813 +812 @@ import (  )    type Bgitter struct { - c *gitter.Gitter - Config *config.Protocol - Remote chan config.Message - protocol string - origin string - Users []gitter.User - Rooms []gitter.Room + c *gitter.Gitter + Config *config.Protocol + Remote chan config.Message + Account string + Users []gitter.User + Rooms []gitter.Room  }    var flog *log.Entry @@ -2412 +2311 @@ func init() {   flog = log.WithFields(log.Fields{"module": protocol})  }   -func New(cfg config.Protocol, origin string, c chan config.Message) *Bgitter { +func New(cfg config.Protocol, account string, c chan config.Message) *Bgitter {   b := &Bgitter{}   b.Config = &cfg   b.Remote = c - b.protocol = protocol - b.origin = origin + b.Account = account   return b  }   @@ -4710 +456 @@ func (b *Bgitter) Connect() error {   return nil  }   -func (b *Bgitter) FullOrigin() string { - return b.protocol + "." + b.origin -} -  func (b *Bgitter) JoinChannel(channel string) error {   room := channel   roomID := b.getRoomID(room) @@ -779 +719 @@ func (b *Bgitter) JoinChannel(channel string) error {   case *gitter.MessageReceived:   // check for ZWSP to see if it's not an echo   if !strings.HasSuffix(ev.Message.Text, "​") { - flog.Debugf("Sending message from %s on %s to gateway", ev.Message.From.Username, b.FullOrigin()) + flog.Debugf("Sending message from %s on %s to gateway", ev.Message.From.Username, b.Account)   b.Remote <- config.Message{Username: ev.Message.From.Username, Text: ev.Message.Text, Channel: room, - Origin: b.origin, Protocol: b.protocol, FullOrigin: b.FullOrigin(), Avatar: b.getAvatar(ev.Message.From.Username)} + Account: b.Account, Avatar: b.getAvatar(ev.Message.From.Username)}   }   case *gitter.GitterConnectionClosed:   flog.Errorf("connection with gitter closed for room %s", room) @@ -8918 +836 @@ func (b *Bgitter) JoinChannel(channel string) error {   return nil  }   -func (b *Bgitter) Name() string { - return b.protocol + "." + b.origin -} - -func (b *Bgitter) Protocol() string { - return b.protocol -} - -func (b *Bgitter) Origin() string { - return b.origin -} -  func (b *Bgitter) Send(msg config.Message) error {   flog.Debugf("Receiving %#v", msg)   roomID := b.getRoomID(msg.Channel) @@ -1089 +908 @@ func (b *Bgitter) Send(msg config.Message) error {   flog.Errorf("Could not find roomID for %v", msg.Channel)   return nil   } - nick := config.GetNick(&msg, b.Config)   // add ZWSP because gitter echoes our own messages - return b.c.SendMessage(roomID, nick+msg.Text+" ​") + return b.c.SendMessage(roomID, msg.Username+msg.Text+" ​")  }    func (b *Bgitter) getRoomID(channel string) string { diff --git a/bridge/irc/irc.go b/bridge/irc/irc.go index 61b55da..ea139be 100644 --- a/bridge/irc/irc.go +++ b/bridge/irc/irc.go @@ -1911 +1910 @@ type Birc struct {   Nick string   names map[string][]string   Config *config.Protocol - origin string - protocol string   Remote chan config.Message   connected chan struct{}   Local chan config.Message // local queue for flood control + Account string  }    var flog *log.Entry @@ -3314 +3213 @@ func init() {   flog = log.WithFields(log.Fields{"module": protocol})  }   -func New(cfg config.Protocol, origin string, c chan config.Message) *Birc { +func New(cfg config.Protocol, account string, c chan config.Message) *Birc {   b := &Birc{}   b.Config = &cfg   b.Nick = b.Config.Nick   b.Remote = c   b.names = make(map[string][]string) - b.origin = origin - b.protocol = protocol + b.Account = account   b.connected = make(chan struct{})   if b.Config.MessageDelay == 0 {   b.Config.MessageDelay = 1300 @@ -9343 +9126 @@ func (b *Birc) Connect() error {   return nil  }   -func (b *Birc) FullOrigin() string { - return b.protocol + "." + b.origin -} -  func (b *Birc) JoinChannel(channel string) error {   b.i.Join(channel)   return nil  }   -func (b *Birc) Name() string { - return b.protocol + "." + b.origin -} - -func (b *Birc) Protocol() string { - return b.protocol -} - -func (b *Birc) Origin() string { - return b.origin -} -  func (b *Birc) Send(msg config.Message) error {   flog.Debugf("Receiving %#v", msg) - if msg.FullOrigin == b.FullOrigin() { + if msg.Account == b.Account {   return nil   }   if strings.HasPrefix(msg.Text, "!") {   b.Command(&msg)   return nil   } - nick := config.GetNick(&msg, b.Config)   for _, text := range strings.Split(msg.Text, "\n") {   if len(b.Local) < b.Config.MessageQueue {   if len(b.Local) == b.Config.MessageQueue-1 {   text = text + " <message clipped>"   } - b.Local <- config.Message{Text: text, Username: nick, Channel: msg.Channel} + b.Local <- config.Message{Text: text, Username: msg.Username, Channel: msg.Channel}   } else {   flog.Debugf("flooding, dropping message (queue at %d)", len(b.Local))   } @@ -15312 +13412 @@ func (b *Birc) endNames(event *irc.Event) {   continued := false   for len(b.names[channel]) > maxNamesPerPost {   b.Remote <- config.Message{Username: b.Nick, Text: b.formatnicks(b.names[channel][0:maxNamesPerPost], continued), - Channel: channel, Origin: b.origin, Protocol: b.protocol, FullOrigin: b.FullOrigin()} + Channel: channel, Account: b.Account}   b.names[channel] = b.names[channel][maxNamesPerPost:]   continued = true   } - b.Remote <- config.Message{Username: b.Nick, Text: b.formatnicks(b.names[channel], continued), Channel: channel, - Origin: b.origin, Protocol: b.protocol, FullOrigin: b.FullOrigin()} + b.Remote <- config.Message{Username: b.Nick, Text: b.formatnicks(b.names[channel], continued), + Channel: channel, Account: b.Account}   b.names[channel] = nil  }   @@ -2158 +1968 @@ func (b *Birc) handlePrivMsg(event *irc.Event) {   // strip IRC colors   re := regexp.MustCompile(`[[:cntrl:]](\d+,|)\d+`)   msg = re.ReplaceAllString(msg, "") - flog.Debugf("Sending message from %s on %s to gateway", event.Arguments[0], b.FullOrigin()) - b.Remote <- config.Message{Username: event.Nick, Text: msg, Channel: event.Arguments[0], Origin: b.origin, Protocol: b.protocol, FullOrigin: b.FullOrigin()} + flog.Debugf("Sending message from %s on %s to gateway", event.Arguments[0], b.Account) + b.Remote <- config.Message{Username: event.Nick, Text: msg, Channel: event.Arguments[0], Account: b.Account}  }    func (b *Birc) handleTopicWhoTime(event *irc.Event) { diff --git a/bridge/mattermost/mattermost.go b/bridge/mattermost/mattermost.go index 7f7340b..51d8f20 100644 --- a/bridge/mattermost/mattermost.go +++ b/bridge/mattermost/mattermost.go @@ -2612 +2611 @@ type MMMessage struct {  type Bmattermost struct {   MMhook   MMapi - Config *config.Protocol - Remote chan config.Message - name string - origin string - protocol string - TeamId string + Config *config.Protocol + Remote chan config.Message + name string + TeamId string + Account string  }    var flog *log.Entry @@ -4113 +4011 @@ func init() {   flog = log.WithFields(log.Fields{"module": protocol})  }   -func New(cfg config.Protocol, origin string, c chan config.Message) *Bmattermost { +func New(cfg config.Protocol, account string, c chan config.Message) *Bmattermost {   b := &Bmattermost{}   b.Config = &cfg - b.origin = origin   b.Remote = c - b.protocol = "mattermost" - b.name = cfg.Name + b.Account = account   b.mmMap = make(map[string]string)   return b  } @@ -8010 +776 @@ func (b *Bmattermost) Connect() error {   return nil  }   -func (b *Bmattermost) FullOrigin() string { - return b.protocol + "." + b.origin -} -  func (b *Bmattermost) JoinChannel(channel string) error {   // we can only join channels using the API   if b.Config.UseAPI { @@ -9221 +859 @@ func (b *Bmattermost) JoinChannel(channel string) error {   return nil  }   -func (b *Bmattermost) Name() string { - return b.protocol + "." + b.origin -} - -func (b *Bmattermost) Origin() string { - return b.origin -} - -func (b *Bmattermost) Protocol() string { - return b.protocol -} -  func (b *Bmattermost) Send(msg config.Message) error {   flog.Debugf("Receiving %#v", msg) - nick := config.GetNick(&msg, b.Config) + nick := msg.Username   message := msg.Text   channel := msg.Channel   @@ -1448 +1258 @@ func (b *Bmattermost) handleMatter() {   go b.handleMatterHook(mchan)   }   for message := range mchan { - flog.Debugf("Sending message from %s on %s to gateway", message.Username, b.FullOrigin()) - b.Remote <- config.Message{Text: message.Text, Username: message.Username, Channel: message.Channel, Origin: b.origin, Protocol: b.protocol, FullOrigin: b.FullOrigin()} + flog.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.Channel, Account: b.Account}   }  }   diff --git a/bridge/slack/slack.go b/bridge/slack/slack.go index f700aee..159204d 100644 --- a/bridge/slack/slack.go +++ b/bridge/slack/slack.go @@ -258 +257 @@ type Bslack struct {   Plus bool   Remote chan config.Message   Users []slack.User - protocol string - origin string + Account string   si *slack.Info   channels []slack.Channel  } @@ -3812 +3711 @@ func init() {   flog = log.WithFields(log.Fields{"module": protocol})  }   -func New(cfg config.Protocol, origin string, c chan config.Message) *Bslack { +func New(cfg config.Protocol, account string, c chan config.Message) *Bslack {   b := &Bslack{}   b.Config = &cfg   b.Remote = c - b.protocol = protocol - b.origin = origin + b.Account = account   return b  }   @@ -6610 +646 @@ func (b *Bslack) Connect() error {   return nil  }   -func (b *Bslack) FullOrigin() string { - return b.protocol + "." + b.origin -} -  func (b *Bslack) JoinChannel(channel string) error {   // we can only join channels using the API   if b.Config.UseAPI { @@ -8124 +7512 @@ func (b *Bslack) JoinChannel(channel string) error {   return nil  }   -func (b *Bslack) Name() string { - return b.protocol + "." + b.origin -} - -func (b *Bslack) Protocol() string { - return b.protocol -} - -func (b *Bslack) Origin() string { - return b.origin -} -  func (b *Bslack) Send(msg config.Message) error {   flog.Debugf("Receiving %#v", msg) - if msg.FullOrigin == b.FullOrigin() { + if msg.Account == b.Account {   return nil   } - nick := config.GetNick(&msg, b.Config) + nick := msg.Username   message := msg.Text   channel := msg.Channel   if b.Config.PrefixMessagesWithNick { @@ -15414 +13614 @@ func (b *Bslack) getAvatar(user string) string {    func (b *Bslack) getChannelByName(name string) (*slack.Channel, error) {   if b.channels == nil { - return nil, fmt.Errorf("%s: channel %s not found (no channels found)", b.FullOrigin(), name) + return nil, fmt.Errorf("%s: channel %s not found (no channels found)", b.Account, name)   }   for _, channel := range b.channels {   if channel.Name == name {   return &channel, nil   }   } - return nil, fmt.Errorf("%s: channel %s not found", b.FullOrigin(), name) + return nil, fmt.Errorf("%s: channel %s not found", b.Account, name)  }    func (b *Bslack) handleSlack() { @@ -1818 +1638 @@ func (b *Bslack) handleSlack() {   }   texts := strings.Split(message.Text, "\n")   for _, text := range texts { - flog.Debugf("Sending message from %s on %s to gateway", message.Username, b.FullOrigin()) - b.Remote <- config.Message{Text: text, Username: message.Username, Channel: message.Channel, Origin: b.origin, Protocol: b.protocol, FullOrigin: b.FullOrigin(), Avatar: b.getAvatar(message.Username)} + flog.Debugf("Sending message from %s on %s to gateway", message.Username, b.Account) + b.Remote <- config.Message{Text: text, Username: message.Username, Channel: message.Channel, Account: b.Account, Avatar: b.getAvatar(message.Username)}   }   }  } diff --git a/bridge/xmpp/xmpp.go b/bridge/xmpp/xmpp.go index 51237a0..f57fa51 100644 --- a/bridge/xmpp/xmpp.go +++ b/bridge/xmpp/xmpp.go @@ -1012 +1011 @@ import (  )    type Bxmpp struct { - xc *xmpp.Client - xmppMap map[string]string - Config *config.Protocol - origin string - protocol string - Remote chan config.Message + xc *xmpp.Client + xmppMap map[string]string + Config *config.Protocol + Remote chan config.Message + Account string  }    var flog *log.Entry @@ -2512 +2411 @@ func init() {   flog = log.WithFields(log.Fields{"module": protocol})  }   -func New(cfg config.Protocol, origin string, c chan config.Message) *Bxmpp { +func New(cfg config.Protocol, account string, c chan config.Message) *Bxmpp {   b := &Bxmpp{}   b.xmppMap = make(map[string]string)   b.Config = &cfg - b.protocol = protocol - b.origin = origin + b.Account = account   b.Remote = c   return b  } @@ -4831 +4614 @@ func (b *Bxmpp) Connect() error {   return nil  }   -func (b *Bxmpp) FullOrigin() string { - return b.protocol + "." + b.origin -} -  func (b *Bxmpp) JoinChannel(channel string) error {   b.xc.JoinMUCNoHistory(channel+"@"+b.Config.Muc, b.Config.Nick)   return nil  }   -func (b *Bxmpp) Name() string { - return b.protocol + "." + b.origin -} - -func (b *Bxmpp) Protocol() string { - return b.protocol -} - -func (b *Bxmpp) Origin() string { - return b.origin -} -  func (b *Bxmpp) Send(msg config.Message) error {   flog.Debugf("Receiving %#v", msg) - nick := config.GetNick(&msg, b.Config) - b.xc.Send(xmpp.Chat{Type: "groupchat", Remote: msg.Channel + "@" + b.Config.Muc, Text: nick + msg.Text}) + b.xc.Send(xmpp.Chat{Type: "groupchat", Remote: msg.Channel + "@" + b.Config.Muc, Text: msg.Username + msg.Text})   return nil  }   @@ -1288 +1098 @@ func (b *Bxmpp) handleXmpp() error {   nick = s[1]   }   if nick != b.Config.Nick { - flog.Debugf("Sending message from %s on %s to gateway", nick, b.FullOrigin()) - b.Remote <- config.Message{Username: nick, Text: v.Text, Channel: channel, Origin: b.origin, Protocol: b.protocol, FullOrigin: b.FullOrigin()} + flog.Debugf("Sending message from %s on %s to gateway", nick, b.Account) + b.Remote <- config.Message{Username: nick, Text: v.Text, Channel: channel, Account: b.Account}   }   }   case xmpp.Presence: diff --git a/gateway/gateway.go b/gateway/gateway.go index 07fcdaf..580e129 100644 --- a/gateway/gateway.go +++ b/gateway/gateway.go @@ -118 +119 @@ import (    type Gateway struct {   *config.Config - MyConfig *config.Gateway - Bridges []bridge.Bridge + MyConfig *config.Gateway + //Bridges []*bridge.Bridge + Bridges map[string]*bridge.Bridge   ChannelsOut map[string][]string   ChannelsIn map[string][]string   ignoreNicks map[string][]string @@ -2628 +2729 @@ func New(cfg *config.Config, gateway *config.Gateway) *Gateway {   gw.Config = cfg   gw.MyConfig = gateway   gw.Message = make(chan config.Message) + gw.Bridges = make(map[string]*bridge.Bridge)   return gw  }    func (gw *Gateway) AddBridge(cfg *config.Bridge) error {   for _, br := range gw.Bridges { - if br.FullOrigin() == cfg.Account { + if br.Account == cfg.Account {   return nil   }   }   log.Infof("Starting bridge: %s ", cfg.Account)   br := bridge.New(gw.Config, cfg, gw.Message) - gw.Bridges = append(gw.Bridges, br) + gw.Bridges[cfg.Account] = br   err := br.Connect()   if err != nil { - return fmt.Errorf("Bridge %s failed to start: %v", br.FullOrigin(), err) + return fmt.Errorf("Bridge %s failed to start: %v", br.Account, err)   }   exists := make(map[string]bool) - for _, channel := range append(gw.ChannelsOut[br.FullOrigin()], gw.ChannelsIn[br.FullOrigin()]...) { - if !exists[br.FullOrigin()+channel] { - log.Infof("%s: joining %s", br.FullOrigin(), channel) + for _, channel := range append(gw.ChannelsOut[br.Account], gw.ChannelsIn[br.Account]...) { + if !exists[br.Account+channel] { + log.Infof("%s: joining %s", br.Account, channel)   br.JoinChannel(channel) - exists[br.FullOrigin()+channel] = true + exists[br.Account+channel] = true   }   }   return nil @@ -1037 +1057 @@ func (gw *Gateway) mapIgnores() {  }    func (gw *Gateway) getDestChannel(msg *config.Message, dest string) []string { - channels := gw.ChannelsIn[msg.FullOrigin] + channels := gw.ChannelsIn[msg.Account]   for _, channel := range channels {   if channel == msg.Channel {   return gw.ChannelsOut[dest] @@ -11215 +11415 @@ func (gw *Gateway) getDestChannel(msg *config.Message, dest string) []string {   return []string{}  }   -func (gw *Gateway) handleMessage(msg config.Message, dest bridge.Bridge) { +func (gw *Gateway) handleMessage(msg config.Message, dest *bridge.Bridge) {   if gw.ignoreMessage(&msg) {   return   }   originchannel := msg.Channel - channels := gw.getDestChannel(&msg, dest.FullOrigin()) + channels := gw.getDestChannel(&msg, dest.Account)   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() && channel == originchannel { + if msg.Account == dest.Account && channel == originchannel {   continue   }   msg.Channel = channel @@ -1287 +1308 @@ func (gw *Gateway) handleMessage(msg config.Message, dest bridge.Bridge) {   log.Debug("empty channel")   return   } - log.Debugf("Sending %#v from %s (%s) to %s (%s)", msg, msg.FullOrigin, originchannel, dest.FullOrigin(), channel) + log.Debugf("Sending %#v from %s (%s) to %s (%s)", msg, msg.Account, originchannel, dest.Account, channel) + gw.modifyUsername(&msg, dest)   err := dest.Send(msg)   if err != nil {   fmt.Println(err) @@ -1387 +1417 @@ func (gw *Gateway) handleMessage(msg config.Message, dest bridge.Bridge) {    func (gw *Gateway) ignoreMessage(msg *config.Message) bool {   // should we discard messages ? - for _, entry := range gw.ignoreNicks[msg.FullOrigin] { + for _, entry := range gw.ignoreNicks[msg.Account] {   if msg.Username == entry {   return true   } @@ -14617 +14926 @@ func (gw *Gateway) ignoreMessage(msg *config.Message) bool {   return false  }   -func (gw *Gateway) modifyMessage(msg *config.Message, dest bridge.Bridge) { +func (gw *Gateway) modifyMessage(msg *config.Message, dest *bridge.Bridge) {   val := reflect.ValueOf(gw.Config).Elem()   for i := 0; i < val.NumField(); i++ {   typeField := val.Type().Field(i)   // look for the protocol map (both lowercase) - if strings.ToLower(typeField.Name) == dest.Protocol() { + if strings.ToLower(typeField.Name) == dest.Protocol {   // get the Protocol struct from the map - protoCfg := val.Field(i).MapIndex(reflect.ValueOf(dest.Origin())) + protoCfg := val.Field(i).MapIndex(reflect.ValueOf(dest.Name))   //config.SetNickFormat(msg, protoCfg.Interface().(config.Protocol)) - val.Field(i).SetMapIndex(reflect.ValueOf(dest.Origin()), protoCfg) + val.Field(i).SetMapIndex(reflect.ValueOf(dest.Name), protoCfg)   break   }   }  } + +func (gw *Gateway) modifyUsername(msg *config.Message, dest *bridge.Bridge) { + br := gw.Bridges[msg.Account] + nick := dest.Config.RemoteNickFormat + nick = strings.Replace(nick, "{NICK}", msg.Username, -1) + nick = strings.Replace(nick, "{BRIDGE}", br.Name, -1) + nick = strings.Replace(nick, "{PROTOCOL}", br.Protocol, -1) + msg.Username = nick +} diff --git a/gateway/samechannel/samechannel.go b/gateway/samechannel/samechannel.go index 5cdd59a..23c4152 100644 --- a/gateway/samechannel/samechannel.go +++ b/gateway/samechannel/samechannel.go @@ -107 +107 @@ import (  type SameChannelGateway struct {   *config.Config   MyConfig *config.SameChannelGateway - Bridges []bridge.Bridge + Bridges map[string]*bridge.Bridge   Channels []string   ignoreNicks map[string][]string   Name string @@ -196 +197 @@ type SameChannelGateway struct {  func New(cfg *config.Config, gateway *config.SameChannelGateway) error {   c := make(chan config.Message)   gw := &SameChannelGateway{} + gw.Bridges = make(map[string]*bridge.Bridge)   gw.Name = gateway.Name   gw.Config = cfg   gw.MyConfig = gateway @@ -2615 +2715 @@ func New(cfg *config.Config, gateway *config.SameChannelGateway) error {   for _, account := range gateway.Accounts {   br := config.Bridge{Account: account}   log.Infof("Starting bridge: %s", account) - gw.Bridges = append(gw.Bridges, bridge.New(cfg, &br, c)) + gw.Bridges[account] = bridge.New(cfg, &br, c)   }   for _, br := range gw.Bridges {   err := br.Connect()   if err != nil { - log.Fatalf("Bridge %s failed to start: %v", br.FullOrigin(), err) + log.Fatalf("Bridge %s failed to start: %v", br.Account, err)   }   for _, channel := range gw.Channels { - log.Infof("%s: joining %s", br.FullOrigin(), channel) + log.Infof("%s: joining %s", br.Account, channel)   br.JoinChannel(channel)   }   } @@ -5338 +5424 @@ func (gw *SameChannelGateway) handleReceive(c chan config.Message) {   }  }   -func (gw *SameChannelGateway) handleMessage(msg config.Message, dest bridge.Bridge) { +func (gw *SameChannelGateway) handleMessage(msg config.Message, dest *bridge.Bridge) {   // do not send the message to the bridge we come from if also the channel is the same - if msg.FullOrigin == dest.FullOrigin() { + if msg.Account == dest.Account {   return   } - gw.modifyMessage(&msg, dest) - log.Debugf("Sending %#v from %s to %s", msg, msg.FullOrigin, dest.FullOrigin()) + gw.modifyUsername(&msg, dest) + log.Debugf("Sending %#v from %s to %s", msg, msg.Account, dest.Account)   err := dest.Send(msg)   if err != nil {   log.Error(err)   }  }   -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 *SameChannelGateway) modifyMessage(msg *config.Message, dest bridge.Bridge) { - switch dest.Protocol() { - case "irc": - setNickFormat(msg, gw.Config.IRC[dest.Origin()].RemoteNickFormat) - case "mattermost": - setNickFormat(msg, gw.Config.Mattermost[dest.Origin()].RemoteNickFormat) - case "slack": - setNickFormat(msg, gw.Config.Slack[dest.Origin()].RemoteNickFormat) - case "discord": - setNickFormat(msg, gw.Config.Discord[dest.Origin()].RemoteNickFormat) - } +func (gw *SameChannelGateway) modifyUsername(msg *config.Message, dest *bridge.Bridge) { + br := gw.Bridges[msg.Account] + nick := dest.Config.RemoteNickFormat + nick = strings.Replace(nick, "{NICK}", msg.Username, -1) + nick = strings.Replace(nick, "{BRIDGE}", br.Name, -1) + nick = strings.Replace(nick, "{PROTOCOL}", br.Protocol, -1) + msg.Username = nick  }