diff --git a/.gitignore b/.gitignore index 66fd13c..5e22399 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,5 @@ # Dependency directories (remove the comment below to include it) # vendor/ + +InnkeeperBot \ No newline at end of file diff --git a/add.go b/add.go new file mode 100644 index 0000000..8954b71 --- /dev/null +++ b/add.go @@ -0,0 +1,55 @@ +package main + +import ( + "strings" + + "github.com/bwmarrin/discordgo" +) + +func commandAdd(s *discordgo.Session, m *discordgo.MessageCreate) { + // Parameters should contains the channel name and the username + parameters := strings.Fields(m.Content) + if len(parameters) < 2 { + s.ChannelMessageSend(m.ChannelID, "Please specify the channel name and the username") + return + } + + username := strings.TrimPrefix(m.Content, parameters[0]+" "+parameters[1]+" ") + + category := searchChannel(s, m.GuildID, "Personalizzato", "") + if category == nil { + s.ChannelMessageSend(m.ChannelID, "Unable to delete channel, category not found") + } + + channel := searchChannel(s, m.GuildID, parameters[1], category.ID) + if channel == nil { + s.ChannelMessageSend(m.ChannelID, "Channel "+parameters[1]+" not found, unable to add permission") + return + } + + user := searchUser(s, m.GuildID, username) + if user == nil { + s.ChannelMessageSend(m.ChannelID, "User "+username+" not found") + return + } + + if len(channel.PermissionOverwrites) == 0 { + s.ChannelMessageSend(m.ChannelID, "You cannot change permissions of a public channel") + return + } + + // Check if the user has got permissions + authorized := false + for _, role := range channel.PermissionOverwrites { + if role.ID == m.Author.ID && role.Allow&0x00000010 == 0x00000010 { + authorized = true + } + } + + if authorized { + s.ChannelPermissionSet(channel.ID, user.ID, discordgo.PermissionOverwriteTypeMember, 0x00100000, 0) + s.ChannelMessageSend(m.ChannelID, "User "+username+" can now join "+parameters[1]) + } else { + s.ChannelMessageSend(m.ChannelID, "You don't have the permission to authorize an user to join "+parameters[1]) + } +} diff --git a/cmd/innkeeperbot/main.go b/cmd/innkeeperbot/main.go deleted file mode 100644 index 8f078f9..0000000 --- a/cmd/innkeeperbot/main.go +++ /dev/null @@ -1,430 +0,0 @@ -// InnkeeperBot, a bot to create and manage custom channels -// Copyright (C) 2020 Matteo Schiff -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published -// by the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package main - -import ( - "flag" - "fmt" - "os" - "os/signal" - "strings" - "syscall" - "time" - - "github.com/bwmarrin/discordgo" -) - -// Variables used for command line parameters -var ( - Token string -) - -func init() { - - flag.StringVar(&Token, "t", "", "Bot Token") - flag.Parse() -} - -func main() { - - // Create a new Discord session using the provided bot token. - dg, err := discordgo.New("Bot " + Token) - if err != nil { - fmt.Println("error creating Discord session,", err) - return - } - - // Register the messageCreate func as a callback for MessageCreate events. - dg.AddHandler(messageCreate) - - // Open a websocket connection to Discord and begin listening. - err = dg.Open() - if err != nil { - fmt.Println("error opening connection,", err) - return - } - - // Wait here until CTRL-C or other term signal is received. - fmt.Println("Bot is now running. Press CTRL-C to exit.") - sc := make(chan os.Signal, 1) - signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill) - <-sc - - // Cleanly close down the Discord session. - dg.Close() -} - -// This function will be called (due to AddHandler above) every time a new -// message is created on any channel that the autenticated bot has access to. -func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) { - - // Ignore all messages created by the bot itself - if m.Author.ID == s.State.User.ID { - return - } - // If the message starts with "!new", create a new custom channel. Parameters: name, privacy [public or private](default public, optional) - if strings.HasPrefix(m.Content, "!new") { - // Parameters should contains the channel name and the privacy preference - parameters := strings.Fields(m.Content) - if len(parameters) < 1 { - s.ChannelMessageSend(m.ChannelID, "Please specify the channel name") - return - } - - category := searchChannel(s, m.GuildID, "Personalizzato", "") - if category == nil { - s.ChannelMessageSend(m.ChannelID, "Unable to create channel, category not found") - return - } - - newChannelData := discordgo.GuildChannelCreateData{ - Name: parameters[1], - Type: discordgo.ChannelTypeGuildVoice, - ParentID: category.ID} - - newChannel, _ := s.GuildChannelCreateComplex(m.GuildID, newChannelData) - - // Allow the channel creator and the bot to join the channel - s.ChannelPermissionSet(newChannel.ID, s.State.User.ID, "member", 0x00100000|0x00000010, 0) - s.ChannelPermissionSet(newChannel.ID, m.Author.ID, "member", 0x00100000|0x00000010, 0) - - if len(parameters) > 2 && parameters[2] == "private" { - roleEveryone := searchRole(s, m.GuildID, "@everyone") - // Deny anyone else joining this channel - s.ChannelPermissionSet(newChannel.ID, roleEveryone.ID, "role", 0, 0x00100000) - } - - s.ChannelMessageSend(m.ChannelID, "New channel created: "+parameters[1]) - } - - // If the message starts with "!del", delete a custom channel. Parameters: name - if strings.HasPrefix(m.Content, "!del") { - // Parameters should contains the name of the channel to delete - parameters := strings.Fields(m.Content) - if len(parameters) < 1 { - s.ChannelMessageSend(m.ChannelID, "Please specify the channel name") - return - } - - category := searchChannel(s, m.GuildID, "Personalizzato", "") - if category == nil { - s.ChannelMessageSend(m.ChannelID, "Unable to delete channel, category not found") - return - } - - channel := searchChannel(s, m.GuildID, parameters[1], category.ID) - if channel == nil { - s.ChannelMessageSend(m.ChannelID, "Unable to delete channel, not found") - } else if len(channel.PermissionOverwrites) == 0 { - s.ChannelDelete(channel.ID) - s.ChannelMessageSend(m.ChannelID, "Channel "+parameters[1]+" deleted") - } else { - // Check if the user has got manage channels permissions - authorized := false - for _, role := range channel.PermissionOverwrites { - if role.ID == m.Author.ID && role.Allow&0x00000010 == 0x00000010 { - authorized = true - } - } - - if authorized { - s.ChannelDelete(channel.ID) - s.ChannelMessageSend(m.ChannelID, "Channel "+parameters[1]+" deleted") - } else { - s.ChannelMessageSend(m.ChannelID, "You don't have the permission to delete this channel") - } - } - } - - // If the message starts with "!add", enable an user to join the channel. Parameters: channel name, user name - if strings.HasPrefix(m.Content, "!add") { - // Parameters should contains the channel name and the username - parameters := strings.Fields(m.Content) - if len(parameters) < 2 { - s.ChannelMessageSend(m.ChannelID, "Please specify the channel name and the username") - return - } - - username := strings.TrimPrefix(m.Content, parameters[0]+" "+parameters[1]+" ") - - category := searchChannel(s, m.GuildID, "Personalizzato", "") - if category == nil { - s.ChannelMessageSend(m.ChannelID, "Unable to delete channel, category not found") - } - - channel := searchChannel(s, m.GuildID, parameters[1], category.ID) - if channel == nil { - s.ChannelMessageSend(m.ChannelID, "Channel "+parameters[1]+" not found, unable to add permission") - return - } - - user := searchUser(s, m.GuildID, username) - if user == nil { - s.ChannelMessageSend(m.ChannelID, "User "+username+" not found") - return - } - - if len(channel.PermissionOverwrites) == 0 { - s.ChannelMessageSend(m.ChannelID, "You cannot change permissions of a public channel") - return - } - - // Check if the user has got permissions - authorized := false - for _, role := range channel.PermissionOverwrites { - if role.ID == m.Author.ID && role.Allow&0x00000010 == 0x00000010 { - authorized = true - } - } - - if authorized { - s.ChannelPermissionSet(channel.ID, user.ID, "member", 0x00100000, 0) - s.ChannelMessageSend(m.ChannelID, "User "+username+" can now join "+parameters[1]) - } else { - s.ChannelMessageSend(m.ChannelID, "You don't have the permission to authorize an user to join "+parameters[1]) - } - } - - // If the message starts with "!rem", remove from an user the permission to join the channel. Parameters: channel name, user name - if strings.HasPrefix(m.Content, "!rem") { - // Parameters should contains the channel name and the username - parameters := strings.Fields(m.Content) - if len(parameters) < 2 { - s.ChannelMessageSend(m.ChannelID, "Please specify the channel name and the username") - return - } - - username := strings.TrimPrefix(m.Content, parameters[0]+" "+parameters[1]+" ") - - category := searchChannel(s, m.GuildID, "Personalizzato", "") - - if category == nil { - s.ChannelMessageSend(m.ChannelID, "Unable to delete channel, category not found") - } - - channel := searchChannel(s, m.GuildID, parameters[1], category.ID) - if channel == nil { - s.ChannelMessageSend(m.ChannelID, "Channel "+parameters[1]+" not found, unable to remove permission") - return - } - - user := searchUser(s, m.GuildID, username) - if user == nil { - s.ChannelMessageSend(m.ChannelID, "User "+username+" not found") - return - } - - if len(channel.PermissionOverwrites) == 0 { - s.ChannelMessageSend(m.ChannelID, "You cannot change permissions of a public channel") - return - } - - // Check if the user has got permissions - authorized := false - for _, role := range channel.PermissionOverwrites { - if role.ID == m.Author.ID && role.Allow&0x00000010 == 0x00000010 { - authorized = true - } - } - - if authorized { - s.ChannelPermissionDelete(channel.ID, user.ID) - s.ChannelMessageSend(m.ChannelID, "User "+username+" cannot join "+parameters[1]+" anymore") - } else { - s.ChannelMessageSend(m.ChannelID, "You don't have the permission to revoke the authorization of an user to join "+parameters[1]) - } - - } - - // If the message starts with "!op", enable an user to manage the channel. Parameters: channel name, user name - if strings.HasPrefix(m.Content, "!op") { - // Parameters should contains the channel name and the username - parameters := strings.Fields(m.Content) - if len(parameters) < 2 { - s.ChannelMessageSend(m.ChannelID, "Please specify the channel name and the username") - return - } - - username := strings.TrimPrefix(m.Content, parameters[0]+" "+parameters[1]+" ") - - category := searchChannel(s, m.GuildID, "Personalizzato", "") - if category == nil { - s.ChannelMessageSend(m.ChannelID, "Unable to delete channel, category not found") - } - - channel := searchChannel(s, m.GuildID, parameters[1], category.ID) - if channel == nil { - s.ChannelMessageSend(m.ChannelID, "Channel "+parameters[1]+" not found, unable to add permission") - return - } - - user := searchUser(s, m.GuildID, username) - if user == nil { - s.ChannelMessageSend(m.ChannelID, "User "+username+" not found") - return - } - - if len(channel.PermissionOverwrites) == 0 { - s.ChannelMessageSend(m.ChannelID, "You cannot change permissions of a public channel") - return - } - - // Check if the user has got permissions - authorized := false - for _, role := range channel.PermissionOverwrites { - if role.ID == m.Author.ID && role.Allow&0x00000010 == 0x00000010 { - authorized = true - } - } - - if authorized { - s.ChannelPermissionSet(channel.ID, user.ID, "member", 0x00100000|0x00000010, 0) - s.ChannelMessageSend(m.ChannelID, "User "+username+" can now manage "+parameters[1]) - } else { - s.ChannelMessageSend(m.ChannelID, "You don't have the permission to authorize an user to manage "+parameters[1]) - } - } - - // If the message starts with "!deop", remove from an user the permission to manage the channel. Parameters: channel name, user name - if strings.HasPrefix(m.Content, "!deop") { - // Parameters should contains the channel name and the username - parameters := strings.Fields(m.Content) - if len(parameters) < 2 { - s.ChannelMessageSend(m.ChannelID, "Please specify the channel name and the username") - return - } - - username := strings.TrimPrefix(m.Content, parameters[0]+" "+parameters[1]+" ") - - category := searchChannel(s, m.GuildID, "Personalizzato", "") - - if category == nil { - s.ChannelMessageSend(m.ChannelID, "Unable to delete channel, category not found") - } - - channel := searchChannel(s, m.GuildID, parameters[1], category.ID) - if channel == nil { - s.ChannelMessageSend(m.ChannelID, "Channel "+parameters[1]+" not found, unable to remove permission") - return - } - - user := searchUser(s, m.GuildID, username) - if user == nil { - s.ChannelMessageSend(m.ChannelID, "User "+username+" not found") - return - } - - if len(channel.PermissionOverwrites) == 0 { - s.ChannelMessageSend(m.ChannelID, "You cannot change permissions of a public channel") - return - } - - // Check if the user has got permissions - authorized := false - for _, role := range channel.PermissionOverwrites { - if role.ID == m.Author.ID && role.Allow&0x00000010 == 0x00000010 { - authorized = true - } - } - - if authorized { - s.ChannelPermissionSet(channel.ID, user.ID, "member", 0x00100000, 0) - s.ChannelMessageSend(m.ChannelID, "User "+username+" cannot manage "+parameters[1]+" anymore") - } else { - s.ChannelMessageSend(m.ChannelID, "You don't have the permission to revoke the authorization of an user to manage "+parameters[1]) - } - - } - - // If the message starts with "!rpc", remove from an user the permission to join the channel. Parameters: channel name, user name - if strings.HasPrefix(m.Content, "!help") { - - embed := &discordgo.MessageEmbed{ - Author: &discordgo.MessageEmbedAuthor{}, - Description: "InnkeeperBot allow users to manage custom channels", - Color: 0x00ff00, - Fields: []*discordgo.MessageEmbedField{ - &discordgo.MessageEmbedField{ - Name: "!new [private]", - Value: "Create a new channel. Add the \"private\" keyword at the end of the command to make that channel private", - }, - &discordgo.MessageEmbedField{ - Name: "!del ", - Value: "Delete an existing channel", - }, - &discordgo.MessageEmbedField{ - Name: "!add ", - Value: "Give an user the permission to join a channel", - }, - &discordgo.MessageEmbedField{ - Name: "!rem ", - Value: "Remove join permission from an user", - }, - &discordgo.MessageEmbedField{ - Name: "!op ", - Value: "Give an user the permission to join, edit and delete a channel", - }, - &discordgo.MessageEmbedField{ - Name: "!deop ", - Value: "Remove join/edit/delete permission from an user", - }, - }, - Timestamp: time.Now().Format(time.RFC3339), - Title: "InnkeeperBot help", - } - - s.ChannelMessageSendEmbed(m.ChannelID, embed) - } -} - -func searchChannel(s *discordgo.Session, guildID string, channelName string, channelParent string) (channel *discordgo.Channel) { - channels, _ := s.GuildChannels(guildID) - - for _, channel := range channels { - if channel.Name == channelName { - if channelParent == "" || channel.ParentID == channelParent { - return channel - } - } - } - - return nil -} - -func searchRole(s *discordgo.Session, guildID string, roleName string) (role *discordgo.Role) { - roles, _ := s.GuildRoles(guildID) - - for _, role := range roles { - if role.Name == roleName { - return role - } - } - - return nil -} - -func searchUser(s *discordgo.Session, guildID string, userName string) (role *discordgo.User) { - users, _ := s.GuildMembers(guildID, "", 1000) - - for _, user := range users { - if user.User.Username == userName { - return user.User - } - } - - return nil -} diff --git a/del.go b/del.go new file mode 100644 index 0000000..56f0bb3 --- /dev/null +++ b/del.go @@ -0,0 +1,45 @@ +package main + +import ( + "strings" + + "github.com/bwmarrin/discordgo" +) + +func commandDelete(s *discordgo.Session, m *discordgo.MessageCreate) { + // Parameters should contains the name of the channel to delete + parameters := strings.Fields(m.Content) + if len(parameters) < 1 { + s.ChannelMessageSend(m.ChannelID, "Please specify the channel name") + return + } + + category := searchChannel(s, m.GuildID, "Personalizzato", "") + if category == nil { + s.ChannelMessageSend(m.ChannelID, "Unable to delete channel, category not found") + return + } + + channel := searchChannel(s, m.GuildID, parameters[1], category.ID) + if channel == nil { + s.ChannelMessageSend(m.ChannelID, "Unable to delete channel, not found") + } else if len(channel.PermissionOverwrites) == 0 { + s.ChannelDelete(channel.ID) + s.ChannelMessageSend(m.ChannelID, "Channel "+parameters[1]+" deleted") + } else { + // Check if the user has got manage channels permissions + authorized := false + for _, role := range channel.PermissionOverwrites { + if role.ID == m.Author.ID && role.Allow&0x00000010 == 0x00000010 { + authorized = true + } + } + + if authorized { + s.ChannelDelete(channel.ID) + s.ChannelMessageSend(m.ChannelID, "Channel "+parameters[1]+" deleted") + } else { + s.ChannelMessageSend(m.ChannelID, "You don't have the permission to delete this channel") + } + } +} diff --git a/deop.go b/deop.go new file mode 100644 index 0000000..e1e7954 --- /dev/null +++ b/deop.go @@ -0,0 +1,56 @@ +package main + +import ( + "strings" + + "github.com/bwmarrin/discordgo" +) + +func commandDeop(s *discordgo.Session, m *discordgo.MessageCreate) { + // Parameters should contains the channel name and the username + parameters := strings.Fields(m.Content) + if len(parameters) < 2 { + s.ChannelMessageSend(m.ChannelID, "Please specify the channel name and the username") + return + } + + username := strings.TrimPrefix(m.Content, parameters[0]+" "+parameters[1]+" ") + + category := searchChannel(s, m.GuildID, "Personalizzato", "") + + if category == nil { + s.ChannelMessageSend(m.ChannelID, "Unable to delete channel, category not found") + } + + channel := searchChannel(s, m.GuildID, parameters[1], category.ID) + if channel == nil { + s.ChannelMessageSend(m.ChannelID, "Channel "+parameters[1]+" not found, unable to remove permission") + return + } + + user := searchUser(s, m.GuildID, username) + if user == nil { + s.ChannelMessageSend(m.ChannelID, "User "+username+" not found") + return + } + + if len(channel.PermissionOverwrites) == 0 { + s.ChannelMessageSend(m.ChannelID, "You cannot change permissions of a public channel") + return + } + + // Check if the user has got permissions + authorized := false + for _, role := range channel.PermissionOverwrites { + if role.ID == m.Author.ID && role.Allow&0x00000010 == 0x00000010 { + authorized = true + } + } + + if authorized { + s.ChannelPermissionSet(channel.ID, user.ID, discordgo.PermissionOverwriteTypeMember, 0x00100000, 0) + s.ChannelMessageSend(m.ChannelID, "User "+username+" cannot manage "+parameters[1]+" anymore") + } else { + s.ChannelMessageSend(m.ChannelID, "You don't have the permission to revoke the authorization of an user to manage "+parameters[1]) + } +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..873fb24 --- /dev/null +++ b/go.mod @@ -0,0 +1,9 @@ +module github.com/Matte23/InnkeeperBot + +go 1.17 + +require ( + github.com/bwmarrin/discordgo v0.23.2 + github.com/gorilla/websocket v1.4.0 // indirect + golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..28dbed2 --- /dev/null +++ b/go.sum @@ -0,0 +1,6 @@ +github.com/bwmarrin/discordgo v0.23.2 h1:BzrtTktixGHIu9Tt7dEE6diysEF9HWnXeHuoJEt2fH4= +github.com/bwmarrin/discordgo v0.23.2/go.mod h1:c1WtWUGN6nREDmzIpyTp/iD3VYt4Fpx+bVyfBG7JE+M= +github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16 h1:y6ce7gCWtnH+m3dCjzQ1PCuwl28DDIc3VNnvY29DlIA= +golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/help.go b/help.go new file mode 100644 index 0000000..8069710 --- /dev/null +++ b/help.go @@ -0,0 +1,45 @@ +package main + +import ( + "time" + + "github.com/bwmarrin/discordgo" +) + +func commandHelp(s *discordgo.Session, m *discordgo.MessageCreate) { + embed := &discordgo.MessageEmbed{ + Author: &discordgo.MessageEmbedAuthor{}, + Description: "InnkeeperBot allow users to manage custom channels", + Color: 0x00ff00, + Fields: []*discordgo.MessageEmbedField{ + &discordgo.MessageEmbedField{ + Name: "!new [private]", + Value: "Create a new channel. Add the \"private\" keyword at the end of the command to make that channel private", + }, + &discordgo.MessageEmbedField{ + Name: "!del ", + Value: "Delete an existing channel", + }, + &discordgo.MessageEmbedField{ + Name: "!add ", + Value: "Give an user the permission to join a channel", + }, + &discordgo.MessageEmbedField{ + Name: "!rem ", + Value: "Remove join permission from an user", + }, + &discordgo.MessageEmbedField{ + Name: "!op ", + Value: "Give an user the permission to join, edit and delete a channel", + }, + &discordgo.MessageEmbedField{ + Name: "!deop ", + Value: "Remove join/edit/delete permission from an user", + }, + }, + Timestamp: time.Now().Format(time.RFC3339), + Title: "InnkeeperBot help", + } + + s.ChannelMessageSendEmbed(m.ChannelID, embed) +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..07c947e --- /dev/null +++ b/main.go @@ -0,0 +1,112 @@ +// InnkeeperBot, a bot to create and manage custom channels +// Copyright (C) 2020 Matteo Schiff +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package main + +import ( + "flag" + "fmt" + "os" + "os/signal" + "strings" + "syscall" + + "github.com/bwmarrin/discordgo" +) + +// Variables used for command line parameters +var ( + Token string +) + +func init() { + + flag.StringVar(&Token, "t", "", "Bot Token") + flag.Parse() +} + +func main() { + + // Create a new Discord session using the provided bot token. + dg, err := discordgo.New("Bot " + Token) + if err != nil { + fmt.Println("error creating Discord session,", err) + return + } + + // Register the messageCreate func as a callback for MessageCreate events. + dg.AddHandler(handleMessage) + + // Open a websocket connection to Discord and begin listening. + err = dg.Open() + if err != nil { + fmt.Println("error opening connection,", err) + return + } + + // Wait here until CTRL-C or other term signal is received. + fmt.Println("Bot is now running. Press CTRL-C to exit.") + sc := make(chan os.Signal, 1) + signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt) + <-sc + + // Cleanly close down the Discord session. + dg.Close() +} + +// This function will be called (due to AddHandler above) every time a new +// message is created on any channel that the autenticated bot has access to. +func handleMessage(s *discordgo.Session, m *discordgo.MessageCreate) { + + // Ignore all messages created by the bot itself + if m.Author.ID == s.State.User.ID { + return + } + // If the message starts with "!new", create a new custom channel. Parameters: name, privacy [public or private](default public, optional) + if strings.HasPrefix(m.Content, "!new") { + commandNew(s, m) + } + + // If the message starts with "!del", delete a custom channel. Parameters: name + if strings.HasPrefix(m.Content, "!del") { + commandDelete(s, m) + } + + // If the message starts with "!add", enable an user to join the channel. Parameters: channel name, user name + if strings.HasPrefix(m.Content, "!add") { + commandAdd(s, m) + } + + // If the message starts with "!rem", remove from an user the permission to join the channel. Parameters: channel name, user name + if strings.HasPrefix(m.Content, "!rem") { + commandRem(s, m) + } + + // If the message starts with "!op", enable an user to manage the channel. Parameters: channel name, user name + if strings.HasPrefix(m.Content, "!op") { + commandOp(s, m) + } + + // If the message starts with "!deop", remove from an user the permission to manage the channel. Parameters: channel name, user name + if strings.HasPrefix(m.Content, "!deop") { + commandDeop(s, m) + } + + // If the message starts with "!rpc", remove from an user the permission to join the channel. Parameters: channel name, user name + if strings.HasPrefix(m.Content, "!help") { + commandHelp(s, m) + } +} diff --git a/new.go b/new.go new file mode 100644 index 0000000..144a4a8 --- /dev/null +++ b/new.go @@ -0,0 +1,41 @@ +package main + +import ( + "strings" + + "github.com/bwmarrin/discordgo" +) + +func commandNew(s *discordgo.Session, m *discordgo.MessageCreate) { + // Parameters should contains the channel name and the privacy preference + parameters := strings.Fields(m.Content) + if len(parameters) < 1 { + s.ChannelMessageSend(m.ChannelID, "Please specify the channel name") + return + } + + category := searchChannel(s, m.GuildID, "Personalizzato", "") + if category == nil { + s.ChannelMessageSend(m.ChannelID, "Unable to create channel, category not found") + return + } + + newChannelData := discordgo.GuildChannelCreateData{ + Name: parameters[1], + Type: discordgo.ChannelTypeGuildVoice, + ParentID: category.ID} + + newChannel, _ := s.GuildChannelCreateComplex(m.GuildID, newChannelData) + + // Allow the channel creator and the bot to join the channel + s.ChannelPermissionSet(newChannel.ID, s.State.User.ID, discordgo.PermissionOverwriteTypeMember, 0x00100000|0x00000010, 0) + s.ChannelPermissionSet(newChannel.ID, m.Author.ID, discordgo.PermissionOverwriteTypeMember, 0x00100000|0x00000010, 0) + + if len(parameters) > 2 && parameters[2] == "private" { + roleEveryone := searchRole(s, m.GuildID, "@everyone") + // Deny anyone else joining this channel + s.ChannelPermissionSet(newChannel.ID, roleEveryone.ID, discordgo.PermissionOverwriteTypeRole, 0, 0x00100000) + } + + s.ChannelMessageSend(m.ChannelID, "New channel created: "+parameters[1]) +} diff --git a/op.go b/op.go new file mode 100644 index 0000000..ad60a64 --- /dev/null +++ b/op.go @@ -0,0 +1,55 @@ +package main + +import ( + "strings" + + "github.com/bwmarrin/discordgo" +) + +func commandOp(s *discordgo.Session, m *discordgo.MessageCreate) { + // Parameters should contains the channel name and the username + parameters := strings.Fields(m.Content) + if len(parameters) < 2 { + s.ChannelMessageSend(m.ChannelID, "Please specify the channel name and the username") + return + } + + username := strings.TrimPrefix(m.Content, parameters[0]+" "+parameters[1]+" ") + + category := searchChannel(s, m.GuildID, "Personalizzato", "") + if category == nil { + s.ChannelMessageSend(m.ChannelID, "Unable to delete channel, category not found") + } + + channel := searchChannel(s, m.GuildID, parameters[1], category.ID) + if channel == nil { + s.ChannelMessageSend(m.ChannelID, "Channel "+parameters[1]+" not found, unable to add permission") + return + } + + user := searchUser(s, m.GuildID, username) + if user == nil { + s.ChannelMessageSend(m.ChannelID, "User "+username+" not found") + return + } + + if len(channel.PermissionOverwrites) == 0 { + s.ChannelMessageSend(m.ChannelID, "You cannot change permissions of a public channel") + return + } + + // Check if the user has got permissions + authorized := false + for _, role := range channel.PermissionOverwrites { + if role.ID == m.Author.ID && role.Allow&0x00000010 == 0x00000010 { + authorized = true + } + } + + if authorized { + s.ChannelPermissionSet(channel.ID, user.ID, discordgo.PermissionOverwriteTypeMember, 0x00100000|0x00000010, 0) + s.ChannelMessageSend(m.ChannelID, "User "+username+" can now manage "+parameters[1]) + } else { + s.ChannelMessageSend(m.ChannelID, "You don't have the permission to authorize an user to manage "+parameters[1]) + } +} diff --git a/rem.go b/rem.go new file mode 100644 index 0000000..c04b76d --- /dev/null +++ b/rem.go @@ -0,0 +1,56 @@ +package main + +import ( + "strings" + + "github.com/bwmarrin/discordgo" +) + +func commandRem(s *discordgo.Session, m *discordgo.MessageCreate) { + // Parameters should contains the channel name and the username + parameters := strings.Fields(m.Content) + if len(parameters) < 2 { + s.ChannelMessageSend(m.ChannelID, "Please specify the channel name and the username") + return + } + + username := strings.TrimPrefix(m.Content, parameters[0]+" "+parameters[1]+" ") + + category := searchChannel(s, m.GuildID, "Personalizzato", "") + + if category == nil { + s.ChannelMessageSend(m.ChannelID, "Unable to delete channel, category not found") + } + + channel := searchChannel(s, m.GuildID, parameters[1], category.ID) + if channel == nil { + s.ChannelMessageSend(m.ChannelID, "Channel "+parameters[1]+" not found, unable to remove permission") + return + } + + user := searchUser(s, m.GuildID, username) + if user == nil { + s.ChannelMessageSend(m.ChannelID, "User "+username+" not found") + return + } + + if len(channel.PermissionOverwrites) == 0 { + s.ChannelMessageSend(m.ChannelID, "You cannot change permissions of a public channel") + return + } + + // Check if the user has got permissions + authorized := false + for _, role := range channel.PermissionOverwrites { + if role.ID == m.Author.ID && role.Allow&0x00000010 == 0x00000010 { + authorized = true + } + } + + if authorized { + s.ChannelPermissionDelete(channel.ID, user.ID) + s.ChannelMessageSend(m.ChannelID, "User "+username+" cannot join "+parameters[1]+" anymore") + } else { + s.ChannelMessageSend(m.ChannelID, "You don't have the permission to revoke the authorization of an user to join "+parameters[1]) + } +} diff --git a/utils.go b/utils.go new file mode 100644 index 0000000..14ec940 --- /dev/null +++ b/utils.go @@ -0,0 +1,41 @@ +package main + +import "github.com/bwmarrin/discordgo" + +func searchChannel(s *discordgo.Session, guildID string, channelName string, channelParent string) (channel *discordgo.Channel) { + channels, _ := s.GuildChannels(guildID) + + for _, channel := range channels { + if channel.Name == channelName { + if channelParent == "" || channel.ParentID == channelParent { + return channel + } + } + } + + return nil +} + +func searchRole(s *discordgo.Session, guildID string, roleName string) (role *discordgo.Role) { + roles, _ := s.GuildRoles(guildID) + + for _, role := range roles { + if role.Name == roleName { + return role + } + } + + return nil +} + +func searchUser(s *discordgo.Session, guildID string, userName string) (role *discordgo.User) { + users, _ := s.GuildMembers(guildID, "", 1000) + + for _, user := range users { + if user.User.Username == userName { + return user.User + } + } + + return nil +}