149 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			149 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package bot
 | |
| 
 | |
| import (
 | |
| 	"flag"
 | |
| 	"fmt"
 | |
| 	"os"
 | |
| 	"os/signal"
 | |
| 	"syscall"
 | |
| 
 | |
| 	"git.kill0.net/chill9/beepboop/lib"
 | |
| 	"github.com/bwmarrin/discordgo"
 | |
| 	log "github.com/sirupsen/logrus"
 | |
| 	"github.com/spf13/pflag"
 | |
| 	"github.com/spf13/viper"
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	C Config
 | |
| 
 | |
| 	handlers []MessageCreateHandler = []MessageCreateHandler{
 | |
| 		NewReactionHandler(),
 | |
| 	}
 | |
| )
 | |
| 
 | |
| type Bot struct {
 | |
| 	Session *discordgo.Session
 | |
| 	Config  Config
 | |
| }
 | |
| 
 | |
| func NewBot(s *discordgo.Session, config Config) *Bot {
 | |
| 	return &Bot{Session: s, Config: config}
 | |
| }
 | |
| 
 | |
| func (b *Bot) RegisterCommands() {
 | |
| 	AddCommand(&Command{
 | |
| 		Name: "coin",
 | |
| 		Func: b.CoinCommand(),
 | |
| 	})
 | |
| 	AddCommand(&Command{
 | |
| 		Name:  "deal",
 | |
| 		Func:  b.DealCommand(),
 | |
| 		NArgs: 1,
 | |
| 	})
 | |
| 	AddCommand(&Command{
 | |
| 		Name: "ping",
 | |
| 		Func: b.PingCommand(),
 | |
| 	})
 | |
| 	AddCommand(&Command{
 | |
| 		Name:  "roll",
 | |
| 		Func:  b.RollCommand(),
 | |
| 		NArgs: 1,
 | |
| 	})
 | |
| 	AddCommand(&Command{
 | |
| 		Name:  "time",
 | |
| 		Func:  b.TimeCommand(),
 | |
| 		NArgs: 1,
 | |
| 	})
 | |
| 	AddCommand(&Command{
 | |
| 		Name: "version",
 | |
| 		Func: b.VersionCommand(),
 | |
| 	})
 | |
| 	AddCommand(&Command{
 | |
| 		Name:  "weather",
 | |
| 		Func:  b.WeatherCommand(),
 | |
| 		NArgs: 1,
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func Run() error {
 | |
| 	setupConfig()
 | |
| 
 | |
| 	lib.SeedMathRand()
 | |
| 
 | |
| 	if C.DiscordToken == "" {
 | |
| 		log.Fatalf("Discord token is not set")
 | |
| 	}
 | |
| 
 | |
| 	dg, err := discordgo.New(fmt.Sprintf("Bot %s", C.DiscordToken))
 | |
| 	if err != nil {
 | |
| 		log.Fatalf("error creating Discord session: %v\n", err)
 | |
| 	}
 | |
| 
 | |
| 	for _, h := range handlers {
 | |
| 		h.SetConfig(C)
 | |
| 		dg.AddHandler(h.Handle)
 | |
| 	}
 | |
| 
 | |
| 	b := NewBot(dg, C)
 | |
| 	b.RegisterCommands()
 | |
| 
 | |
| 	dg.AddHandler(NewCommandHandler(b))
 | |
| 
 | |
| 	dg.Identify.Intents = discordgo.IntentsGuildMessages | discordgo.IntentsDirectMessages
 | |
| 
 | |
| 	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")
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func setupConfig() {
 | |
| 	var err error
 | |
| 
 | |
| 	C = NewConfig()
 | |
| 
 | |
| 	flag.Bool("debug", false, "enable debug logging")
 | |
| 	pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
 | |
| 	pflag.Parse()
 | |
| 	viper.BindPFlags(pflag.CommandLine)
 | |
| 
 | |
| 	viper.SetEnvPrefix("BEEPBOOP")
 | |
| 	viper.AutomaticEnv()
 | |
| 
 | |
| 	viper.SetConfigName("config")
 | |
| 	viper.SetConfigType("toml")
 | |
| 	viper.AddConfigPath(".")
 | |
| 
 | |
| 	err = viper.ReadInConfig()
 | |
| 
 | |
| 	viper.BindEnv("DEBUG")
 | |
| 	viper.BindEnv("DISCORD_TOKEN")
 | |
| 	viper.BindEnv("OPEN_WEATHER_MAP_TOKEN")
 | |
| 
 | |
| 	if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
 | |
| 		log.Fatalf("fatal error config file: %v", err)
 | |
| 	}
 | |
| 
 | |
| 	err = viper.Unmarshal(&C)
 | |
| 	if err != nil {
 | |
| 		log.Fatalf("unable to decode into struct: %v", err)
 | |
| 	}
 | |
| 
 | |
| 	if viper.GetBool("debug") {
 | |
| 		log.SetLevel(log.DebugLevel)
 | |
| 	}
 | |
| }
 |