2022-07-01 02:28:20 -04:00
package main
import (
2022-07-01 02:30:35 -04:00
"flag"
"fmt"
2022-07-01 03:48:26 -04:00
"log"
2022-07-01 02:30:35 -04:00
"os"
"os/signal"
"syscall"
2022-07-01 02:28:20 -04:00
"strings"
"regexp"
"context"
2022-07-01 03:48:26 -04:00
"reflect"
2022-07-01 02:28:20 -04:00
2022-07-01 02:30:35 -04:00
"github.com/bwmarrin/discordgo"
2022-07-01 02:28:20 -04:00
"github.com/wader/goutubedl"
2022-07-01 03:48:26 -04:00
"mvdan.cc/xurls/v2" // Peak lazy
2022-07-01 02:28:20 -04:00
)
/ *
// Variables used for command line parameters
var (
commands = [ ] * discordgo . ApplicationCommand {
2022-07-01 02:30:35 -04:00
{
Name : "ping" ,
Description : "Hopefully replies with pong or else I'll be sad." ,
} ,
2022-07-01 02:28:20 -04:00
}
commandHandlers = map [ string ] func ( s * discordgo . Session , i * discordgo . InteractionCreate ) {
2022-07-01 02:30:35 -04:00
"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" ,
} ,
} )
} ,
2022-07-01 02:28:20 -04:00
}
)
* /
// Bot params
var (
2022-07-01 02:30:35 -04:00
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" )
2022-07-01 02:28:20 -04:00
)
// Lazyinator 9001
var (
s * discordgo . Session
err error
)
func init ( ) {
2022-07-01 02:30:35 -04:00
flag . Parse ( )
2022-07-01 02:28:20 -04:00
s , err = discordgo . New ( "Bot " + * BotToken )
if err != nil {
2022-07-01 02:30:35 -04:00
fmt . Println ( "error creating Discord session," , err )
return
}
2022-07-01 02:28:20 -04:00
/ *
s . AddHandler ( func ( s * discordgo . Session , i * discordgo . InteractionCreate ) {
2022-07-01 02:30:35 -04:00
if h , ok := commandHandlers [ i . ApplicationCommandData ( ) . Name ] ; ok {
h ( s , i )
}
} )
2022-07-01 02:28:20 -04:00
* /
}
func main ( ) {
2022-07-01 02:30:35 -04:00
s . AddHandler ( func ( s * discordgo . Session , r * discordgo . Ready ) {
2022-07-01 03:48:26 -04:00
log . Printf ( "Logged in as: %v#%v\n" , s . State . User . Username , s . State . User . Discriminator )
2022-07-01 02:30:35 -04:00
} )
2022-07-01 02:28:20 -04:00
2022-07-01 02:30:35 -04:00
// Register the messageCreate func as a callback for MessageCreate events.
s . AddHandler ( messageCreate )
2022-07-01 02:28:20 -04:00
2022-07-01 02:30:35 -04:00
// In this example, we only care about receiving message events.
s . Identify . Intents = discordgo . IntentsGuildMessages
2022-07-01 02:28:20 -04:00
2022-07-01 02:30:35 -04:00
// Open a websocket connection to Discord and begin listening.
err = s . Open ( )
if err != nil {
fmt . Println ( "error opening connection," , err )
return
}
2022-07-01 02:28:20 -04:00
/ *
fmt . Println ( "Adding commands..." )
2022-07-01 02:30:35 -04:00
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)
2022-07-01 02:28:20 -04:00
fmt . Println ( "Bad" )
panic ( 1 )
2022-07-01 02:30:35 -04:00
}
registeredCommands [ i ] = cmd
}
2022-07-01 02:28:20 -04:00
* /
// Just incase
defer s . Close ( )
2022-07-01 02:30:35 -04:00
// Wait here until CTRL-C or other term signal is received.
2022-07-01 03:48:26 -04:00
log . Println ( "Bot is starting. Press CTRL-C to exit." )
2022-07-01 02:30:35 -04:00
sc := make ( chan os . Signal , 1 )
signal . Notify ( sc , syscall . SIGINT , syscall . SIGTERM , os . Interrupt , os . Kill )
<- sc
2022-07-01 02:28:20 -04:00
2022-07-01 02:30:35 -04:00
// Cleanly close down the Discord session.
s . Close ( )
2022-07-01 02:28:20 -04:00
}
// 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 ) {
2022-07-01 02:30:35 -04:00
// 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
}
2022-07-01 02:28:20 -04:00
/ *
// If the message is "ping" reply with "Pong!"
2022-07-01 02:30:35 -04:00
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!" )
}
2022-07-01 02:28:20 -04:00
* /
2022-07-01 03:48:26 -04:00
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 {
2022-07-01 02:28:20 -04:00
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 ( ) ,
2022-07-01 03:48:26 -04:00
Files : [ ] * discordgo . File { } ,
2022-07-01 02:28:20 -04:00
}
2022-07-01 03:48:26 -04:00
log . Println ( "URLs detected!" )
2022-07-01 02:28:20 -04:00
2022-07-01 03:48:26 -04:00
for _ , url := range urls {
2022-07-01 02:28:20 -04:00
if output , _ := regexp . MatchString ( "http.*twitter" , url ) ; output {
2022-07-01 03:48:26 -04:00
log . Println ( "Cringe twitter detected." )
2022-07-01 02:28:20 -04:00
goutubedl . Path = "yt-dlp"
result , err := goutubedl . New ( context . Background ( ) , url , goutubedl . Options { } )
if err != nil {
s . ChannelMessageSend ( m . ChannelID , err . Error ( ) )
2022-07-01 03:48:26 -04:00
continue
2022-07-01 02:28:20 -04:00
}
2022-07-01 03:48:26 -04:00
message . Content = fmt . Sprintf ( "%s \"%s\"\n" , message . Content , strings . Trim ( regexp . MustCompile ( "https://t.co/.*" ) . ReplaceAllString ( result . Info . Description , "" ) , " " ) ) // Still ugly
2022-07-01 02:28:20 -04:00
2022-07-01 03:48:26 -04:00
var choice goutubedl . Format
2022-07-01 02:28:20 -04:00
for i := len ( result . Formats ( ) ) - 1 ; i >= 0 ; i -- {
size := result . Formats ( ) [ i ] . FilesizeApprox
if size < 8 * 1024 * 1024 {
2022-07-01 03:48:26 -04:00
choice = result . Formats ( ) [ i ]
log . Printf ( "Choice: %s | Size: %fM\n" , choice . FormatID , size / 1024 / 1024 )
2022-07-01 02:28:20 -04:00
break
}
}
2022-07-01 03:48:26 -04:00
downloadResult , err := result . Download ( context . Background ( ) , choice . FormatID )
2022-07-01 02:28:20 -04:00
if err != nil {
s . ChannelMessageSend ( m . ChannelID , err . Error ( ) )
2022-07-01 03:48:26 -04:00
continue
2022-07-01 02:28:20 -04:00
}
2022-07-01 03:48:26 -04:00
fmt . Println ( reflect . TypeOf ( message . Files ) )
2022-07-01 02:28:20 -04:00
2022-07-01 03:48:26 -04:00
/ *
2022-07-01 02:28:20 -04:00
message . Files = [ ] * discordgo . File { & discordgo . File {
2022-07-01 03:48:26 -04:00
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
2022-07-01 02:28:20 -04:00
Reader : downloadResult ,
} }
2022-07-01 03:48:26 -04:00
* /
2022-07-01 02:28:20 -04:00
2022-07-01 03:48:26 -04:00
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 ,
} )
2022-07-01 02:28:20 -04:00
2022-07-01 03:48:26 -04:00
defer downloadResult . Close ( )
2022-07-01 02:28:20 -04:00
}
}
2022-07-01 03:48:26 -04:00
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 )
}
2022-07-01 02:28:20 -04:00
}
}