5
0
mirror of https://github.com/cwinfo/matterbridge.git synced 2024-12-24 03:25:40 +00:00

Merge branch 'refactor'

This commit is contained in:
Wim 2016-11-13 23:09:06 +01:00
commit 4976338677
11 changed files with 178 additions and 274 deletions

View File

@ -11,35 +11,50 @@ 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
}

View File

@ -9,13 +9,11 @@ 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 {
@ -126,16 +124,11 @@ 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
}

View File

@ -11,8 +11,7 @@ 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
@ -25,12 +24,11 @@ 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
}
@ -72,10 +70,6 @@ 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 {
@ -84,18 +78,6 @@ 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)
@ -103,8 +85,7 @@ 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
}
@ -121,13 +102,13 @@ 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 {

View File

@ -8,13 +8,12 @@ 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
@ -24,12 +23,11 @@ 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
}
@ -47,10 +45,6 @@ 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)
@ -77,9 +71,9 @@ 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)
@ -89,18 +83,6 @@ 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)
@ -108,9 +90,8 @@ 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 {

View File

@ -19,11 +19,10 @@ 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
@ -33,14 +32,13 @@ 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
@ -93,43 +91,26 @@ 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))
}
@ -153,12 +134,12 @@ 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
}
@ -215,8 +196,8 @@ 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) {

View File

@ -26,12 +26,11 @@ 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
@ -41,13 +40,11 @@ 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
}
@ -80,10 +77,6 @@ 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 {
@ -92,21 +85,9 @@ 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
@ -144,8 +125,8 @@ 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}
}
}

View File

@ -25,8 +25,7 @@ type Bslack struct {
Plus bool
Remote chan config.Message
Users []slack.User
protocol string
origin string
Account string
si *slack.Info
channels []slack.Channel
}
@ -38,12 +37,11 @@ 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
}
@ -66,10 +64,6 @@ 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 {
@ -81,24 +75,12 @@ 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 {
@ -154,14 +136,14 @@ 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() {
@ -181,8 +163,8 @@ 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)}
}
}
}

View File

@ -10,12 +10,11 @@ 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
@ -25,12 +24,11 @@ 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
}
@ -48,31 +46,14 @@ 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
}
@ -128,8 +109,8 @@ 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:

View File

@ -11,55 +11,68 @@ 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
Name string
Message chan config.Message
}
func New(cfg *config.Config, gateway *config.Gateway) error {
c := make(chan config.Message)
func New(cfg *config.Config, gateway *config.Gateway) *Gateway {
gw := &Gateway{}
gw.Name = gateway.Name
gw.Config = cfg
gw.MyConfig = gateway
exists := make(map[string]bool)
for _, br := range append(gateway.In, gateway.Out...) {
if exists[br.Account] {
continue
}
log.Infof("Starting bridge: %s channel: %s", br.Account, br.Channel)
gw.Bridges = append(gw.Bridges, bridge.New(cfg, &br, c))
exists[br.Account] = true
}
gw.mapChannels()
//TODO fix mapIgnores
//gw.mapIgnores()
exists = make(map[string]bool)
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 {
err := br.Connect()
if err != nil {
log.Fatalf("Bridge %s failed to start: %v", br.FullOrigin(), err)
}
for _, channel := range append(gw.ChannelsOut[br.FullOrigin()], gw.ChannelsIn[br.FullOrigin()]...) {
if exists[br.FullOrigin()+channel] {
continue
}
log.Infof("%s: joining %s", br.FullOrigin(), channel)
br.JoinChannel(channel)
exists[br.FullOrigin()+channel] = true
if br.Account == cfg.Account {
return nil
}
}
log.Infof("Starting bridge: %s ", cfg.Account)
br := bridge.New(gw.Config, cfg, gw.Message)
gw.Bridges[cfg.Account] = br
err := br.Connect()
if err != nil {
return fmt.Errorf("Bridge %s failed to start: %v", br.Account, err)
}
exists := make(map[string]bool)
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.Account+channel] = true
}
}
gw.handleReceive(c)
return nil
}
func (gw *Gateway) handleReceive(c chan config.Message) {
func (gw *Gateway) Start() error {
gw.mapChannels()
for _, br := range append(gw.MyConfig.In, gw.MyConfig.Out...) {
err := gw.AddBridge(&br)
if err != nil {
return err
}
}
//TODO fix mapIgnores
//gw.mapIgnores()
go gw.handleReceive()
return nil
}
func (gw *Gateway) handleReceive() {
for {
select {
case msg := <-c:
case msg := <-gw.Message:
for _, br := range gw.Bridges {
gw.handleMessage(msg, br)
}
@ -92,7 +105,7 @@ 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]
@ -101,15 +114,15 @@ 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
@ -117,7 +130,8 @@ 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)
@ -127,7 +141,7 @@ 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
}
@ -135,17 +149,26 @@ 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
}

View File

@ -10,7 +10,7 @@ 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
@ -19,6 +19,7 @@ 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
@ -26,15 +27,15 @@ 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)
}
}
@ -59,38 +60,24 @@ func (gw *SameChannelGateway) handleMessage(msg config.Message, dest bridge.Brid
return
}
// 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 (%s) to %s (%s)", msg, msg.FullOrigin, msg.Channel, dest.FullOrigin(), msg.Channel)
gw.modifyUsername(&msg, dest)
log.Debugf("Sending %#v from %s (%s) to %s (%s)", msg, msg.Account, msg.Channel, dest.Account, msg.Channel)
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
}
func (gw *SameChannelGateway) validChannel(channel string) bool {

View File

@ -49,12 +49,11 @@ func main() {
continue
}
fmt.Printf("starting gateway %#v\n", gw.Name)
go func(gw config.Gateway) {
err := gateway.New(cfg, &gw)
if err != nil {
log.Debugf("starting gateway failed %#v", err)
}
}(gw)
g := gateway.New(cfg, &gw)
err := g.Start()
if err != nil {
log.Debugf("starting gateway failed %#v", err)
}
}
select {}
}