package main import ( "flag" "fmt" "log" "os" "os/signal" "syscall" "strings" "regexp" "context" "reflect" "github.com/bwmarrin/discordgo" "github.com/wader/goutubedl" "mvdan.cc/xurls/v2" // Peak lazy ) /* // Variables used for command line parameters var ( commands = []*discordgo.ApplicationCommand { { Name: "ping", Description: "Hopefully replies with pong or else I'll be sad.", }, } commandHandlers = map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate) { "ping": func(s *discordgo.Session, i *discordgo.InteractionCreate) { s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ Type: discordgo.InteractionResponseChannelMessageWithSource, Data: &discordgo.InteractionResponseData{ Content: "Hey there! Congratulations, you just executed your first slash command", }, }) }, } ) */ // Bot params var ( GuildID = flag.String("guild", "", "Test guild ID. If not passed - bot registers commands globally") BotToken = flag.String("token", "", "Bot access token") RemoveCommands = flag.Bool("rmcmd", true, "Remove all commands after shutdowning or not") ) // Lazyinator 9001 var ( s *discordgo.Session err error ) func init() { flag.Parse() s, err = discordgo.New("Bot " + *BotToken) if err != nil { fmt.Println("error creating Discord session,", err) return } /* s.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) { if h, ok := commandHandlers[i.ApplicationCommandData().Name]; ok { h(s, i) } }) */ } func main() { s.AddHandler(func(s *discordgo.Session, r *discordgo.Ready) { log.Printf("Logged in as: %v#%v\n", s.State.User.Username, s.State.User.Discriminator) }) // Register the messageCreate func as a callback for MessageCreate events. s.AddHandler(messageCreate) // In this example, we only care about receiving message events. s.Identify.Intents = discordgo.IntentsGuildMessages // Open a websocket connection to Discord and begin listening. err = s.Open() if err != nil { fmt.Println("error opening connection,", err) return } /* fmt.Println("Adding commands...") registeredCommands := make([]*discordgo.ApplicationCommand, len(commands)) for i, v := range commands { cmd, err := s.ApplicationCommandCreate(s.State.User.ID, *GuildID, v) if err != nil { //log.Panicf("Cannot create '%v' command: %v", v.Name, err) fmt.Println("Bad") panic(1) } registeredCommands[i] = cmd } */ // Just incase defer s.Close() // Wait here until CTRL-C or other term signal is received. log.Println("Bot is starting. 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. s.Close() } // This function will be called (due to AddHandler above) every time a new // message is created on any channel that the authenticated bot has access to. func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) { // Ignore all messages created by the bot itself // This isn't required in this specific example but it's a good practice. if m.Author.ID == s.State.User.ID { return } /* // If the message is "ping" reply with "Pong!" if m.Content == "ping" { s.ChannelMessageSend(m.ChannelID, "Pong!") } // If the message is "pong" reply with "Ping!" if m.Content == "pong" { s.ChannelMessageSend(m.ChannelID, "Ping!") } */ log.Printf("[%s] %s#%s: %s", m.ID, m.Author.Username, m.Author.Discriminator, m.Content) rxStrict := xurls.Strict() urls := rxStrict.FindAllString(m.Content, -1) if len(urls) > 0 { message := discordgo.MessageSend { Content: "Woah there partner! I detect some services that don't embed very well in Discord. Let me help you with that!\n", Reference: m.Reference(), Files: []*discordgo.File{}, } log.Println("URLs detected!") for _, url := range urls { if output, _ := regexp.MatchString("http.*twitter", url); output { log.Println("Cringe twitter detected.") goutubedl.Path = "yt-dlp" result, err := goutubedl.New(context.Background(), url, goutubedl.Options{}) if err != nil { s.ChannelMessageSend(m.ChannelID, err.Error()) continue } message.Content = fmt.Sprintf("%s \"%s\"\n", message.Content, strings.Trim(regexp.MustCompile("https://t.co/.*").ReplaceAllString(result.Info.Description, ""), " ")) // Still ugly var choice goutubedl.Format for i := len(result.Formats())-1; i >= 0; i-- { size := result.Formats()[i].FilesizeApprox if size < 8*1024*1024 { choice = result.Formats()[i] log.Printf("Choice: %s | Size: %fM\n", choice.FormatID, size/1024/1024) break } } downloadResult, err := result.Download(context.Background(), choice.FormatID) if err != nil { s.ChannelMessageSend(m.ChannelID, err.Error()) continue } fmt.Println(reflect.TypeOf(message.Files)) /* message.Files = []*discordgo.File{&discordgo.File { Name: fmt.Sprintf("%s.%s", result.Info.ID, choice.Ext), ContentType: "text/plain", // This is of course not true, but Discord doesn't give a shit Reader: downloadResult, }} */ message.Files = append(message.Files, &discordgo.File { Name: fmt.Sprintf("%s.%s", result.Info.ID, choice.Ext), ContentType: "text/plain", // This is of course not true, but Discord doesn't give a shit Reader: downloadResult, }) defer downloadResult.Close() } } if message, err := s.ChannelMessageSendComplex(m.ChannelID, &message); err != nil { log.Println(message) log.Println(err) } else { log.Printf("Successfully responded to %s", m.ID) } } }