bb/cmd/bb/main.go

174 lines
3.5 KiB
Go

package main
import (
"flag"
"fmt"
//"log"
"math/rand"
"os"
"os/signal"
"strings"
"syscall"
"git.kill0.net/chill9/beepboop/command"
"git.kill0.net/chill9/beepboop/lib"
"github.com/bwmarrin/discordgo"
log "github.com/sirupsen/logrus"
"github.com/spf13/pflag"
"github.com/spf13/viper"
)
var (
Token string
defaultReactions []string = []string{"👍", "🌶️", "🤣", "😂", "🍆", "🍑", "❤️", "💦", "😍", "💩", "🔥", "🍒", "🎉", "🥳", "🎊"}
C command.Config
handlers []command.CommandHandler = []command.CommandHandler{
command.NewCoinHandler(),
command.NewPingHandler(),
command.NewRollHandler(),
command.NewRouletteHandler(),
command.NewTimeHandler(),
command.NewVersionHandler("version"),
command.NewWeatherHandler(),
}
)
func main() {
var (
err error
)
flag.Bool("debug", false, "enable debug logging")
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
pflag.Parse()
viper.BindPFlags(pflag.CommandLine)
if viper.GetBool("debug") {
log.SetLevel(log.DebugLevel)
}
lib.SeedMathRand()
viper.SetDefault("handler.reaction.emojis", defaultReactions)
viper.SetEnvPrefix("BEEPBOOP")
viper.AutomaticEnv()
viper.SetConfigName("config")
viper.SetConfigType("toml")
viper.AddConfigPath(".")
err = viper.ReadInConfig()
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
log.Fatalf("fatal error config file: %v", err)
}
Token, ok := viper.Get("discord_token").(string)
err = viper.Unmarshal(&C)
if err != nil {
log.Fatalf("unable to decode into struct: %v", err)
}
if Token == "" {
log.Fatalf("Discord token is not set")
}
if !ok {
log.Fatalf("Invalid type assertion")
}
dg, err := discordgo.New(fmt.Sprintf("Bot %s", Token))
if err != nil {
log.Fatalf("error creating Discord session: %v\n", err)
}
for _, h := range handlers {
h.SetConfig(C)
dg.AddHandler(h.Handle)
}
dg.AddHandler(reactionHandler)
dg.AddHandler(praiseHandler)
dg.Identify.Intents = discordgo.IntentsGuildMessages
err = dg.Open()
if err != nil {
log.Fatalf("error opening connection: %v\n", err)
}
log.Info("The bot is now running. Press CTRL-C to exit.")
defer dg.Close()
sc := make(chan os.Signal, 1)
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill)
<-sc
log.Info("Shutting down")
}
func praiseHandler(s *discordgo.Session, m *discordgo.MessageCreate) {
if m.Author.ID == s.State.User.ID {
return
}
if strings.Contains(m.Content, "good bot") {
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("<@%s> Thank you, daddy.", m.Author.ID))
}
}
func reactionHandler(s *discordgo.Session, m *discordgo.MessageCreate) {
if m.Author.ID == s.State.User.ID {
return
}
emojis := C.Handler.Reaction.Emojis
channels := C.Handler.Reaction.Channels
if len(emojis) == 0 {
log.Warning("emoji list is empty")
return
}
channel, err := s.Channel(m.ChannelID)
if err != nil {
log.Fatalf("unable to get channel name: %v", err)
}
if len(channels) > 0 && !contains(channels, channel.Name) {
return
}
for _, a := range m.Attachments {
if strings.HasPrefix(a.ContentType, "image/") {
for i := 0; i < command.RandInt(1, len(emojis)); i++ {
r := emojis[rand.Intn(len(emojis))]
s.MessageReactionAdd(m.ChannelID, m.ID, r)
}
}
}
for range m.Embeds {
for i := 0; i < command.RandInt(1, len(emojis)); i++ {
r := emojis[rand.Intn(len(emojis))]
s.MessageReactionAdd(m.ChannelID, m.ID, r)
}
}
}
func contains[T comparable](s []T, v T) bool {
for _, x := range s {
if x == v {
return true
}
}
return false
}