package main import ( "fmt" "os" "strings" "github.com/bwmarrin/discordgo" ) var ( Token string ) func init() { Token = os.Getenv("DISCORD_BOT_TOKEN") if Token == "" { fmt.Println("No token provided. Please set DISCORD_BOT_TOKEN environment variable.") os.Exit(1) } } func main() { dg, err := discordgo.New("Bot " + Token) if err != nil { fmt.Println("Error creating Discord session:", err) return } dg.AddHandler(ready) dg.AddHandler(interactionCreate) dg.Identify.Intents = discordgo.IntentsGuilds | discordgo.IntentsGuildMessages err = dg.Open() if err != nil { fmt.Println("Error opening connection:", err) return } fmt.Println("Bot is now running. Press CTRL+C to exit.") select {} } func ready(s *discordgo.Session, event *discordgo.Ready) { s.UpdateGameStatus(0, "Listing webhooks") command := &discordgo.ApplicationCommand{ Name: "webhooks", Description: "List all webhooks in the server", } _, err := s.ApplicationCommandCreate(s.State.User.ID, "", command) if err != nil { fmt.Printf("Cannot create slash command: %v\n", err) return } fmt.Println("Slash command /webhooks created successfully") } func interactionCreate(s *discordgo.Session, i *discordgo.InteractionCreate) { if i.Type == discordgo.InteractionApplicationCommand { switch i.ApplicationCommandData().Name { case "webhooks": handleWebhooksCommand(s, i) } } } func handleWebhooksCommand(s *discordgo.Session, i *discordgo.InteractionCreate) { err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ Type: discordgo.InteractionResponseChannelMessageWithSource, Data: &discordgo.InteractionResponseData{ Content: "Fetching webhooks...", }, }) if err != nil { fmt.Printf("Error responding to interaction: %v\n", err) return } go fetchAndSendWebhookResponses(s, i) } func fetchAndSendWebhookResponses(s *discordgo.Session, i *discordgo.InteractionCreate) { webhooks, channelNames, channelCategories, err := getAllWebhooks(s, i.GuildID) if err != nil { fmt.Printf("Error retrieving webhooks: %v\n", err) editMessage := fmt.Sprintf("Error retrieving webhooks: %v", err) s.InteractionResponseEdit(i.Interaction, &discordgo.WebhookEdit{ Content: &editMessage, }) return } if len(webhooks) == 0 { fmt.Println("No webhooks found in this server.") editMessage := "No webhooks found in this server." s.InteractionResponseEdit(i.Interaction, &discordgo.WebhookEdit{ Content: &editMessage, }) return } webhooksByCategory := make(map[string][]*discordgo.Webhook) for _, webhook := range webhooks { categoryName := channelCategories[webhook.ChannelID] webhooksByCategory[categoryName] = append(webhooksByCategory[categoryName], webhook) } for categoryName, webhooks := range webhooksByCategory { var response strings.Builder response.WriteString(fmt.Sprintf("**Category: %s**\n", categoryName)) for _, webhook := range webhooks { channelName := channelNames[webhook.ChannelID] link := fmt.Sprintf("https://discord.com/api/webhooks/%s/%s", webhook.ID, webhook.Token) str := fmt.Sprintf("Channel: %s (<#%s>), Name: %s, Webhook: %s\n",channelName,webhook.ChannelID, webhook.Name, link) response.WriteString(str) } finalResponse := response.String() s.FollowupMessageCreate(i.Interaction, true, &discordgo.WebhookParams{ Content: finalResponse, }) } } func getAllWebhooks(s *discordgo.Session, serverID string) ([]*discordgo.Webhook, map[string]string, map[string]string, error) { channels, err := s.GuildChannels(serverID) if err != nil { return nil, nil, nil, fmt.Errorf("could not fetch channels: %v", err) } channelNames := make(map[string]string) channelCategories := make(map[string]string) categoryNames := make(map[string]string) var allWebhooks []*discordgo.Webhook for _, channel := range channels { channelNames[channel.ID] = channel.Name if channel.Type == discordgo.ChannelTypeGuildCategory { categoryNames[channel.ID] = channel.Name } } for _, channel := range channels { if channel.ParentID != "" { channelCategories[channel.ID] = categoryNames[channel.ParentID] } else { channelCategories[channel.ID] = "Uncategorized" } if channel.Type != discordgo.ChannelTypeGuildText { continue } webhooks, err := s.ChannelWebhooks(channel.ID) if err != nil { if restErr, ok := err.(*discordgo.RESTError); ok && restErr.Message != nil && restErr.Message.Code == discordgo.ErrCodeUnknownChannel { fmt.Printf("Channel %s does not exist or is not accessible\n", channel.ID) } else { fmt.Printf("Error retrieving webhooks for channel %s: %v\n", channel.ID, err) } continue } allWebhooks = append(allWebhooks, webhooks...) } return allWebhooks, channelNames, channelCategories, nil }