diff --git a/.env_template b/.env_template new file mode 100644 index 0000000..82fb1e4 --- /dev/null +++ b/.env_template @@ -0,0 +1,7 @@ +NAME=bo +CONFIG_PATH=./config +LOKI_URL="http://localhost:3100/loki/api/v1/push" +OTEL_EXPORTER_OTLP_INSECURE="true" +OTEL_RESOURCE_ATTRIBUTES_BOBY="service.name=bo,service.namespace=bo,deployment.environment=prod" +OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317" +OTEL_EXPORTER_OTLP_PROTOCOL=grpc \ No newline at end of file diff --git a/.gitignore b/.gitignore index e5ef195..e7b23bd 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ src/main/config/** .devcontainer/devcontainer.json .vscode/launch.json src/main/logging.log +.env diff --git a/src/command/admin.go b/src/command/admin.go index 13d0d72..b2df0e3 100644 --- a/src/command/admin.go +++ b/src/command/admin.go @@ -1,5 +1,15 @@ package command +import ( + "encoding/json" + "io" +) + +// Config for admin commands. +type AdminConfig struct { + Enabled bool // Whether admin commands are enabled. +} + // ImAdminTrigger is a trigger to use for an ImAdmin command. const ImAdminTrigger = "imadmin" @@ -15,6 +25,15 @@ const IsAdminTrigger = "isadmin" // Repo is a URL to this project's repository. Useful for showing with help information. const Repo = "https://github.com/BKrajancic/boby" +func GetAdminConfigs(reader io.Reader) (AdminConfig, error) { + bytes, err := io.ReadAll(reader) + if err != nil { + return AdminConfig{}, err + } + var config AdminConfig + return config, json.Unmarshal(bytes, &config) +} + // AdminCommands returns an array of commands for handling admins. func AdminCommands() []Command { return []Command{ diff --git a/src/config/config.go b/src/config/config.go index c33d845..a4f7e02 100644 --- a/src/config/config.go +++ b/src/config/config.go @@ -13,6 +13,7 @@ import ( "github.com/BKrajancic/boby/m/v2/src/utils" ) +const adminConfigFilepath = "admin_config.json" const jsonFilepath = "json_getter_config.json" const regexpFilepath = "regexp_scraper_config.json" const goqueryFilepath = "goquery_scraper_config.json" @@ -159,7 +160,7 @@ func MakeExampleDir(dir string) error { // ConfiguredBot uses files in configDir to return a bot ready for usage. // This bot is not attached to any storage or services. func ConfiguredBot(configDir string, storage *storage.Storage) ([]command.Command, error) { - commands := command.AdminCommands() + commands := []command.Command{} file, err := os.Open(path.Join(configDir, jsonFilepath)) if err != nil { @@ -243,6 +244,19 @@ func ConfiguredBot(configDir string, storage *storage.Storage) ([]command.Comman commands = append(commands, oxfordCommandInfo) } + file, err = os.Open(path.Join(configDir, adminConfigFilepath)) + if err != nil { + return commands, err + } + + adminConfig, err := command.GetAdminConfigs(bufio.NewReader(file)) + if err != nil { + return commands, err + } + if adminConfig.Enabled { + commands = append(commands, command.AdminCommands()...) + } + // TODO: Helptext is hardcoded for discord, and is therefore a leaky abstraction. renderCmd := command.Command{ Trigger: "render", diff --git a/src/service/discordservice/discord_subject.go b/src/service/discordservice/discord_subject.go index 825bc8e..0a78ff3 100644 --- a/src/service/discordservice/discord_subject.go +++ b/src/service/discordservice/discord_subject.go @@ -543,13 +543,23 @@ func (d *DiscordSubject) helpExec(conversation service.Conversation, user servic Value: command.Repo, }) - return sink( - conversation, - service.Message{ - Title: "Help", - Fields: fields, - }, - ) + const batchSize = 25 + for i := 0; i < len(fields); i += batchSize { + batch := fields[i:min(i+batchSize, len(fields))] + err := sink( + conversation, + service.Message{ + Title: "Help", + Fields: batch, + }, + ) + + if err != nil { + return err + } + } + + return nil } func (d *DiscordSubject) handleMessageError(m *discordgo.Message, event string, err error) {