From 757500eb42327690c053ef8e1d250f29441994f3 Mon Sep 17 00:00:00 2001 From: Matte23 Date: Thu, 28 Oct 2021 12:10:25 +0200 Subject: [PATCH] Tidy code up --- .gitignore | 2 + add.go | 55 +++++ cmd/innkeeperbot/main.go | 430 --------------------------------------- del.go | 45 ++++ deop.go | 56 +++++ go.mod | 9 + go.sum | 6 + help.go | 45 ++++ main.go | 112 ++++++++++ new.go | 41 ++++ op.go | 55 +++++ rem.go | 56 +++++ utils.go | 41 ++++ 13 files changed, 523 insertions(+), 430 deletions(-) create mode 100644 add.go delete mode 100644 cmd/innkeeperbot/main.go create mode 100644 del.go create mode 100644 deop.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 help.go create mode 100644 main.go create mode 100644 new.go create mode 100644 op.go create mode 100644 rem.go create mode 100644 utils.go 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 +}