forked from kageru/discord-selphybot
Compare commits
18 Commits
Author | SHA1 | Date | |
---|---|---|---|
kageru | d6383af189 | ||
kageru | 6393950694 | ||
kageru | 3cdb5418ff | ||
kageru | ffae758587 | ||
kageru | 943e9fcaba | ||
kageru | a99496377e | ||
kageru | c22f81d6cb | ||
kageru | a4e7ecb92e | ||
kageru | 67fb364f4f | ||
kageru | 7be862a133 | ||
kageru | 377bdde44b | ||
kageru | 982144f059 | ||
kageru | 3b672e2f30 | ||
kageru | 9dd7775168 | ||
kageru | 4566ffc230 | ||
kageru | 6e7229d787 | ||
kageru | ebd7f0bb5e | ||
kageru | 0b522fde88 |
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -1,6 +1,18 @@
|
|||
# Selphybot Changelog
|
||||
Updates are listed in reverse chronological order.
|
||||
|
||||
### 1.5 (dev)
|
||||
- added !vc to create temporary voice channels
|
||||
|
||||
### 1.4
|
||||
- a copy of each deleted message is now send via DM to the author (suggested by CommanderLook)
|
||||
- seasonal fluff
|
||||
- finally use gofmt
|
||||
- better logging of own messages and embeds
|
||||
- logging always occurs after the action that is being logged
|
||||
- redirect function is much cleaner now
|
||||
- commands can be limited to certain channels
|
||||
|
||||
### 1.3
|
||||
- use global array of pointers to commands to allow easier modification and avoid unnecessary memcpy
|
||||
- added feedback to !complain (used to work but was forgotten when refactoring)
|
||||
|
|
141
command.go
141
command.go
|
@ -4,10 +4,10 @@ import (
|
|||
"fmt"
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"github.com/deckarep/golang-set"
|
||||
"strings"
|
||||
"time"
|
||||
"log"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type CommandType int
|
||||
|
@ -41,11 +41,11 @@ type Command struct {
|
|||
IgnoreCase bool
|
||||
// for custom commands that go beyond prints and deletions
|
||||
Function func(*discordgo.Session, *discordgo.MessageCreate)
|
||||
AllowedChannels mapset.Set // allowed everywhere if blank
|
||||
|
||||
UsersOnCooldown mapset.Set // don’t set this manually (it’s overwritten anyway)
|
||||
}
|
||||
|
||||
|
||||
// Performs basic input validation on a given command and adds it to the global command array
|
||||
func registerCommand(command Command) {
|
||||
if command.Trigger == "" {
|
||||
|
@ -56,6 +56,9 @@ func registerCommand(command Command) {
|
|||
command.Trigger = strings.ToLower(command.Trigger)
|
||||
}
|
||||
command.UsersOnCooldown = mapset.NewSet()
|
||||
if command.AllowedChannels == nil {
|
||||
command.AllowedChannels = mapset.NewSet()
|
||||
}
|
||||
commands = append(commands, &command)
|
||||
}
|
||||
|
||||
|
@ -68,7 +71,12 @@ func registerCommand(command Command) {
|
|||
*/
|
||||
func evaluateMessage(s *discordgo.Session, m *discordgo.MessageCreate) {
|
||||
if m.Author.ID == s.State.User.ID {
|
||||
// Properly log embeds
|
||||
if len(m.Embeds) > 0 {
|
||||
log.Printf("<Self> %s", m.Embeds[0].Description)
|
||||
} else {
|
||||
log.Printf("<Self> %s", m.Content)
|
||||
}
|
||||
return
|
||||
}
|
||||
for _, command := range commands {
|
||||
|
@ -110,10 +118,7 @@ func evaluateMessage(s *discordgo.Session, m *discordgo.MessageCreate) {
|
|||
Sets command cooldowns if necessary and also clears them again.
|
||||
*/
|
||||
func executeCommand(session *discordgo.Session, message *discordgo.MessageCreate, command *Command) {
|
||||
if isAdmin(message.Author) || // no restrictions for admins
|
||||
(!command.AdminOnly && (isDM(session, message) || !command.UsersOnCooldown.Contains(message.Author.ID)) &&
|
||||
(!command.DMOnly || isDM(session, message))) {
|
||||
|
||||
if commandAllowed(session, message, command) {
|
||||
log.Printf("Executed command %s triggered by user %s", command.Trigger, userToString(message.Author))
|
||||
if command.Cooldown > 0 && !isDM(session, message) && !isAdmin(message.Author) {
|
||||
command.UsersOnCooldown.Add(message.Author.ID)
|
||||
|
@ -128,7 +133,7 @@ func executeCommand(session *discordgo.Session, message *discordgo.MessageCreate
|
|||
session.ChannelMessageSendEmbed(message.ChannelID, command.OutputEmbed)
|
||||
}
|
||||
if command.DeleteInput {
|
||||
session.ChannelMessageDelete(message.ChannelID, message.ID)
|
||||
deleteAndSendViaDM(session, message)
|
||||
}
|
||||
} else {
|
||||
// execute custom function
|
||||
|
@ -139,6 +144,37 @@ func executeCommand(session *discordgo.Session, message *discordgo.MessageCreate
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if a user has the permission to trigger a given command.
|
||||
* To be honest, this whole logic is a mess, but I don’t know a better way to handle it.
|
||||
*/
|
||||
func commandAllowed(session *discordgo.Session, message *discordgo.MessageCreate, command *Command) bool {
|
||||
// no restrictions for admins
|
||||
if isAdmin(message.Author) {
|
||||
return true
|
||||
}
|
||||
// blacklist admin commands for everyone else
|
||||
if command.AdminOnly {
|
||||
return false
|
||||
}
|
||||
// cooldowns are irrelevant in DMs
|
||||
if !isDM(session, message) && command.UsersOnCooldown.Contains(message.Author.ID) {
|
||||
return false
|
||||
}
|
||||
// the command is not limited to DMs or we are inside a DM chat
|
||||
if command.DMOnly && !isDM(session, message) {
|
||||
return false
|
||||
}
|
||||
// no allowed channels = all channels are allowed.
|
||||
// DMs are whitelisted by default
|
||||
if command.AllowedChannels.Cardinality() != 0 &&
|
||||
!command.AllowedChannels.Contains(message.ChannelID) &&
|
||||
isDM(session, message) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func removeCooldown(command *Command, uid string) {
|
||||
time.Sleep(time.Duration(command.Cooldown) * time.Second)
|
||||
if command.UsersOnCooldown.Contains(uid) {
|
||||
|
@ -146,6 +182,13 @@ func removeCooldown(command *Command, uid string) {
|
|||
}
|
||||
}
|
||||
|
||||
func deleteAndSendViaDM(s *discordgo.Session, message *discordgo.MessageCreate) {
|
||||
s.ChannelMessageDelete(message.ChannelID, message.ID)
|
||||
dm := getDMChannelFromMessage(s, message)
|
||||
s.ChannelMessageSend(dm.ID, "Deine Nachricht wurde gelöscht, weil sie ein verbotenes Wort enthielt. Falls du sie editieren und erneut abschicken willst, hier die Nachricht:")
|
||||
s.ChannelMessageSend(dm.ID, message.Content)
|
||||
}
|
||||
|
||||
func generateReply(message *discordgo.MessageCreate, command *Command) string {
|
||||
output := command.Output
|
||||
if command.OutputIsReply {
|
||||
|
@ -155,31 +198,50 @@ func generateReply(message *discordgo.MessageCreate, command *Command) string {
|
|||
}
|
||||
|
||||
/*
|
||||
Any message passed to this method will be redirected to config.ModChannel.
|
||||
This is useful for anonymous complaints or similar messages.
|
||||
* I’m beginning to doubt my own self-imposed limitations of
|
||||
* only allowing func(session, message) to be attached to commands,
|
||||
* but refactoring that might be more effort than it’s worth.
|
||||
* Hence, small wrappers around the redirect function.
|
||||
*/
|
||||
func redirectComplaint(s *discordgo.Session, m *discordgo.MessageCreate) {
|
||||
embed := &discordgo.MessageEmbed {
|
||||
Author: &discordgo.MessageEmbedAuthor{},
|
||||
Color: 0xbb0000,
|
||||
Description: m.Content,
|
||||
}
|
||||
s.ChannelMessageSendEmbed(config.ModChannel, embed)
|
||||
func modComplain(s *discordgo.Session, m *discordgo.MessageCreate) {
|
||||
success := redirectMessage(s, m, config.ModChannel, true)
|
||||
dm, _ := s.UserChannelCreate(m.Author.ID)
|
||||
if success {
|
||||
s.ChannelMessageSend(dm.ID, config.ComplaintReceivedMessage)
|
||||
} else {
|
||||
s.ChannelMessageSend(dm.ID, "Could not send message. Please tell kageru about this.")
|
||||
}
|
||||
}
|
||||
|
||||
// copy paste programming btw :haHAA:
|
||||
func redirectComplaintToDM(s *discordgo.Session, m *discordgo.MessageCreate) {
|
||||
func selphyComplain(s *discordgo.Session, m *discordgo.MessageCreate) {
|
||||
dm_target, _ := s.UserChannelCreate("190958368301645824")
|
||||
success := redirectMessage(s, m, dm_target.ID, true)
|
||||
dm, _ := s.UserChannelCreate(m.Author.ID)
|
||||
if success {
|
||||
s.ChannelMessageSend(dm.ID, config.ComplaintReceivedMessage)
|
||||
} else {
|
||||
s.ChannelMessageSend(dm.ID, "Could not send message. Please tell kageru about this.")
|
||||
}
|
||||
}
|
||||
|
||||
func redirectMessage(s *discordgo.Session, m *discordgo.MessageCreate, target string, isEmbed bool) bool {
|
||||
var err error
|
||||
if isEmbed {
|
||||
embed := &discordgo.MessageEmbed{
|
||||
// Embed are anonymized by default for now. Fits the use case.
|
||||
Author: &discordgo.MessageEmbedAuthor{},
|
||||
Color: 0xbb0000,
|
||||
Description: m.Content,
|
||||
}
|
||||
dm_target, _ := s.UserChannelCreate("190958368301645824")
|
||||
s.ChannelMessageSendEmbed(dm_target.ID, embed)
|
||||
dm, _ := s.UserChannelCreate(m.Author.ID)
|
||||
s.ChannelMessageSend(dm.ID, config.ComplaintReceivedMessage)
|
||||
_, err = s.ChannelMessageSendEmbed(target, embed)
|
||||
} else {
|
||||
_, err = s.ChannelMessageSend(target, messageToString(m.Message))
|
||||
}
|
||||
if err != nil {
|
||||
log.Printf("Could not redirect message", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func echoMessage(s *discordgo.Session, m *discordgo.MessageCreate) {
|
||||
|
@ -187,16 +249,38 @@ func echoMessage(s *discordgo.Session, m *discordgo.MessageCreate) {
|
|||
}
|
||||
|
||||
func giveAgeRole(s *discordgo.Session, m *discordgo.MessageCreate) {
|
||||
Member, _ := s.GuildMember(config.ServerID, m.Author.ID)
|
||||
dm, _ := s.UserChannelCreate(Member.User.ID)
|
||||
Member, err := s.GuildMember(config.ServerID, m.Author.ID)
|
||||
if err != nil {
|
||||
log.Printf("User could not be retrieved for role assignment\n%s", err)
|
||||
return
|
||||
}
|
||||
dm, err := s.UserChannelCreate(Member.User.ID)
|
||||
if err != nil {
|
||||
log.Printf("Could not reply to user\n%s", err)
|
||||
return
|
||||
}
|
||||
required := mapset.NewSetWith("416184227672096780", "416184208470310922", "416184150404628480", "416184132473847810", "440996904948465664")
|
||||
for command, role := range config.RoleCommands {
|
||||
if m.Content == command {
|
||||
// Found the command that was triggered
|
||||
// This is a restriction imposed by my own wrapper,
|
||||
// but working around it is not actually necessary for performance and makes the code uglier in other places.
|
||||
for _, newRole := range config.RoleCommands {
|
||||
// check if the user has a twitch sub or any of the patreon roles
|
||||
isAllowed := false
|
||||
for _, curRole := range Member.Roles {
|
||||
// If the user already has one of the available roles, tell him and exit
|
||||
if required.Contains(curRole) {
|
||||
isAllowed = true
|
||||
}
|
||||
}
|
||||
|
||||
if !isAllowed {
|
||||
s.ChannelMessageSend(dm.ID, "Du kannst dir keine Rolle zuweisen, da weder Patreon noch Twitch mit deinem Account verlinkt ist oder du Selphy auf keiner dieser Plattformen unterstützt. Bei Problemen wende dich bitte an die `!mods`.")
|
||||
log.Printf("Denied role %s to %s. User is neither patron nor sub.", roleName(s.State, newRole), userToString(m.Author))
|
||||
return
|
||||
}
|
||||
for _, curRole := range Member.Roles {
|
||||
// If the user already has one of the available roles, tell them and exit
|
||||
if newRole == curRole {
|
||||
if curRole == role {
|
||||
// User is trying to get the role they already have
|
||||
|
@ -210,9 +294,9 @@ func giveAgeRole(s *discordgo.Session, m *discordgo.MessageCreate) {
|
|||
}
|
||||
}
|
||||
}
|
||||
log.Printf("Giving Role %s to %s", roleName(s.State, role), userToString(m.Author))
|
||||
s.ChannelMessageSend(dm.ID, "Haaai, Ryoukai desu~")
|
||||
s.GuildMemberRoleAdd(config.ServerID, m.Author.ID, role)
|
||||
s.ChannelMessageSend(dm.ID, "Haaai, Ryoukai desu~")
|
||||
log.Printf("Giving Role %s to %s", roleName(s.State, role), userToString(m.Author))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -247,4 +331,3 @@ func getHelpEmbed() *discordgo.MessageEmbed {
|
|||
}
|
||||
return embed
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"encoding/json"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Embed struct {
|
||||
|
@ -29,7 +29,6 @@ type Config struct {
|
|||
RoleCommands map[string]string
|
||||
}
|
||||
|
||||
|
||||
func readConfig() Config {
|
||||
file, _ := os.Open("config.json")
|
||||
conf := Config{}
|
||||
|
@ -37,4 +36,3 @@ func readConfig() Config {
|
|||
file.Close()
|
||||
return conf
|
||||
}
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@ func onJoin(s *discordgo.Session, member *discordgo.GuildMemberAdd) {
|
|||
}
|
||||
if err != nil {
|
||||
// if any of the preceding operations produced an error
|
||||
log.Printf("Sending welcome @mention at %s", userToString(member.User))
|
||||
s.ChannelMessageSend(config.GeneralChannel, fmt.Sprintf("Wilkommen <@%s>. Bitte aktiviere vorübergehend DMs für diesen Server und sende eine Nachricht mit !welcome an mich.", member.User.ID))
|
||||
log.Printf("Sending welcome @mention @%s", userToString(member.User))
|
||||
s.ChannelMessageSend(config.GeneralChannel, fmt.Sprintf("Wilkommen <@%s>. Bitte aktiviere vorübergehend DMs für diesen Server und sende eine Nachricht mit !welcome an mich. https://cdn.discordapp.com/attachments/333450842151714816/591581555219234826/Selphy-queen.png", member.User.ID))
|
||||
}
|
||||
}
|
||||
log.Printf("User joined: %s", userToString(member.User))
|
||||
|
@ -32,7 +32,6 @@ func onJoin(s *discordgo.Session, member *discordgo.GuildMemberAdd) {
|
|||
|
||||
func onDM(s *discordgo.Session, m *discordgo.MessageCreate) {
|
||||
log.Printf("Received DM from %s with content: “%s”", userToString(m.Author), m.Content)
|
||||
fmt.Sprintf("Received DM from %s with content: “%s”", userToString(m.Author), m.Content)
|
||||
Member, _ := s.GuildMember(config.ServerID, m.Author.ID)
|
||||
dm, _ := s.UserChannelCreate(Member.User.ID)
|
||||
for comm, role := range config.RoleCommands {
|
||||
|
@ -46,10 +45,9 @@ func onDM(s *discordgo.Session, m *discordgo.MessageCreate) {
|
|||
}
|
||||
}
|
||||
}
|
||||
log.Printf("Giving Role %s to %s", roleName(s.State, role), userToString(m.Author))
|
||||
s.ChannelMessageSend(dm.ID, "Haaai, Ryoukai desu~")
|
||||
s.GuildMemberRoleAdd(config.ServerID, m.Author.ID, role)
|
||||
log.Printf("Giving Role %s to %s", roleName(s.State, role), userToString(m.Author))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
17
helpers.go
17
helpers.go
|
@ -1,9 +1,9 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"log"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func unlockUser(s *discordgo.Session, id string) {
|
||||
|
@ -42,6 +42,11 @@ func isDM(s *discordgo.Session, m *discordgo.MessageCreate) bool {
|
|||
return (getChannel(s.State, m.ChannelID).Type == discordgo.ChannelTypeDM)
|
||||
}
|
||||
|
||||
func getDMChannelFromMessage(s *discordgo.Session, m *discordgo.MessageCreate) *discordgo.Channel {
|
||||
dm, _ := s.UserChannelCreate(m.Author.ID)
|
||||
return dm
|
||||
}
|
||||
|
||||
func isAdmin(u *discordgo.User) bool {
|
||||
for _, admin := range config.Admins {
|
||||
if u.ID == admin {
|
||||
|
@ -50,3 +55,13 @@ func isAdmin(u *discordgo.User) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func getServer() (*discordgo.Guild, error) {
|
||||
server, err := state.Guild(config.ServerID)
|
||||
return server, err
|
||||
}
|
||||
|
||||
func remove(channels []*discordgo.Channel, position int) []*discordgo.Channel {
|
||||
channels[len(channels)-1], channels[position] = channels[position], channels[len(channels)-1]
|
||||
return channels[:len(channels)-1]
|
||||
}
|
||||
|
|
49
main.go
49
main.go
|
@ -2,27 +2,29 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os/signal"
|
||||
"os"
|
||||
"syscall"
|
||||
"log"
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"github.com/deckarep/golang-set"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
var config = readConfig()
|
||||
var commands []*Command
|
||||
var state *discordgo.State
|
||||
|
||||
func main() {
|
||||
dg, err := discordgo.New("Bot " + config.Token)
|
||||
session, err := discordgo.New("Bot " + config.Token)
|
||||
if err != nil {
|
||||
fmt.Println("error: ", err)
|
||||
return
|
||||
}
|
||||
defer dg.Close()
|
||||
defer session.Close()
|
||||
|
||||
dg.AddHandler(evaluateMessage)
|
||||
dg.AddHandler(onJoin)
|
||||
err = dg.Open()
|
||||
session.AddHandler(evaluateMessage)
|
||||
session.AddHandler(onJoin)
|
||||
err = session.Open()
|
||||
if err != nil {
|
||||
fmt.Println("No connection:\n", err)
|
||||
return
|
||||
|
@ -34,7 +36,15 @@ func main() {
|
|||
}
|
||||
defer f.Close()
|
||||
log.SetOutput(f)
|
||||
dg.UpdateStatus(0, "!help")
|
||||
session.UpdateStatus(0, "!help")
|
||||
state = discordgo.NewState()
|
||||
server, err := session.Guild(config.ServerID)
|
||||
if err != nil {
|
||||
fmt.Println("Guild incorrectly configured. Exiting...")
|
||||
return
|
||||
}
|
||||
state.GuildAdd(server)
|
||||
go checkAndDeleteUnusedChannels(session)
|
||||
addCommands()
|
||||
|
||||
fmt.Println("Bot running. selphyWoo")
|
||||
|
@ -43,6 +53,9 @@ func main() {
|
|||
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill)
|
||||
<-sc
|
||||
|
||||
for _, channel := range tempChannels {
|
||||
session.ChannelDelete(channel.ID)
|
||||
}
|
||||
fmt.Println("Exiting...")
|
||||
log.Println("Exiting...")
|
||||
}
|
||||
|
@ -50,31 +63,34 @@ func main() {
|
|||
// I’ll just put all of the commands here for now.
|
||||
func addCommands() {
|
||||
// Moderation
|
||||
registerCommand(Command{Trigger: "^[^`]*([()|DoOvVcC][-=^']?;|;[-=^']?[()|DoOpPvVcC]|:wink:|😉)[^`]*$", Output: "<@%s> Oboe!", DeleteInput: true, OutputIsReply: true, Type: CommandTypeRegex})
|
||||
registerCommand(Command{Trigger: "^[^`]*([()|DoOvVcC][-=^']?;|;[-=^']?[()|DoOpPvVcC3]|:wink:|😉)[^`]*$", Output: "<@%s> Oboe!", DeleteInput: true, OutputIsReply: true, Type: CommandTypeRegex})
|
||||
registerCommand(Command{Trigger: "(\\s|\n|^)[nN][hH]([ ?.,\n]|$)", Output: "<@%s> „nh“ ist kein Wort, du Oboe!", DeleteInput: true, OutputIsReply: true, Type: CommandTypeRegex})
|
||||
registerCommand(Command{Trigger: "einzigste", Output: "<@%s> Es heißt „einzige“, du Tuba.", DeleteInput: true, OutputIsReply: true, Type: CommandTypeContains})
|
||||
registerCommand(Command{Trigger: "!complain", Type: CommandTypePrefix, DMOnly: true, Function: redirectComplaint})
|
||||
registerCommand(Command{Trigger: "!scomplain", Type: CommandTypePrefix, DMOnly: true, Function: redirectComplaintToDM})
|
||||
registerCommand(Command{Trigger: "!beschwerde", Type: CommandTypePrefix, DMOnly: true, Function: redirectComplaint})
|
||||
registerCommand(Command{Trigger: "!complain", Type: CommandTypePrefix, DMOnly: true, Function: modComplain})
|
||||
registerCommand(Command{Trigger: "!scomplain", Type: CommandTypePrefix, DMOnly: true, Function: selphyComplain})
|
||||
registerCommand(Command{Trigger: "!beschwerde", Type: CommandTypePrefix, DMOnly: true, Function: modComplain})
|
||||
|
||||
for comm, _ := range config.RoleCommands {
|
||||
registerCommand(Command{Trigger: comm, Type: CommandTypeFullMatch, DMOnly: true, Function: giveAgeRole})
|
||||
}
|
||||
|
||||
// Misc commands
|
||||
// Fluff
|
||||
registerCommand(Command{Trigger: "o/", Output: "\\o", Type: CommandTypeFullMatch, Cooldown: 10})
|
||||
registerCommand(Command{Trigger: "\\o", Output: "o/", Type: CommandTypeFullMatch, Cooldown: 10})
|
||||
registerCommand(Command{Trigger: "\\o/", Output: "/o\\", Type: CommandTypeFullMatch, Cooldown: 10})
|
||||
registerCommand(Command{Trigger: "/o\\", Output: "\\o/", Type: CommandTypeFullMatch, Cooldown: 10})
|
||||
registerCommand(Command{Trigger: "!heil", Output: "(ノ・ェ・)ノ Selphy (ノ・ェ・)ノ", Type: CommandTypeFullMatch, Cooldown: 30})
|
||||
registerCommand(Command{Trigger: "ayy", Output: "lmao", Type: CommandTypeFullMatch, Cooldown: 0})
|
||||
registerCommand(Command{Trigger: "<:selphyDango:441001954542616576>", Output: "<:dango:430669469799677953> :notes: Dango Daikazoku :notes: <:dango:430669469799677953>", Type: CommandTypeFullMatch, Cooldown: 10800})
|
||||
registerCommand(Command{Trigger: "<:selphyDango:531594585424527370>", Output: "<:dango:430669469799677953> :notes: Dango Daikazoku :notes: <:dango:430669469799677953>", Type: CommandTypeFullMatch, Cooldown: 10800})
|
||||
registerCommand(Command{Trigger: "praise the sun", Output: "If only I could be so grossly incandescent \\\\[T]/", Type: CommandTypeContains, IgnoreCase: true, Cooldown: 85600})
|
||||
|
||||
// Information
|
||||
registerCommand(Command{Trigger: "!welcome", OutputEmbed: getWelcomeEmbed(), Type: CommandTypeFullMatch, DMOnly: true})
|
||||
registerCommand(Command{Trigger: "!mods", Output: "Bei Fragen, Problemen und Beschwerden wende dich bitte an die Moderatoren oder schick mir eine Nachricht beginnend mit !complain, um dich anonym zu beschweren.\nAktuell anwesende Mods werden dir rechts mit dem Rang „Maid“ angezeigt.", Type: CommandTypeFullMatch})
|
||||
|
||||
// Features :Pog:
|
||||
registerCommand(Command{Trigger: "!vc ", Type: CommandTypePrefix, Function: parseVoiceChannelCommand, AllowedChannels: mapset.NewSetWith("525852491976278016")})
|
||||
|
||||
// Admin and/or debug
|
||||
registerCommand(Command{Trigger: "<@%s> <3", Output: "<@%s> <3", Type: CommandTypeFullMatch, AdminOnly: true, OutputIsReply: true, RequiresMention: true})
|
||||
registerCommand(Command{Trigger: "echo", Type: CommandTypePrefix, Function: echoMessage, AdminOnly: true})
|
||||
|
@ -85,4 +101,3 @@ func addCommands() {
|
|||
fmt.Printf("Successfully initialized %d commands\n", len(commands))
|
||||
log.Printf("Successfully initialized %d commands", len(commands))
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"log"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var tempChannels []*discordgo.Channel
|
||||
|
||||
func parseVoiceChannelCommand(session *discordgo.Session, message *discordgo.MessageCreate) {
|
||||
userLimit, err := strconv.Atoi(strings.Split(message.Content, " ")[1])
|
||||
if err != nil {
|
||||
session.ChannelMessageSend(message.ChannelID, "Error: Expected a number after !vc")
|
||||
log.Printf("Incorrect syntax for !vc, “%s” triggered by %s", message.Content, userToString(message.Author))
|
||||
return
|
||||
}
|
||||
if userLimit > 99 {
|
||||
session.ChannelMessageSend(message.ChannelID, fmt.Sprintf("Als ob %d Leute *mit dir* in einen Channel wollen.", userLimit-1))
|
||||
log.Printf("%s tried to create a channel with %d slots", userToString(message.Author), userLimit)
|
||||
return
|
||||
}
|
||||
createData := discordgo.GuildChannelCreateData{
|
||||
Name: fmt.Sprintf("%s’s Volatile Corner", message.Author.Username),
|
||||
Type: discordgo.ChannelTypeGuildVoice,
|
||||
UserLimit: userLimit,
|
||||
ParentID: "410162599762853909",
|
||||
}
|
||||
channel, err := session.GuildChannelCreateComplex(message.GuildID, createData)
|
||||
if err != nil {
|
||||
session.ChannelMessageSend(message.ChannelID, "Couldn’t create the voice channel. Please bug kageru about this.")
|
||||
log.Printf("Failed to create voice channel, %s", err)
|
||||
return
|
||||
}
|
||||
tempChannels = append(tempChannels, channel)
|
||||
err = session.GuildMemberMove(config.ServerID, message.Author.ID, channel.ID)
|
||||
if err != nil {
|
||||
log.Printf("Couldn’t move user %s: %s", userToString(message.Author), err)
|
||||
}
|
||||
session.ChannelMessageSend(message.ChannelID, "haaaai~")
|
||||
log.Printf("Created channel %s", channel.ID)
|
||||
}
|
||||
|
||||
func checkAndDeleteUnusedChannels(session *discordgo.Session) {
|
||||
for true {
|
||||
time.Sleep(30 * time.Second)
|
||||
server, err := getServer()
|
||||
if err == nil {
|
||||
for i, channel := range tempChannels {
|
||||
if channelIsEmpty(channel.ID, server.VoiceStates) {
|
||||
session.ChannelDelete(channel.ID)
|
||||
tempChannels = remove(tempChannels, i)
|
||||
log.Printf("Deleted channel %s", channel.ID)
|
||||
log.Printf("Tempchannels: %d", len(tempChannels))
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.Printf("Could not retrieve voice state from API, %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func channelIsEmpty(channelID string, voiceStates []*discordgo.VoiceState) bool {
|
||||
for _, state := range voiceStates {
|
||||
if channelID == state.ChannelID {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"fmt"
|
||||
"github.com/bwmarrin/discordgo"
|
||||
)
|
||||
|
||||
func getWelcomeEmbed() *discordgo.MessageEmbed {
|
||||
|
|
Loading…
Reference in New Issue