diff --git a/bs.patch b/bs.patch
deleted file mode 100644
index 03758e675f4195572cf7ad67501dd7a40e16be93..0000000000000000000000000000000000000000
--- a/bs.patch
+++ /dev/null
@@ -1,190 +0,0 @@
-diff --git a/.gitignore b/.gitignore
-index 66c0676..584bf4c 100644
---- a/.gitignore
-+++ b/.gitignore
-@@ -1,3 +1,4 @@
- go-voice-bot
- go-voice-bot.*
--.idea/
-\ No newline at end of file
-+.idea/
-+server.conf
-\ No newline at end of file
-diff --git a/config.go b/config.go
-new file mode 100644
-index 0000000..40ca7c1
---- /dev/null
-+++ b/config.go
-@@ -0,0 +1,53 @@
-+package main
-+
-+import (
-+	"flag"
-+	"git.randomchars.net/freenitori/log"
-+	"github.com/BurntSushi/toml"
-+	"os"
-+)
-+
-+var config configPayload
-+var configPath string
-+var defaultConfig = configPayload{
-+	Token:     "TOKEN",
-+	ChannelID: []string{},
-+	Prefix:    "!",
-+}
-+
-+type configPayload struct {
-+	Token     string
-+	ChannelID []string
-+	Prefix    string
-+}
-+
-+func init() {
-+	flag.StringVar(&configPath, "-t", "server.conf", "Specify configuration file location.")
-+}
-+
-+func parse() {
-+	if _, err := toml.DecodeFile(configPath, &config); err != nil {
-+		if os.IsNotExist(err) {
-+			var file *os.File
-+			if file, err = os.Create(configPath); err != nil {
-+				log.Fatalf("Error while creating configuration file, %s", err)
-+				os.Exit(1)
-+			}
-+			if err = toml.NewEncoder(file).Encode(defaultConfig); err != nil {
-+				log.Fatalf("Error while encoding default configuration, %s", err)
-+				os.Exit(1)
-+			}
-+			log.Warnf("Default configuration generated at %s, edit before next startup.", configPath)
-+			os.Exit(1)
-+		}
-+		log.Fatalf("Error while decoding configuration file, %s", err)
-+		os.Exit(1)
-+	} else {
-+		log.Infof("Loaded config at %s.", configPath)
-+	}
-+
-+	allowedChannels = make(map[string]bool)
-+	for _, id := range config.ChannelID {
-+		allowedChannels[id] = true
-+	}
-+}
-diff --git a/go.mod b/go.mod
-index 4b448f1..3c02d0d 100644
---- a/go.mod
-+++ b/go.mod
-@@ -6,6 +6,7 @@ require (
- 	git.randomchars.net/freenitori/embedutil v1.0.2
- 	git.randomchars.net/freenitori/log v1.0.0
- 	git.randomchars.net/freenitori/multiplexer v1.0.12
-+	github.com/BurntSushi/toml v0.3.1
- 	github.com/bwmarrin/discordgo v0.23.2
- 	github.com/sirupsen/logrus v1.8.1
- )
-diff --git a/go.sum b/go.sum
-index 367e548..ede86a0 100644
---- a/go.sum
-+++ b/go.sum
-@@ -10,6 +10,8 @@ git.randomchars.net/freenitori/log v1.0.0 h1:hU99jGk940I1O5OcaTfnXOpN8ozXiarxhu6
- git.randomchars.net/freenitori/log v1.0.0/go.mod h1:YZFRZgVWDIrbyDGHyDeRlIRWeq0DXamXONxIt12eq2Q=
- git.randomchars.net/freenitori/multiplexer v1.0.12 h1:XsMMSeeaeBtavlsMl7M6ZrW00wa2+zsx/w5gYWR5Qh0=
- git.randomchars.net/freenitori/multiplexer v1.0.12/go.mod h1:Bx9vu2RXDtBrsKBslrhrc8v3IJl5Dna7I/rsHF586w0=
-+github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
-+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
- 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/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-diff --git a/handler.go b/handler.go
-index 7bdb866..0efca9b 100644
---- a/handler.go
-+++ b/handler.go
-@@ -3,23 +3,54 @@ package main
- import (
- 	"git.randomchars.net/freenitori/log"
- 	"git.randomchars.net/freenitori/multiplexer"
-+	"github.com/bwmarrin/discordgo"
- )
- 
- func init() {
- 	m.VoiceStateUpdate = append(m.VoiceStateUpdate, handleVoiceUpdate)
- }
- 
-+var allowedChannels map[string]bool
-+
- func handleVoiceUpdate(context *multiplexer.Context) {
- 
- 	if context.Channel == nil {
- 		return
- 	}
- 
--	log.Info(context.Channel.ID)
-+	if !allowedChannels[context.Channel.ID] {
-+		return
-+	}
-+
-+	var event *discordgo.VoiceStateUpdate
-+	if e, ok := context.Event.(*discordgo.VoiceStateUpdate); !ok {
-+		return
-+	} else {
-+		event = e
-+	}
-+
-+	var member *discordgo.Member
-+	if u, err := context.Session.State.Member(event.GuildID, event.UserID); err != nil {
-+		if u, err = context.Session.GuildMember(event.GuildID, event.UserID); err != nil {
-+			log.Errorf("Error getting member %s (%s), %s", event.UserID, event.GuildID, err)
-+			return
-+		} else {
-+			member = u
-+			_ = context.Session.State.MemberAdd(u)
-+		}
-+	} else {
-+		member = u
-+	}
-+
-+	if member == nil {
-+		return
-+	}
- 
--	// TODO: unhardcode
--	//if context.Channel.ID == "783703981620723762" {
--	//	log.Infof("%s joined click me channel", context.Member.User.Username)
--	//}
--	
--}
-\ No newline at end of file
-+	log.Infof("%s#%s (%s) has joined the designated channel #%s (%s).",
-+		member.User.Username,
-+		member.User.Discriminator,
-+		member.User.ID,
-+		context.Channel.Name,
-+		context.Channel.ID,
-+		)
-+}
-diff --git a/main.go b/main.go
-index 714ace3..abf5657 100644
---- a/main.go
-+++ b/main.go
-@@ -18,10 +18,7 @@ var system = multiplexer.NewCategory("System", "System-related utilities.")
- 
- func main() {
- 	flag.Parse()
--	if len(flag.Args()) != 1 {
--		fmt.Println("expecting 1 argument: token")
--		os.Exit(1)
--	}
-+	parse()
- 
- 	// Set discordgo log handler
- 	discordgo.Logger = func(msgL, _ int, format string, a ...interface{}) {
-@@ -51,8 +48,8 @@ func main() {
- 	} else {
- 		session = s
- 	}
--	session.UserAgent = "DiscordBot (ticket-bot)"
--	session.Token = "Bot " + flag.Arg(0)
-+	session.UserAgent = "DiscordBot (voice-bot)"
-+	session.Token = "Bot " + config.Token
- 	session.ShouldReconnectOnError = true
- 	session.Identify.Intents = discordgo.IntentsAllWithoutPrivileged
-