mirror of
				https://github.com/42wim/matterbridge.git
				synced 2025-10-31 05:47:24 +01:00 
			
		
		
		
	Merge branch 'status'
This commit is contained in:
		
						commit
						7558a2162e
					
				| @ -10,6 +10,8 @@ import ( | ||||
| 	"github.com/42wim/matterbridge/bridge/slack" | ||||
| 	"github.com/42wim/matterbridge/bridge/telegram" | ||||
| 	"github.com/42wim/matterbridge/bridge/xmpp" | ||||
| 	log "github.com/Sirupsen/logrus" | ||||
| 
 | ||||
| 	"strings" | ||||
| ) | ||||
| 
 | ||||
| @ -17,18 +19,23 @@ type Bridger interface { | ||||
| 	Send(msg config.Message) error | ||||
| 	Connect() error | ||||
| 	JoinChannel(channel string) error | ||||
| 	Disconnect() error | ||||
| } | ||||
| 
 | ||||
| type Bridge struct { | ||||
| 	Config config.Protocol | ||||
| 	Bridger | ||||
| 	Name     string | ||||
| 	Account  string | ||||
| 	Protocol string | ||||
| 	Name        string | ||||
| 	Account     string | ||||
| 	Protocol    string | ||||
| 	ChannelsIn  map[string]config.ChannelOptions | ||||
| 	ChannelsOut map[string]config.ChannelOptions | ||||
| } | ||||
| 
 | ||||
| func New(cfg *config.Config, bridge *config.Bridge, c chan config.Message) *Bridge { | ||||
| 	b := new(Bridge) | ||||
| 	b.ChannelsIn = make(map[string]config.ChannelOptions) | ||||
| 	b.ChannelsOut = make(map[string]config.ChannelOptions) | ||||
| 	accInfo := strings.Split(bridge.Account, ".") | ||||
| 	protocol := accInfo[0] | ||||
| 	name := accInfo[1] | ||||
| @ -66,3 +73,27 @@ func New(cfg *config.Config, bridge *config.Bridge, c chan config.Message) *Brid | ||||
| 	} | ||||
| 	return b | ||||
| } | ||||
| 
 | ||||
