Allow a webhookurl per channel (discord). #239

This commit is contained in:
Wim 2017-08-12 14:51:41 +02:00
parent ad4d461606
commit 28710d0bc7
14 changed files with 100 additions and 49 deletions

View File

@ -61,7 +61,7 @@ func (b *Api) Disconnect() error {
return nil return nil
} }
func (b *Api) JoinChannel(channel string) error { func (b *Api) JoinChannel(channel config.ChannelInfo) error {
return nil return nil
} }

View File

@ -21,7 +21,7 @@ import (
type Bridger interface { type Bridger interface {
Send(msg config.Message) error Send(msg config.Message) error
Connect() error Connect() error
JoinChannel(channel string) error JoinChannel(channel config.ChannelInfo) error
Disconnect() 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 { func (b *Bridge) joinChannels(channels map[string]config.ChannelInfo, exists map[string]bool) error {
mychannel := ""
for ID, channel := range channels { for ID, channel := range channels {
if !exists[ID] { if !exists[ID] {
mychannel = channel.Name
log.Infof("%s: joining %s (%s)", b.Account, channel.Name, ID) log.Infof("%s: joining %s (%s)", b.Account, channel.Name, ID)
if b.Protocol == "irc" && channel.Options.Key != "" { err := b.JoinChannel(channel)
log.Debugf("using key %s for channel %s", channel.Options.Key, channel.Name)
mychannel = mychannel + " " + channel.Options.Key
}
err := b.JoinChannel(mychannel)
if err != nil { if err != nil {
return err return err
} }

View File

@ -85,7 +85,8 @@ type Protocol struct {
} }
type ChannelOptions struct { type ChannelOptions struct {
Key string // irc Key string // irc
WebhookURL string // discord
} }
type Bridge struct { type Bridge struct {

View File

@ -10,17 +10,18 @@ import (
) )
type bdiscord struct { type bdiscord struct {
c *discordgo.Session c *discordgo.Session
Config *config.Protocol Config *config.Protocol
Remote chan config.Message Remote chan config.Message
Account string Account string
Channels []*discordgo.Channel Channels []*discordgo.Channel
Nick string Nick string
UseChannelID bool UseChannelID bool
userMemberMap map[string]*discordgo.Member userMemberMap map[string]*discordgo.Member
guildID string guildID string
webhookID string webhookID string
webhookToken string webhookToken string
channelInfoMap map[string]*config.ChannelInfo
sync.RWMutex sync.RWMutex
} }
@ -37,11 +38,10 @@ func New(cfg config.Protocol, account string, c chan config.Message) *bdiscord {
b.Remote = c b.Remote = c
b.Account = account b.Account = account
b.userMemberMap = make(map[string]*discordgo.Member) b.userMemberMap = make(map[string]*discordgo.Member)
b.channelInfoMap = make(map[string]*config.ChannelInfo)
if b.Config.WebhookURL != "" { if b.Config.WebhookURL != "" {
flog.Debug("Configuring Discord Incoming Webhook") flog.Debug("Configuring Discord Incoming Webhook")
webhookURLSplit := strings.Split(b.Config.WebhookURL, "/") b.webhookToken, b.webhookID = b.splitURL(b.Config.WebhookURL)
b.webhookToken = webhookURLSplit[len(webhookURLSplit)-1]
b.webhookID = webhookURLSplit[len(webhookURLSplit)-2]
} }
return b return b
} }
@ -99,8 +99,9 @@ func (b *bdiscord) Disconnect() error {
return nil return nil
} }
func (b *bdiscord) JoinChannel(channel string) error { func (b *bdiscord) JoinChannel(channel config.ChannelInfo) error {
idcheck := strings.Split(channel, "ID:") b.channelInfoMap[channel.ID] = &channel
idcheck := strings.Split(channel.Name, "ID:")
if len(idcheck) > 1 { if len(idcheck) > 1 {
b.UseChannelID = true b.UseChannelID = true
} }
@ -117,14 +118,23 @@ func (b *bdiscord) Send(msg config.Message) error {
if msg.Event == config.EVENT_USER_ACTION { if msg.Event == config.EVENT_USER_ACTION {
msg.Text = "_" + msg.Text + "_" msg.Text = "_" + msg.Text + "_"
} }
if b.Config.WebhookURL == "" {
wID := b.webhookID
wToken := b.webhookToken
if ci, ok := b.channelInfoMap[msg.Channel+msg.Account]; ok {
if ci.Options.WebhookURL != "" {
wID, wToken = b.splitURL(ci.Options.WebhookURL)
}
}
if wID == "" {
flog.Debugf("Broadcasting using token (API)") flog.Debugf("Broadcasting using token (API)")
b.c.ChannelMessageSend(channelID, msg.Username+msg.Text) b.c.ChannelMessageSend(channelID, msg.Username+msg.Text)
} else { } else {
flog.Debugf("Broadcasting using Webhook") flog.Debugf("Broadcasting using Webhook %#v %#v", wID, wToken)
b.c.WebhookExecute( b.c.WebhookExecute(
b.webhookID, wID,
b.webhookToken, wToken,
true, true,
&discordgo.WebhookParams{ &discordgo.WebhookParams{
Content: msg.Text, Content: msg.Text,
@ -153,7 +163,7 @@ func (b *bdiscord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreat
return return
} }
// if using webhooks, do not relay if it's ours // 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 return
} }
@ -310,3 +320,35 @@ func (b *bdiscord) stripCustomoji(text string) string {
re := regexp.MustCompile("<(:.*?:)[0-9]+>") re := regexp.MustCompile("<(:.*?:)[0-9]+>")
return re.ReplaceAllString(text, `$1`) 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 {
for _, channel := range b.channelInfoMap {
if channel.Options.WebhookURL != "" {
wID, _ := b.splitURL(channel.Options.WebhookURL)
if wID == id {
return true
}
}
}
return false
}

View File

@ -51,10 +51,10 @@ func (b *Bgitter) Disconnect() error {
} }
func (b *Bgitter) JoinChannel(channel string) error { func (b *Bgitter) JoinChannel(channel config.ChannelInfo) error {
roomID, err := b.c.GetRoomId(channel) roomID, err := b.c.GetRoomId(channel.Name)
if err != nil { 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) room, err := b.c.GetRoom(roomID)
if err != nil { if err != nil {

View File

@ -117,8 +117,13 @@ func (b *Birc) Disconnect() error {
return nil return nil
} }
func (b *Birc) JoinChannel(channel string) error { func (b *Birc) JoinChannel(channel config.ChannelInfo) error {
b.i.Join(channel) 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 return nil
} }

View File

@ -63,13 +63,13 @@ func (b *Bmatrix) Disconnect() error {
return nil return nil
} }
func (b *Bmatrix) JoinChannel(channel string) error { func (b *Bmatrix) JoinChannel(channel config.ChannelInfo) error {
resp, err := b.mc.JoinRoom(channel, "", nil) resp, err := b.mc.JoinRoom(channel.Name, "", nil)
if err != nil { if err != nil {
return err return err
} }
b.Lock() b.Lock()
b.RoomMap[resp.RoomID] = channel b.RoomMap[resp.RoomID] = channel.Name
b.Unlock() b.Unlock()
return err return err
} }

View File

@ -108,10 +108,10 @@ func (b *Bmattermost) Disconnect() error {
return nil 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 // we can only join channels using the API
if b.Config.WebhookURL == "" && b.Config.WebhookBindAddress == "" { 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 return nil
} }

View File

@ -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 return nil
} }

View File

@ -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 // we can only join channels using the API
if b.Config.WebhookURL == "" && b.Config.WebhookBindAddress == "" { if b.Config.WebhookURL == "" && b.Config.WebhookBindAddress == "" {
if strings.HasPrefix(b.Config.Token, "xoxb") { if strings.HasPrefix(b.Config.Token, "xoxb") {
// TODO check if bot has already joined channel // TODO check if bot has already joined channel
return nil return nil
} }
_, err := b.sc.JoinChannel(channel) _, err := b.sc.JoinChannel(channel.Name)
if err != nil { if err != nil {
if err.Error() != "name_taken" { if err.Error() != "name_taken" {
return err return err

View File

@ -60,8 +60,8 @@ func (b *Bsteam) Disconnect() error {
} }
func (b *Bsteam) JoinChannel(channel string) error { func (b *Bsteam) JoinChannel(channel config.ChannelInfo) error {
id, err := steamid.NewId(channel) id, err := steamid.NewId(channel.Name)
if err != nil { if err != nil {
return err return err
} }

View File

@ -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 return nil
} }

View File

@ -74,8 +74,8 @@ func (b *Bxmpp) Disconnect() error {
return nil return nil
} }
func (b *Bxmpp) JoinChannel(channel string) error { func (b *Bxmpp) JoinChannel(channel config.ChannelInfo) error {
b.xc.JoinMUCNoHistory(channel+"@"+b.Config.Muc, b.Config.Nick) b.xc.JoinMUCNoHistory(channel.Name+"@"+b.Config.Muc, b.Config.Nick)
return nil return nil
} }

View File

@ -448,6 +448,7 @@ ShowEmbeds=false
UseUserName=false UseUserName=false
#Specify WebhookURL. If given, will relay messages using the Webhook, which gives a better look to messages. #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) #OPTIONAL (default empty)
WebhookURL="Yourwebhooktokenhere" WebhookURL="Yourwebhooktokenhere"
@ -833,6 +834,14 @@ enable=true
#OPTIONAL - your irc channel key #OPTIONAL - your irc channel key
key="yourkey" 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 #API example
#[[gateway.inout]] #[[gateway.inout]]
#account="api.local" #account="api.local"