commit 9c3da7407838bf3a53f0110c8036a549534d7389 Author: Lukas Höppner Date: Tue May 19 16:05:17 2026 +0200 initial commit diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..e4d1bef --- /dev/null +++ b/.env.example @@ -0,0 +1,4 @@ +# Discord Bot Token +# Zu finden unter https://discord.com/developers/applications → Bot → Token +DISCORD_TOKEN=dein_token_hier +TARGET_CHANNEL_NAME=mein-channel \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..d3f4df4 --- /dev/null +++ b/go.mod @@ -0,0 +1,12 @@ +module discord-thread-bot + +go 1.23.0 + +require github.com/bwmarrin/discordgo v0.29.0 + +require ( + github.com/gorilla/websocket v1.5.3 // indirect + github.com/joho/godotenv v1.5.1 // indirect + golang.org/x/crypto v0.38.0 // indirect + golang.org/x/sys v0.33.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..cc90639 --- /dev/null +++ b/go.sum @@ -0,0 +1,17 @@ +github.com/bwmarrin/discordgo v0.29.0 h1:FmWeXFaKUwrcL3Cx65c20bTRW+vOb6k8AnaP+EgjDno= +github.com/bwmarrin/discordgo v0.29.0/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= +golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/main.go b/main.go new file mode 100644 index 0000000..160e5e3 --- /dev/null +++ b/main.go @@ -0,0 +1,85 @@ +package main + +import ( + "fmt" + "log" + "os" + "os/signal" + "syscall" + + "github.com/bwmarrin/discordgo" + "github.com/joho/godotenv" +) + +func main() { + if err := godotenv.Load(); err != nil && !os.IsNotExist(err) { + log.Println("Warnung: .env-Datei konnte nicht geladen werden:", err) + } + + token := os.Getenv("DISCORD_TOKEN") + if token == "" { + log.Fatal("Umgebungsvariable DISCORD_TOKEN ist nicht gesetzt") + } + + dg, err := discordgo.New("Bot " + token) + if err != nil { + log.Fatal("Fehler beim Erstellen der Discord-Session:", err) + } + + targetChannelName := os.Getenv("TARGET_CHANNEL_NAME") + if targetChannelName == "" { + targetChannelName = "threads-und-diskussionen" + } + + dg.AddHandler(func(s *discordgo.Session, t *discordgo.ThreadCreate) { + onThreadCreate(s, t, targetChannelName) + }) + + // GUILDS-Intent enthält THREAD_CREATE-Events + dg.Identify.Intents = discordgo.IntentsGuilds + + if err = dg.Open(); err != nil { + log.Fatal("Fehler beim Öffnen der Verbindung:", err) + } + defer dg.Close() + + fmt.Println("Bot läuft. CTRL+C zum Beenden.") + + sc := make(chan os.Signal, 1) + signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt) + <-sc +} + +func onThreadCreate(s *discordgo.Session, t *discordgo.ThreadCreate, targetChannelName string) { + // Neu erstellte Threads haben NewlyCreated == true. + // Ohne diese Prüfung feuert das Event auch beim Bot-Start für bestehende Threads. + if !t.NewlyCreated { + return + } + + channels, err := s.GuildChannels(t.GuildID) + if err != nil { + log.Println("Fehler beim Abrufen der Channels:", err) + return + } + + var targetChannelID string + for _, ch := range channels { + if ch.Name == targetChannelName { + targetChannelID = ch.ID + break + } + } + + if targetChannelID == "" { + log.Printf("Channel #%s nicht gefunden\n", targetChannelName) + return + } + + threadLink := fmt.Sprintf("https://discord.com/channels/%s/%s", t.GuildID, t.ID) + message := fmt.Sprintf("Neuer Thread: **%s**\n%s", t.Name, threadLink) + + if _, err = s.ChannelMessageSend(targetChannelID, message); err != nil { + log.Println("Fehler beim Senden der Nachricht:", err) + } +}