| func (b *Bridge) JoinChannels() error { | ||||
| 	exists := make(map[string]bool) | ||||
| 	b.joinChannels(b.ChannelsIn, exists) | ||||
| 	b.joinChannels(b.ChannelsOut, exists) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (b *Bridge) joinChannels(cMap map[string]config.ChannelOptions, exists map[string]bool) error { | ||||
| 	mychannel := "" | ||||
| 	for channel, info := range cMap { | ||||
| 		if !exists[channel] { | ||||
| 			mychannel = channel | ||||
| 			log.Infof("%s: joining %s", b.Account, channel) | ||||
| 			if b.Protocol == "irc" && info.Key != "" { | ||||
| 				log.Debugf("using key %s for channel %s", info.Key, channel) | ||||
| 				mychannel = mychannel + " " + info.Key | ||||
| 			} | ||||
| 			b.JoinChannel(mychannel) | ||||
| 			exists[channel] = true | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @ -10,6 +10,7 @@ import ( | ||||
| 
 | ||||
| const ( | ||||
| 	EVENT_JOIN_LEAVE = "join_leave" | ||||
| 	EVENT_FAILURE    = "failure" | ||||
| ) | ||||
| 
 | ||||
| type Message struct { | ||||
|  | ||||
| @ -80,6 +80,10 @@ func (b *bdiscord) Connect() error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (b *bdiscord) Disconnect() error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (b *bdiscord) JoinChannel(channel string) error { | ||||
| 	idcheck := strings.Split(channel, "ID:") | ||||
| 	if len(idcheck) > 1 { | ||||
|  | ||||
| @ -45,6 +45,11 @@ func (b *Bgitter) Connect() error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (b *Bgitter) Disconnect() error { | ||||
| 	return nil | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| func (b *Bgitter) JoinChannel(channel string) error { | ||||
| 	room := channel | ||||
| 	roomID := b.getRoomID(room) | ||||
|  | ||||
| @ -46,7 +46,6 @@ func New(cfg config.Protocol, account string, c chan config.Message) *Birc { | ||||
| 	if b.Config.MessageQueue == 0 { | ||||
| 		b.Config.MessageQueue = 30 | ||||
| 	} | ||||
| 	b.Local = make(chan config.Message, b.Config.MessageQueue+10) | ||||
| 	return b | ||||
| } | ||||
| 
 | ||||
| @ -61,6 +60,7 @@ func (b *Birc) Command(msg *config.Message) string { | ||||
| } | ||||
| 
 | ||||
| func (b *Birc) Connect() error { | ||||
| 	b.Local = make(chan config.Message, b.Config.MessageQueue+10) | ||||
| 	flog.Infof("Connecting %s", b.Config.Server) | ||||
| 	i := irc.IRC(b.Config.Nick, b.Config.Nick) | ||||
| 	if log.GetLevel() == log.DebugLevel { | ||||
| @ -91,6 +91,12 @@ func (b *Birc) Connect() error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (b *Birc) Disconnect() error { | ||||
| 	b.i.Disconnect() | ||||
| 	close(b.Local) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (b *Birc) JoinChannel(channel string) error { | ||||
| 	b.i.Join(channel) | ||||
| 	return nil | ||||
| @ -170,7 +176,11 @@ func (b *Birc) handleJoinPart(event *irc.Event) { | ||||
| 	flog.Debugf("Sending JOIN_LEAVE event from %s to gateway", b.Account) | ||||
| 	channel := event.Arguments[0] | ||||
| 	if event.Code == "QUIT" { | ||||
| 		channel = "" | ||||
| 		if event.Nick == b.Nick && strings.Contains(event.Raw, "Ping timeout") { | ||||
| 			flog.Infof("%s reconnecting ..", b.Account) | ||||
| 			b.Remote <- config.Message{Username: "system", Text: "reconnect", Channel: channel, Account: b.Account, Event: config.EVENT_FAILURE} | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 	b.Remote <- config.Message{Username: "system", Text: event.Nick + " " + strings.ToLower(event.Code) + "s", Channel: channel, Account: b.Account, Event: config.EVENT_JOIN_LEAVE} | ||||
| 	flog.Debugf("handle %#v", event) | ||||
|  | ||||
| @ -77,6 +77,10 @@ func (b *Bmattermost) Connect() error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (b *Bmattermost) Disconnect() error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (b *Bmattermost) JoinChannel(channel string) error { | ||||
| 	// we can only join channels using the API | ||||
| 	if b.Config.UseAPI { | ||||
|  | ||||
| @ -49,6 +49,11 @@ func (b *Brocketchat) Connect() error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (b *Brocketchat) Disconnect() error { | ||||
| 	return nil | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| func (b *Brocketchat) JoinChannel(channel string) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @ -65,6 +65,11 @@ func (b *Bslack) Connect() error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (b *Bslack) Disconnect() error { | ||||
| 	return nil | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| func (b *Bslack) JoinChannel(channel string) error { | ||||
| 	// we can only join channels using the API | ||||
| 	if b.Config.UseAPI { | ||||
|  | ||||
| @ -51,6 +51,11 @@ func (b *Btelegram) Connect() error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (b *Btelegram) Disconnect() error { | ||||
| 	return nil | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| func (b *Btelegram) JoinChannel(channel string) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @ -1,10 +1,10 @@ | ||||
| package bxmpp | ||||
| 
 | ||||
| import ( | ||||
| 	"crypto/tls" | ||||
| 	"github.com/42wim/matterbridge/bridge/config" | ||||
| 	log "github.com/Sirupsen/logrus" | ||||
| 	"github.com/mattn/go-xmpp" | ||||
| 	"crypto/tls" | ||||
| 
 | ||||
| 	"strings" | ||||
| 	"time" | ||||
| @ -47,6 +47,10 @@ func (b *Bxmpp) Connect() error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (b *Bxmpp) Disconnect() error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (b *Bxmpp) JoinChannel(channel string) error { | ||||
| 	b.xc.JoinMUCNoHistory(channel+"@"+b.Config.Muc, b.Config.Nick) | ||||
| 	return nil | ||||
| @ -63,11 +67,11 @@ func (b *Bxmpp) createXMPP() (*xmpp.Client, error) { | ||||
| 	tc.InsecureSkipVerify = b.Config.SkipTLSVerify | ||||
| 	tc.ServerName = strings.Split(b.Config.Server, ":")[0] | ||||
| 	options := xmpp.Options{ | ||||
| 		Host:     b.Config.Server, | ||||
| 		User:     b.Config.Jid, | ||||
| 		Password: b.Config.Password, | ||||
| 		NoTLS:    true, | ||||
| 		StartTLS: true, | ||||
| 		Host:      b.Config.Server, | ||||
| 		User:      b.Config.Jid, | ||||
| 		Password:  b.Config.Password, | ||||
| 		NoTLS:     true, | ||||
| 		StartTLS:  true, | ||||
| 		TLSConfig: tc, | ||||
| 
 | ||||
| 		//StartTLS:      false, | ||||
|  | ||||
| @ -7,18 +7,19 @@ import ( | ||||
| 	log "github.com/Sirupsen/logrus" | ||||
| 	"reflect" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
| type Gateway struct { | ||||
| 	*config.Config | ||||
| 	MyConfig *config.Gateway | ||||
| 	//Bridges     []*bridge.Bridge | ||||
| 	Bridges        map[string]*bridge.Bridge | ||||
| 	ChannelsOut    map[string][]string | ||||
| 	ChannelsIn     map[string][]string | ||||
| 	ChannelOptions map[string]config.ChannelOptions | ||||
| 	Name           string | ||||
| 	Message        chan config.Message | ||||
| 	MyConfig        *config.Gateway | ||||
| 	Bridges         map[string]*bridge.Bridge | ||||
| 	ChannelsOut     map[string][]string | ||||
| 	ChannelsIn      map[string][]string | ||||
| 	ChannelOptions  map[string]config.ChannelOptions | ||||
| 	Name            string | ||||
| 	Message         chan config.Message | ||||
| 	DestChannelFunc func(msg *config.Message, dest string) []string | ||||
| } | ||||
| 
 | ||||
| func New(cfg *config.Config, gateway *config.Gateway) *Gateway { | ||||
| @ -28,6 +29,7 @@ func New(cfg *config.Config, gateway *config.Gateway) *Gateway { | ||||
| 	gw.MyConfig = gateway | ||||
| 	gw.Message = make(chan config.Message) | ||||
| 	gw.Bridges = make(map[string]*bridge.Bridge) | ||||
| 	gw.DestChannelFunc = gw.getDestChannel | ||||
| 	return gw | ||||
| } | ||||
| 
 | ||||
| @ -39,25 +41,25 @@ func (gw *Gateway) AddBridge(cfg *config.Bridge) error { | ||||
| 	} | ||||
| 	log.Infof("Starting bridge: %s ", cfg.Account) | ||||
| 	br := bridge.New(gw.Config, cfg, gw.Message) | ||||
| 	gw.mapChannelsToBridge(br, gw.ChannelsOut) | ||||
| 	gw.mapChannelsToBridge(br, gw.ChannelsIn) | ||||
| 	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] { | ||||
| 			mychannel := channel | ||||
| 			log.Infof("%s: joining %s", br.Account, channel) | ||||
| 			if br.Protocol == "irc" && gw.ChannelOptions[br.Account+channel].Key != "" { | ||||
| 				log.Debugf("using key %s for channel %s", gw.ChannelOptions[br.Account+channel].Key, channel) | ||||
| 				mychannel = mychannel + " " + gw.ChannelOptions[br.Account+channel].Key | ||||
| 			} | ||||
| 			br.JoinChannel(mychannel) | ||||
| 			exists[br.Account+channel] = true | ||||
| 	br.JoinChannels() | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (gw *Gateway) mapChannelsToBridge(br *bridge.Bridge, cMap map[string][]string) { | ||||
| 	for _, channel := range cMap[br.Account] { | ||||
| 		if _, ok := gw.ChannelOptions[br.Account+channel]; ok { | ||||
| 			br.ChannelsOut[channel] = gw.ChannelOptions[br.Account+channel] | ||||
| 		} else { | ||||
| 			br.ChannelsOut[channel] = config.ChannelOptions{} | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (gw *Gateway) Start() error { | ||||
| @ -76,6 +78,13 @@ func (gw *Gateway) handleReceive() { | ||||
| 	for { | ||||
| 		select { | ||||
| 		case msg := <-gw.Message: | ||||
| 			if msg.Event == config.EVENT_FAILURE { | ||||
| 				for _, br := range gw.Bridges { | ||||
| 					if msg.Account == br.Account { | ||||
| 						go gw.reconnectBridge(br) | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			if !gw.ignoreMessage(&msg) { | ||||
| 				for _, br := range gw.Bridges { | ||||
| 					gw.handleMessage(msg, br) | ||||
| @ -85,6 +94,20 @@ func (gw *Gateway) handleReceive() { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (gw *Gateway) reconnectBridge(br *bridge.Bridge) { | ||||
| 	br.Disconnect() | ||||
| 	time.Sleep(time.Second * 5) | ||||
| RECONNECT: | ||||
| 	log.Infof("Reconnecting %s", br.Account) | ||||
| 	err := br.Connect() | ||||
| 	if err != nil { | ||||
| 		log.Errorf("Reconnection failed: %s. Trying again in 60 seconds", err) | ||||
| 		time.Sleep(time.Second * 60) | ||||
| 		goto RECONNECT | ||||
| 	} | ||||
| 	br.JoinChannels() | ||||
| } | ||||
| 
 | ||||
| func (gw *Gateway) mapChannels() error { | ||||
| 	options := make(map[string]config.ChannelOptions) | ||||
| 	m := make(map[string][]string) | ||||
| @ -129,7 +152,7 @@ func (gw *Gateway) handleMessage(msg config.Message, dest *bridge.Bridge) { | ||||
| 		return | ||||
| 	} | ||||
| 	originchannel := msg.Channel | ||||
| 	channels := gw.getDestChannel(&msg, dest.Account) | ||||
| 	channels := gw.DestChannelFunc(&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.Account == dest.Account && channel == originchannel { | ||||
|  | ||||
| @ -1,105 +1,49 @@ | ||||
| package samechannelgateway | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/42wim/matterbridge/bridge" | ||||
| 	"github.com/42wim/matterbridge/bridge/config" | ||||
| 	log "github.com/Sirupsen/logrus" | ||||
| 	"strings" | ||||
| 	"github.com/42wim/matterbridge/gateway" | ||||
| ) | ||||
| 
 | ||||
| type SameChannelGateway struct { | ||||
| 	*config.Config | ||||
| 	MyConfig    *config.SameChannelGateway | ||||
| 	Bridges     map[string]*bridge.Bridge | ||||
| 	Channels    []string | ||||
| 	ignoreNicks map[string][]string | ||||
| 	Name        string | ||||
| 	MyConfig *config.SameChannelGateway | ||||
| 	Channels []string | ||||
| 	Name     string | ||||
| } | ||||
| 
 | ||||
| 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 | ||||
| 	gw.Channels = gateway.Channels | ||||
| 	for _, account := range gateway.Accounts { | ||||
| 		br := config.Bridge{Account: account} | ||||
| 		log.Infof("Starting bridge: %s", account) | ||||
| 		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.Account, err) | ||||
| 		} | ||||
| 		for _, channel := range gw.Channels { | ||||
| 			log.Infof("%s: joining %s", br.Account, channel) | ||||
| 			br.JoinChannel(channel) | ||||
| func New(cfg *config.Config, gatewayCfg *config.SameChannelGateway) *SameChannelGateway { | ||||
| 	return &SameChannelGateway{ | ||||
| 		MyConfig: gatewayCfg, | ||||
| 		Channels: gatewayCfg.Channels, | ||||
| 		Name:     gatewayCfg.Name, | ||||
| 		Config:   cfg} | ||||
| } | ||||
| 
 | ||||
| func (sgw *SameChannelGateway) Start() error { | ||||
| 	gw := gateway.New(sgw.Config, &config.Gateway{Name: sgw.Name}) | ||||
| 	gw.DestChannelFunc = sgw.getDestChannel | ||||
| 	for _, account := range sgw.MyConfig.Accounts { | ||||
| 		for _, channel := range sgw.Channels { | ||||
| 			br := config.Bridge{Account: account, Channel: channel} | ||||
| 			gw.MyConfig.InOut = append(gw.MyConfig.InOut, br) | ||||
| 		} | ||||
| 	} | ||||
| 	gw.handleReceive(c) | ||||
| 	return nil | ||||
| 	return gw.Start() | ||||
| } | ||||
| 
 | ||||
| func (gw *SameChannelGateway) handleReceive(c chan config.Message) { | ||||
| 	for { | ||||
| 		select { | ||||
| 		case msg := <-c: | ||||
| 			if !gw.ignoreMessage(&msg) { | ||||
| 				for _, br := range gw.Bridges { | ||||
| 					gw.handleMessage(msg, br) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (gw *SameChannelGateway) handleMessage(msg config.Message, dest *bridge.Bridge) { | ||||
| 	// is this a configured channel | ||||
| 	if !gw.validChannel(msg.Channel) { | ||||
| 		return | ||||
| 	} | ||||
| 	// do not send the message to the bridge we come from if also the channel is the same | ||||
| 	if msg.Account == dest.Account { | ||||
| 		return | ||||
| 	} | ||||
| 	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 (gw *SameChannelGateway) ignoreMessage(msg *config.Message) bool { | ||||
| 	for _, entry := range strings.Fields(gw.Bridges[msg.Account].Config.IgnoreNicks) { | ||||
| 		if msg.Username == entry { | ||||
| 			log.Debugf("ignoring %s from %s", msg.Username, msg.Account) | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| func (gw *SameChannelGateway) modifyUsername(msg *config.Message, dest *bridge.Bridge) { | ||||
| 	br := gw.Bridges[msg.Account] | ||||
| 	nick := gw.Config.General.RemoteNickFormat | ||||
| 	if nick == "" { | ||||
| 		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 { | ||||
| 	for _, c := range gw.Channels { | ||||
| func (sgw *SameChannelGateway) validChannel(channel string) bool { | ||||
| 	for _, c := range sgw.Channels { | ||||
| 		if c == channel { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| func (sgw *SameChannelGateway) getDestChannel(msg *config.Message, dest string) []string { | ||||
| 	if sgw.validChannel(msg.Channel) { | ||||
| 		return []string{msg.Channel} | ||||
| 	} | ||||
| 	return []string{} | ||||
| } | ||||
|  | ||||
| @ -36,12 +36,11 @@ func main() { | ||||
| 			continue | ||||
| 		} | ||||
| 		fmt.Printf("starting samechannel gateway %#v\n", gw.Name) | ||||
| 		go func(gw config.SameChannelGateway) { | ||||
| 			err := samechannelgateway.New(cfg, &gw) | ||||
| 			if err != nil { | ||||
| 				log.Fatalf("starting gateway failed %#v", err) | ||||
| 			} | ||||
| 		}(gw) | ||||
| 		g := samechannelgateway.New(cfg, &gw) | ||||
| 		err := g.Start() | ||||
| 		if err != nil { | ||||
| 			log.Fatalf("starting gateway failed %#v", err) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	for _, gw := range cfg.Gateway { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Wim
						Wim