Add initial support for getting ChannelMember info of all bridges.

Adds an EventGetChannelMembers event, which gets send every x time to
all bridges. Bridges should respond on this event with a Message
containing ChannelMembers in the EventGetChannelMembers key in the
Extra field.

handleEventGetChannelMembers will handle this Message and sets the
contained ChannelMembers to the Bridge struct.
This commit is contained in:
Wim
2019-01-06 23:15:37 +01:00
parent bab385c342
commit e28d2f5d89
4 changed files with 83 additions and 21 deletions

View File

@@ -5,6 +5,7 @@ import (
"github.com/42wim/matterbridge/bridge/config" "github.com/42wim/matterbridge/bridge/config"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"sync"
) )
type Bridger interface { type Bridger interface {
@@ -16,14 +17,16 @@ type Bridger interface {
type Bridge struct { type Bridge struct {
Bridger Bridger
Name string Name string
Account string Account string
Protocol string Protocol string
Channels map[string]config.ChannelInfo Channels map[string]config.ChannelInfo
Joined map[string]bool Joined map[string]bool
Log *logrus.Entry ChannelMembers *config.ChannelMembers
Config config.Config Log *logrus.Entry
General *config.Protocol Config config.Config
General *config.Protocol
*sync.RWMutex
} }
type Config struct { type Config struct {
@@ -37,15 +40,17 @@ type Config struct {
type Factory func(*Config) Bridger type Factory func(*Config) Bridger
func New(bridge *config.Bridge) *Bridge { func New(bridge *config.Bridge) *Bridge {
b := new(Bridge) b := &Bridge{
b.Channels = make(map[string]config.ChannelInfo) Channels: make(map[string]config.ChannelInfo),
RWMutex: new(sync.RWMutex),
Joined: make(map[string]bool),
}
accInfo := strings.Split(bridge.Account, ".") accInfo := strings.Split(bridge.Account, ".")
protocol := accInfo[0] protocol := accInfo[0]
name := accInfo[1] name := accInfo[1]
b.Name = name b.Name = name
b.Protocol = protocol b.Protocol = protocol
b.Account = bridge.Account b.Account = bridge.Account
b.Joined = make(map[string]bool)
return b return b
} }
@@ -54,6 +59,13 @@ func (b *Bridge) JoinChannels() error {
return err return err
} }
// SetChannelMembers sets the newMembers to the bridge ChannelMembers
func (b *Bridge) SetChannelMembers(newMembers *config.ChannelMembers) {
b.Lock()
b.ChannelMembers = newMembers
b.Unlock()
}
func (b *Bridge) joinChannels(channels map[string]config.ChannelInfo, exists map[string]bool) error { func (b *Bridge) joinChannels(channels map[string]config.ChannelInfo, exists map[string]bool) error {
for ID, channel := range channels { for ID, channel := range channels {
if !exists[ID] { if !exists[ID] {

View File

@@ -14,16 +14,17 @@ import (
) )
const ( const (
EventJoinLeave = "join_leave" EventJoinLeave = "join_leave"
EventTopicChange = "topic_change" EventTopicChange = "topic_change"
EventFailure = "failure" EventFailure = "failure"
EventFileFailureSize = "file_failure_size" EventFileFailureSize = "file_failure_size"
EventAvatarDownload = "avatar_download" EventAvatarDownload = "avatar_download"
EventRejoinChannels = "rejoin_channels" EventRejoinChannels = "rejoin_channels"
EventUserAction = "user_action" EventUserAction = "user_action"
EventMsgDelete = "msg_delete" EventMsgDelete = "msg_delete"
EventAPIConnected = "api_connected" EventAPIConnected = "api_connected"
EventUserTyping = "user_typing" EventUserTyping = "user_typing"
EventGetChannelMembers = "get_channel_members"
) )
type Message struct { type Message struct {
@@ -61,6 +62,16 @@ type ChannelInfo struct {
Options ChannelOptions Options ChannelOptions
} }
type ChannelMember struct {
Username string
Nick string
UserID string
ChannelID string
ChannelName string
}
type ChannelMembers []ChannelMember
type Protocol struct { type Protocol struct {
AuthCode string // steam AuthCode string // steam
BindAddress string // mattermost, slack // DEPRECATED BindAddress string // mattermost, slack // DEPRECATED

View File

@@ -30,6 +30,23 @@ func (r *Router) handleEventFailure(msg *config.Message) {
} }
} }
// handleEventGetChannelMembers handles channel members
func (r *Router) handleEventGetChannelMembers(msg *config.Message) {
if msg.Event != config.EventGetChannelMembers {
return
}
for _, gw := range r.Gateways {
for _, br := range gw.Bridges {
if msg.Account == br.Account {
cMembers := msg.Extra[config.EventGetChannelMembers][0].(config.ChannelMembers)
flog.Debugf("Syncing channelmembers from %s", msg.Account)
br.SetChannelMembers(&cMembers)
return
}
}
}
}
// handleEventRejoinChannels handles rejoining of channels. // handleEventRejoinChannels handles rejoining of channels.
func (r *Router) handleEventRejoinChannels(msg *config.Message) { func (r *Router) handleEventRejoinChannels(msg *config.Message) {
if msg.Event != config.EventRejoinChannels { if msg.Event != config.EventRejoinChannels {

View File

@@ -2,6 +2,7 @@ package gateway
import ( import (
"fmt" "fmt"
"sync"
"time" "time"
"github.com/42wim/matterbridge/bridge" "github.com/42wim/matterbridge/bridge"
@@ -16,6 +17,7 @@ type Router struct {
Gateways map[string]*Gateway Gateways map[string]*Gateway
Message chan config.Message Message chan config.Message
MattermostPlugin chan config.Message MattermostPlugin chan config.Message
sync.RWMutex
} }
func NewRouter(cfg config.Config, bridgeMap map[string]bridge.Factory) (*Router, error) { func NewRouter(cfg config.Config, bridgeMap map[string]bridge.Factory) (*Router, error) {
@@ -81,6 +83,7 @@ func (r *Router) Start() error {
} }
} }
go r.handleReceive() go r.handleReceive()
go r.updateChannelMembers()
return nil return nil
} }
@@ -108,6 +111,7 @@ func (r *Router) getBridge(account string) *bridge.Bridge {
func (r *Router) handleReceive() { func (r *Router) handleReceive() {
for msg := range r.Message { for msg := range r.Message {
msg := msg // scopelint msg := msg // scopelint
r.handleEventGetChannelMembers(&msg)
r.handleEventFailure(&msg) r.handleEventFailure(&msg)
r.handleEventRejoinChannels(&msg) r.handleEventRejoinChannels(&msg)
for _, gw := range r.Gateways { for _, gw := range r.Gateways {
@@ -129,3 +133,21 @@ func (r *Router) handleReceive() {
} }
} }
} }
// updateChannelMembers sends every minute an GetChannelMembers event to all bridges.
func (r *Router) updateChannelMembers() {
// TODO sleep a minute because slack can take a while
// fix this by having actually connectionDone events send to the router
time.Sleep(time.Minute)
for {
for _, gw := range r.Gateways {
for _, br := range gw.Bridges {
flog.Debugf("sending %s to %s", config.EventGetChannelMembers, br.Account)
if _, err := br.Send(config.Message{Event: config.EventGetChannelMembers}); err != nil {
flog.Errorf("updateChannelMembers: %s", err)
}
}
}
time.Sleep(time.Minute)
}
}