Compare commits
	
		
			9 Commits
		
	
	
		
			v1.0.0-rc1
			...
			v1.0.1
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | a5259f56c5 | ||
|   | 3f75ed9c18 | ||
|   | 49ece51167 | ||
|   | e77c3eb20a | ||
|   | 59b2a5f8d0 | ||
|   | 28710d0bc7 | ||
|   | ad4d461606 | ||
|   | 67905089ba | ||
|   | f2483af561 | 
| @@ -53,7 +53,7 @@ See https://github.com/42wim/matterbridge/wiki | ||||
|  | ||||
| # Installing | ||||
| ## Binaries | ||||
| * Latest stable release [v1.0.0-rc1](https://github.com/42wim/matterbridge/releases/latest) | ||||
| * Latest stable release [v1.0.1](https://github.com/42wim/matterbridge/releases/latest) | ||||
| * Development releases (follows master) can be downloaded [here](https://dl.bintray.com/42wim/nightly/)   | ||||
|  | ||||
| ## Building | ||||
|   | ||||
| @@ -61,7 +61,7 @@ func (b *Api) Disconnect() error { | ||||
| 	return nil | ||||
|  | ||||
| } | ||||
| func (b *Api) JoinChannel(channel string) error { | ||||
| func (b *Api) JoinChannel(channel config.ChannelInfo) error { | ||||
| 	return nil | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -21,7 +21,7 @@ import ( | ||||
| type Bridger interface { | ||||
| 	Send(msg config.Message) error | ||||
| 	Connect() error | ||||
| 	JoinChannel(channel string) error | ||||
| 	JoinChannel(channel config.ChannelInfo) error | ||||
| 	Disconnect() error | ||||
| } | ||||
|  | ||||
| @@ -92,16 +92,10 @@ func (b *Bridge) JoinChannels() error { | ||||
| } | ||||
|  | ||||
| func (b *Bridge) joinChannels(channels map[string]config.ChannelInfo, exists map[string]bool) error { | ||||
| 	mychannel := "" | ||||
| 	for ID, channel := range channels { | ||||
| 		if !exists[ID] { | ||||
| 			mychannel = channel.Name | ||||
| 			log.Infof("%s: joining %s (%s)", b.Account, channel.Name, ID) | ||||
| 			if b.Protocol == "irc" && channel.Options.Key != "" { | ||||
| 				log.Debugf("using key %s for channel %s", channel.Options.Key, channel.Name) | ||||
| 				mychannel = mychannel + " " + channel.Options.Key | ||||
| 			} | ||||
| 			err := b.JoinChannel(mychannel) | ||||
| 			err := b.JoinChannel(channel) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
|   | ||||
| @@ -77,6 +77,7 @@ type Protocol struct { | ||||
| 	UseSASL                bool   // IRC | ||||
| 	UseTLS                 bool   // IRC | ||||
| 	UseFirstName           bool   // telegram | ||||
| 	UseUserName            bool   // discord | ||||
| 	UseInsecureURL         bool   // telegram | ||||
| 	WebhookBindAddress     string // mattermost, slack | ||||
| 	WebhookURL             string // mattermost, slack | ||||
| @@ -84,7 +85,8 @@ type Protocol struct { | ||||
| } | ||||
|  | ||||
| type ChannelOptions struct { | ||||
| 	Key string // irc | ||||
| 	Key        string // irc | ||||
| 	WebhookURL string // discord | ||||
| } | ||||
|  | ||||
| type Bridge struct { | ||||
|   | ||||
| @@ -10,17 +10,18 @@ import ( | ||||
| ) | ||||
|  | ||||
| type bdiscord struct { | ||||
| 	c             *discordgo.Session | ||||
| 	Config        *config.Protocol | ||||
| 	Remote        chan config.Message | ||||
| 	Account       string | ||||
| 	Channels      []*discordgo.Channel | ||||
| 	Nick          string | ||||
| 	UseChannelID  bool | ||||
| 	userMemberMap map[string]*discordgo.Member | ||||
| 	guildID       string | ||||
| 	webhookID     string | ||||
| 	webhookToken  string | ||||
| 	c              *discordgo.Session | ||||
| 	Config         *config.Protocol | ||||
| 	Remote         chan config.Message | ||||
| 	Account        string | ||||
| 	Channels       []*discordgo.Channel | ||||
| 	Nick           string | ||||
| 	UseChannelID   bool | ||||
| 	userMemberMap  map[string]*discordgo.Member | ||||
| 	guildID        string | ||||
| 	webhookID      string | ||||
| 	webhookToken   string | ||||
| 	channelInfoMap map[string]*config.ChannelInfo | ||||
| 	sync.RWMutex | ||||
| } | ||||
|  | ||||
| @@ -37,11 +38,10 @@ func New(cfg config.Protocol, account string, c chan config.Message) *bdiscord { | ||||
| 	b.Remote = c | ||||
| 	b.Account = account | ||||
| 	b.userMemberMap = make(map[string]*discordgo.Member) | ||||
| 	b.channelInfoMap = make(map[string]*config.ChannelInfo) | ||||
| 	if b.Config.WebhookURL != "" { | ||||
| 		flog.Debug("Configuring Discord Incoming Webhook") | ||||
| 		webhookURLSplit := strings.Split(b.Config.WebhookURL, "/") | ||||
| 		b.webhookToken = webhookURLSplit[len(webhookURLSplit)-1] | ||||
| 		b.webhookID = webhookURLSplit[len(webhookURLSplit)-2] | ||||
| 		b.webhookID, b.webhookToken = b.splitURL(b.Config.WebhookURL) | ||||
| 	} | ||||
| 	return b | ||||
| } | ||||
| @@ -99,8 +99,9 @@ func (b *bdiscord) Disconnect() error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (b *bdiscord) JoinChannel(channel string) error { | ||||
| 	idcheck := strings.Split(channel, "ID:") | ||||
| func (b *bdiscord) JoinChannel(channel config.ChannelInfo) error { | ||||
| 	b.channelInfoMap[channel.ID] = &channel | ||||
| 	idcheck := strings.Split(channel.Name, "ID:") | ||||
| 	if len(idcheck) > 1 { | ||||
| 		b.UseChannelID = true | ||||
| 	} | ||||
| @@ -114,21 +115,26 @@ func (b *bdiscord) Send(msg config.Message) error { | ||||
| 		flog.Errorf("Could not find channelID for %v", msg.Channel) | ||||
| 		return nil | ||||
| 	} | ||||
| 	if b.Config.WebhookURL == "" { | ||||
| 		flog.Debugf("Broadcasting using token (API)") | ||||
| 		if msg.Event == config.EVENT_USER_ACTION { | ||||
| 			msg.Username = "_" + msg.Username | ||||
| 			msg.Text = msg.Text + "_" | ||||
| 	if msg.Event == config.EVENT_USER_ACTION { | ||||
| 		msg.Text = "_" + msg.Text + "_" | ||||
| 	} | ||||
|  | ||||
| 	wID := b.webhookID | ||||
| 	wToken := b.webhookToken | ||||
| 	if ci, ok := b.channelInfoMap[msg.Channel+b.Account]; ok { | ||||
| 		if ci.Options.WebhookURL != "" { | ||||
| 			wID, wToken = b.splitURL(ci.Options.WebhookURL) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if wID == "" { | ||||
| 		flog.Debugf("Broadcasting using token (API)") | ||||
| 		b.c.ChannelMessageSend(channelID, msg.Username+msg.Text) | ||||
| 	} else { | ||||
| 		flog.Debugf("Broadcasting using Webhook") | ||||
| 		if msg.Event == config.EVENT_USER_ACTION { | ||||
| 			msg.Text = "_" + msg.Text + "_" | ||||
| 		} | ||||
| 		b.c.WebhookExecute( | ||||
| 			b.webhookID, | ||||
| 			b.webhookToken, | ||||
| 			wID, | ||||
| 			wToken, | ||||
| 			true, | ||||
| 			&discordgo.WebhookParams{ | ||||
| 				Content:   msg.Text, | ||||
| @@ -157,7 +163,7 @@ func (b *bdiscord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreat | ||||
| 		return | ||||
| 	} | ||||
| 	// if using webhooks, do not relay if it's ours | ||||
| 	if b.Config.WebhookURL != "" && m.Author.Bot && m.Author.ID == b.webhookID { | ||||
| 	if b.useWebhook() && m.Author.Bot && b.isWebhookID(m.Author.ID) { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| @@ -185,7 +191,12 @@ func (b *bdiscord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreat | ||||
| 	if b.UseChannelID { | ||||
| 		rmsg.Channel = "ID:" + m.ChannelID | ||||
| 	} | ||||
| 	rmsg.Username = b.getNick(m.Author) | ||||
|  | ||||
| 	if !b.Config.UseUserName { | ||||
| 		rmsg.Username = b.getNick(m.Author) | ||||
| 	} else { | ||||
| 		rmsg.Username = m.Author.Username | ||||
| 	} | ||||
|  | ||||
| 	if b.Config.ShowEmbeds && m.Message.Embeds != nil { | ||||
| 		for _, embed := range m.Message.Embeds { | ||||
| @@ -309,3 +320,41 @@ func (b *bdiscord) stripCustomoji(text string) string { | ||||
| 	re := regexp.MustCompile("<(:.*?:)[0-9]+>") | ||||
| 	return re.ReplaceAllString(text, `$1`) | ||||
| } | ||||
|  | ||||
| // splitURL splits a webhookURL and returns the id and token | ||||
| func (b *bdiscord) splitURL(url string) (string, string) { | ||||
| 	webhookURLSplit := strings.Split(url, "/") | ||||
| 	return webhookURLSplit[len(webhookURLSplit)-2], webhookURLSplit[len(webhookURLSplit)-1] | ||||
| } | ||||
|  | ||||
| // useWebhook returns true if we have a webhook defined somewhere | ||||
| func (b *bdiscord) useWebhook() bool { | ||||
| 	if b.Config.WebhookURL != "" { | ||||
| 		return true | ||||
| 	} | ||||
| 	for _, channel := range b.channelInfoMap { | ||||
| 		if channel.Options.WebhookURL != "" { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // isWebhookID returns true if the specified id is used in a defined webhook | ||||
| func (b *bdiscord) isWebhookID(id string) bool { | ||||
| 	if b.Config.WebhookURL != "" { | ||||
| 		wID, _ := b.splitURL(b.Config.WebhookURL) | ||||
| 		if wID == id { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	for _, channel := range b.channelInfoMap { | ||||
| 		if channel.Options.WebhookURL != "" { | ||||
| 			wID, _ := b.splitURL(channel.Options.WebhookURL) | ||||
| 			if wID == id { | ||||
| 				return true | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|   | ||||
| @@ -51,10 +51,10 @@ func (b *Bgitter) Disconnect() error { | ||||
|  | ||||
| } | ||||
|  | ||||
| func (b *Bgitter) JoinChannel(channel string) error { | ||||
| 	roomID, err := b.c.GetRoomId(channel) | ||||
| func (b *Bgitter) JoinChannel(channel config.ChannelInfo) error { | ||||
| 	roomID, err := b.c.GetRoomId(channel.Name) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("Could not find roomID for %v. Please create the room on gitter.im", channel) | ||||
| 		return fmt.Errorf("Could not find roomID for %v. Please create the room on gitter.im", channel.Name) | ||||
| 	} | ||||
| 	room, err := b.c.GetRoom(roomID) | ||||
| 	if err != nil { | ||||
|   | ||||
| @@ -117,8 +117,13 @@ func (b *Birc) Disconnect() error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (b *Birc) JoinChannel(channel string) error { | ||||
| 	b.i.Join(channel) | ||||
| func (b *Birc) JoinChannel(channel config.ChannelInfo) error { | ||||
| 	if channel.Options.Key != "" { | ||||
| 		flog.Debugf("using key %s for channel %s", channel.Options.Key, channel.Name) | ||||
| 		b.i.Join(channel.Name + " " + channel.Options.Key) | ||||
| 	} else { | ||||
| 		b.i.Join(channel.Name) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -63,13 +63,13 @@ func (b *Bmatrix) Disconnect() error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (b *Bmatrix) JoinChannel(channel string) error { | ||||
| 	resp, err := b.mc.JoinRoom(channel, "", nil) | ||||
| func (b *Bmatrix) JoinChannel(channel config.ChannelInfo) error { | ||||
| 	resp, err := b.mc.JoinRoom(channel.Name, "", nil) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	b.Lock() | ||||
| 	b.RoomMap[resp.RoomID] = channel | ||||
| 	b.RoomMap[resp.RoomID] = channel.Name | ||||
| 	b.Unlock() | ||||
| 	return err | ||||
| } | ||||
|   | ||||
| @@ -108,10 +108,10 @@ func (b *Bmattermost) Disconnect() error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (b *Bmattermost) JoinChannel(channel string) error { | ||||
| func (b *Bmattermost) JoinChannel(channel config.ChannelInfo) error { | ||||
| 	// we can only join channels using the API | ||||
| 	if b.Config.WebhookURL == "" && b.Config.WebhookBindAddress == "" { | ||||
| 		return b.mc.JoinChannel(b.mc.GetChannelId(channel, "")) | ||||
| 		return b.mc.JoinChannel(b.mc.GetChannelId(channel.Name, "")) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|   | ||||
| @@ -53,7 +53,7 @@ func (b *Brocketchat) Disconnect() error { | ||||
|  | ||||
| } | ||||
|  | ||||
| func (b *Brocketchat) JoinChannel(channel string) error { | ||||
| func (b *Brocketchat) JoinChannel(channel config.ChannelInfo) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -108,14 +108,14 @@ func (b *Bslack) Disconnect() error { | ||||
|  | ||||
| } | ||||
|  | ||||
| func (b *Bslack) JoinChannel(channel string) error { | ||||
| func (b *Bslack) JoinChannel(channel config.ChannelInfo) error { | ||||
| 	// we can only join channels using the API | ||||
| 	if b.Config.WebhookURL == "" && b.Config.WebhookBindAddress == "" { | ||||
| 		if strings.HasPrefix(b.Config.Token, "xoxb") { | ||||
| 			// TODO check if bot has already joined channel | ||||
| 			return nil | ||||
| 		} | ||||
| 		_, err := b.sc.JoinChannel(channel) | ||||
| 		_, err := b.sc.JoinChannel(channel.Name) | ||||
| 		if err != nil { | ||||
| 			if err.Error() != "name_taken" { | ||||
| 				return err | ||||
|   | ||||
| @@ -60,8 +60,8 @@ func (b *Bsteam) Disconnect() error { | ||||
|  | ||||
| } | ||||
|  | ||||
| func (b *Bsteam) JoinChannel(channel string) error { | ||||
| 	id, err := steamid.NewId(channel) | ||||
| func (b *Bsteam) JoinChannel(channel config.ChannelInfo) error { | ||||
| 	id, err := steamid.NewId(channel.Name) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|   | ||||
| @@ -53,7 +53,7 @@ func (b *Btelegram) Disconnect() error { | ||||
|  | ||||
| } | ||||
|  | ||||
| func (b *Btelegram) JoinChannel(channel string) error { | ||||
| func (b *Btelegram) JoinChannel(channel config.ChannelInfo) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -74,8 +74,8 @@ func (b *Bxmpp) Disconnect() error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (b *Bxmpp) JoinChannel(channel string) error { | ||||
| 	b.xc.JoinMUCNoHistory(channel+"@"+b.Config.Muc, b.Config.Nick) | ||||
| func (b *Bxmpp) JoinChannel(channel config.ChannelInfo) error { | ||||
| 	b.xc.JoinMUCNoHistory(channel.Name+"@"+b.Config.Muc, b.Config.Nick) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										12
									
								
								changelog.md
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								changelog.md
									
									
									
									
									
								
							| @@ -1,3 +1,15 @@ | ||||
| # v1.0.1 | ||||
| ## New features | ||||
| * mattermost: add support for mattermost 4.1.x | ||||
| * discord: allow a webhookURL per channel #239 | ||||
|  | ||||
| ## Bugfix | ||||
|  | ||||
| # v1.0.0 | ||||
| ## New features | ||||
| * general: Add action support for slack,mattermost,irc,gitter,matrix,xmpp,discord. #199 | ||||
| * discord: Shows the username instead of the server nickname #234 | ||||
|  | ||||
| # v1.0.0-rc1 | ||||
| ## New features | ||||
| * general: Add action support for slack,mattermost,irc,gitter,matrix,xmpp,discord. #199 | ||||
|   | ||||
| @@ -5,14 +5,13 @@ import ( | ||||
| 	"fmt" | ||||
| 	"github.com/42wim/matterbridge/bridge/config" | ||||
| 	"github.com/42wim/matterbridge/gateway" | ||||
| 	//"github.com/42wim/matterbridge/gateway/samechannel" | ||||
| 	log "github.com/Sirupsen/logrus" | ||||
| 	"github.com/google/gops/agent" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	version = "1.0.0-rc1" | ||||
| 	version = "1.0.1" | ||||
| 	githash string | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -443,7 +443,12 @@ Server="yourservername" | ||||
| #OPTIONAL (default false) | ||||
| ShowEmbeds=false | ||||
|  | ||||
| #Shows the username (minus the discriminator) instead of the server nickname | ||||
| #OPTIONAL (default false) | ||||
| UseUserName=false | ||||
|  | ||||
| #Specify WebhookURL. If given, will relay messages using the Webhook, which gives a better look to messages. | ||||
| #This only works if you have one discord channel, if you have multiple discord channels you'll have to specify it in the gateway config | ||||
| #OPTIONAL (default empty) | ||||
| WebhookURL="Yourwebhooktokenhere" | ||||
|  | ||||
| @@ -829,6 +834,14 @@ enable=true | ||||
|         #OPTIONAL - your irc channel key | ||||
|         key="yourkey" | ||||
|  | ||||
|     [[gateway.inout]] | ||||
|     account="discord.game" | ||||
|     channel="mygreatgame" | ||||
|  | ||||
|         #OPTIONAL - webhookurl only works for discord (it needs a different URL for each cahnnel) | ||||
|         [gateway.inout.options] | ||||
|         webhookurl=""https://discordapp.com/api/webhooks/123456789123456789/C9WPqExYWONPDZabcdef-def1434FGFjstasJX9pYht73y" | ||||
|  | ||||
|     #API example | ||||
|     #[[gateway.inout]] | ||||
|     #account="api.local" | ||||
|   | ||||
| @@ -869,7 +869,8 @@ func supportedVersion(version string) bool { | ||||
| 		strings.HasPrefix(version, "3.8.0") || | ||||
| 		strings.HasPrefix(version, "3.9.0") || | ||||
| 		strings.HasPrefix(version, "3.10.0") || | ||||
| 		strings.HasPrefix(version, "4.0") { | ||||
| 		strings.HasPrefix(version, "4.0") || | ||||
| 		strings.HasPrefix(version, "4.1") { | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
|   | ||||
| @@ -43,6 +43,7 @@ type IMessage struct { | ||||
| 	ServiceId   string `schema:"service_id"` | ||||
| 	Text        string `schema:"text"` | ||||
| 	TriggerWord string `schema:"trigger_word"` | ||||
| 	FileIDs     string `schema:"file_ids"` | ||||
| } | ||||
|  | ||||
| // Client for Mattermost. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user