Add support for discord category channels (discord) (#863)

This adds support for the discord category option that can be used
to group channels in. This means we can have multiple channels with
the same name.

We add the option to specify a category in the channel option of a
discord account under [[gateway]]

Besides channel="channel" or channel="ID:channelID", now also
channel="category/channel" can be specified.

This change remains backwards compatible with people that haven't
specified the category and incorporates the fix in #861
This commit is contained in:
Wim 2019-07-15 21:56:35 +02:00 committed by GitHub
parent 5551f9d56f
commit 7d2e440c83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 23 deletions

View File

@ -95,12 +95,10 @@ func (b *Bdiscord) Connect() error {
b.channelsMutex.Lock() b.channelsMutex.Lock()
for _, guild := range guilds { for _, guild := range guilds {
if guild.Name == serverName || guild.ID == serverName { if guild.Name == serverName || guild.ID == serverName {
var chans []*discordgo.Channel b.channels, err = b.c.GuildChannels(guild.ID)
chans, err = b.c.GuildChannels(guild.ID)
if err != nil { if err != nil {
break break
} }
b.channels = filterChannelsByType(chans, discordgo.ChannelTypeGuildText, false)
b.guildID = guild.ID b.guildID = guild.ID
guildFound = true guildFound = true
} }

View File

@ -52,6 +52,9 @@ func (b *Bdiscord) getGuildMemberByNick(nick string) (*discordgo.Member, error)
} }
func (b *Bdiscord) getChannelID(name string) string { func (b *Bdiscord) getChannelID(name string) string {
if strings.Contains(name, "/") {
return b.getCategoryChannelID(name)
}
b.channelsMutex.RLock() b.channelsMutex.RLock()
defer b.channelsMutex.RUnlock() defer b.channelsMutex.RUnlock()
@ -60,25 +63,70 @@ func (b *Bdiscord) getChannelID(name string) string {
return idcheck[1] return idcheck[1]
} }
for _, channel := range b.channels { for _, channel := range b.channels {
if channel.Name == name { if channel.Name == name && channel.Type == discordgo.ChannelTypeGuildText {
return channel.ID return channel.ID
} }
} }
return "" return ""
} }
func (b *Bdiscord) getCategoryChannelID(name string) string {
b.channelsMutex.RLock()
defer b.channelsMutex.RUnlock()
res := strings.Split(name, "/")
// shouldn't happen because function should be only called from getChannelID
if len(res) != 2 {
return ""
}
catName, chanName := res[0], res[1]
for _, channel := range b.channels {
// if we have a parentID, lookup the name of that parent (category)
// and if it matches return it
if channel.Name == chanName && channel.ParentID != "" {
for _, cat := range b.channels {
if cat.ID == channel.ParentID && cat.Name == catName {
return channel.ID
}
}
}
}
return ""
}
func (b *Bdiscord) getChannelName(id string) string { func (b *Bdiscord) getChannelName(id string) string {
b.channelsMutex.RLock() b.channelsMutex.RLock()
defer b.channelsMutex.RUnlock() defer b.channelsMutex.RUnlock()
for _, channel := range b.channels { for _, channel := range b.channels {
if channel.ID == id { if channel.ID == id {
return channel.Name return b.getCategoryChannelName(channel.Name, channel.ParentID)
} }
} }
return "" return ""
} }
func (b *Bdiscord) getCategoryChannelName(name, parentID string) string {
var usesCat bool
// do we have a category configuration in the channel config
for _, c := range b.channelInfoMap {
if strings.Contains(c.Name, "/") {
usesCat = true
break
}
}
// configuration without category, return the normal channel name
if !usesCat {
return name
}
// create a category/channel response
for _, c := range b.channels {
if c.ID == parentID {
name = c.Name + "/" + name
}
}
return name
}
var ( var (
// See https://discordapp.com/developers/docs/reference#message-formatting. // See https://discordapp.com/developers/docs/reference#message-formatting.
channelMentionRE = regexp.MustCompile("<#[0-9]+>") channelMentionRE = regexp.MustCompile("<#[0-9]+>")
@ -93,8 +141,8 @@ func (b *Bdiscord) replaceChannelMentions(text string) string {
// If we don't have the channel refresh our list. // If we don't have the channel refresh our list.
if channelName == "" { if channelName == "" {
chans, err := b.c.GuildChannels(b.guildID) var err error
b.channels = filterChannelsByType(chans, discordgo.ChannelTypeGuildCategory, true) b.channels, err = b.c.GuildChannels(b.guildID)
if err != nil { if err != nil {
return "#unknownchannel" return "#unknownchannel"
} }
@ -211,19 +259,3 @@ func (b *Bdiscord) webhookExecute(webhookID, token string, wait bool, data *disc
return st, nil return st, nil
} }
func filterChannelsByType(chans []*discordgo.Channel, t discordgo.ChannelType, filterOut bool) []*discordgo.Channel {
cs := []*discordgo.Channel{}
for _, c := range chans {
keep := c.Type == t
if filterOut {
keep = c.Type != t
}
if keep {
cs = append(cs, c)
}
}
return cs
}

View File

@ -1553,6 +1553,7 @@ enable=true
# discord - channel (without the #) # discord - channel (without the #)
# - ID:123456789 (where 123456789 is the channel ID) # - ID:123456789 (where 123456789 is the channel ID)
# (https://github.com/42wim/matterbridge/issues/57) # (https://github.com/42wim/matterbridge/issues/57)
# - category/channel (without the #) if you're using discord categories to group your channels
# telegram - chatid (a large negative number, eg -123456789) # telegram - chatid (a large negative number, eg -123456789)
# see (https://www.linkedin.com/pulse/telegram-bots-beginners-marco-frau) # see (https://www.linkedin.com/pulse/telegram-bots-beginners-marco-frau)
# hipchat - id_channel (see https://www.hipchat.com/account/xmpp for the correct channel) # hipchat - id_channel (see https://www.hipchat.com/account/xmpp for the correct channel)