mirror of
https://github.com/Fluffy-Bean/Lynxie.git
synced 2025-05-14 08:02:17 +00:00
Error handling
Embed responses
This commit is contained in:
parent
b93820e9d0
commit
f3929f2665
6 changed files with 169 additions and 48 deletions
68
app/app.go
68
app/app.go
|
@ -2,14 +2,18 @@ package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/Fluffy-Bean/lynxie/utils"
|
||||||
"github.com/bwmarrin/discordgo"
|
"github.com/bwmarrin/discordgo"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Callback func(h *Handler, args []string) Error
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Prefix string
|
Prefix string
|
||||||
Token string
|
Token string
|
||||||
|
@ -18,17 +22,17 @@ type Config struct {
|
||||||
|
|
||||||
type App struct {
|
type App struct {
|
||||||
Config Config
|
Config Config
|
||||||
Commands map[string]func(h *Handler, args []string)
|
Commands map[string]Callback
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewApp(config Config) *App {
|
func NewApp(config Config) *App {
|
||||||
return &App{
|
return &App{
|
||||||
Config: config,
|
Config: config,
|
||||||
Commands: make(map[string]func(h *Handler, args []string)),
|
Commands: make(map[string]Callback),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) RegisterCommand(cmd string, f func(h *Handler, args []string)) {
|
func (a *App) RegisterCommand(cmd string, f Callback) {
|
||||||
a.Commands[cmd] = f
|
a.Commands[cmd] = f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,34 +65,76 @@ func (a *App) Run() {
|
||||||
type Handler struct {
|
type Handler struct {
|
||||||
Session *discordgo.Session
|
Session *discordgo.Session
|
||||||
Message *discordgo.MessageCreate
|
Message *discordgo.MessageCreate
|
||||||
|
Reference *discordgo.MessageReference
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) handler(session *discordgo.Session, message *discordgo.MessageCreate) {
|
func (a *App) handler(session *discordgo.Session, message *discordgo.MessageCreate) {
|
||||||
h := &Handler{
|
h := &Handler{
|
||||||
Session: session,
|
Session: session,
|
||||||
Message: message,
|
Message: message,
|
||||||
|
Reference: &discordgo.MessageReference{
|
||||||
|
ChannelID: message.ChannelID,
|
||||||
|
MessageID: message.ID,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.Message.Author.ID == h.Session.State.User.ID {
|
if h.Message.Author.ID == h.Session.State.User.ID {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.Message.Author.Bot {
|
if h.Message.Author.Bot {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var command string
|
var cmd string
|
||||||
var args string
|
var args string
|
||||||
|
|
||||||
command = h.Message.Content
|
cmd = h.Message.Content
|
||||||
command = strings.TrimSpace(command)
|
cmd = strings.TrimPrefix(cmd, a.Config.Prefix)
|
||||||
command = strings.TrimPrefix(command, a.Config.Prefix)
|
cmd, args, _ = strings.Cut(cmd, " ")
|
||||||
command, args, _ = strings.Cut(command, " ")
|
|
||||||
|
|
||||||
callback, ok := a.Commands[command]
|
callback, ok := a.Commands[cmd]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
// Falling back to default help command
|
||||||
|
if cmd == "help" {
|
||||||
|
printHelp(a, h)
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(h, strings.Split(args, " "))
|
h.Session.ChannelTyping(h.Message.ChannelID)
|
||||||
|
|
||||||
|
err := callback(h, strings.Split(args, " "))
|
||||||
|
if !err.Ok() {
|
||||||
|
printError(a, h, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func printHelp(a *App, h *Handler) {
|
||||||
|
var commands []string
|
||||||
|
for cmd := range a.Commands {
|
||||||
|
commands = append(commands, cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
h.Session.ChannelMessageSendComplex(h.Message.ChannelID, &discordgo.MessageSend{
|
||||||
|
Embed: &discordgo.MessageEmbed{
|
||||||
|
Title: "Help",
|
||||||
|
Description: strings.Join(commands, "\n"),
|
||||||
|
Color: utils.ColorFromRGB(255, 255, 255),
|
||||||
|
},
|
||||||
|
Reference: h.Reference,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func printError(a *App, h *Handler, e Error) {
|
||||||
|
log.Println(e.Err)
|
||||||
|
|
||||||
|
h.Session.ChannelMessageSendComplex(h.Message.ChannelID, &discordgo.MessageSend{
|
||||||
|
Embed: &discordgo.MessageEmbed{
|
||||||
|
Title: "Error",
|
||||||
|
Description: e.Msg,
|
||||||
|
Color: utils.ColorFromRGB(255, 0, 0),
|
||||||
|
},
|
||||||
|
Reference: h.Reference,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
10
app/errors.go
Normal file
10
app/errors.go
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package app
|
||||||
|
|
||||||
|
type Error struct {
|
||||||
|
Msg string
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Error) Ok() bool {
|
||||||
|
return e.Err == nil
|
||||||
|
}
|
|
@ -9,6 +9,8 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Fluffy-Bean/lynxie/app"
|
"github.com/Fluffy-Bean/lynxie/app"
|
||||||
|
"github.com/Fluffy-Bean/lynxie/utils"
|
||||||
|
"github.com/bwmarrin/discordgo"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RegisterMetaCommands(a *app.App) {
|
func RegisterMetaCommands(a *app.App) {
|
||||||
|
@ -16,8 +18,8 @@ func RegisterMetaCommands(a *app.App) {
|
||||||
a.RegisterCommand("debug", registerDebug(a))
|
a.RegisterCommand("debug", registerDebug(a))
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerPong(a *app.App) func(h *app.Handler, args []string) {
|
func registerPong(a *app.App) app.Callback {
|
||||||
return func(h *app.Handler, args []string) {
|
return func(h *app.Handler, args []string) app.Error {
|
||||||
var options struct {
|
var options struct {
|
||||||
latency bool
|
latency bool
|
||||||
}
|
}
|
||||||
|
@ -26,22 +28,27 @@ func registerPong(a *app.App) func(h *app.Handler, args []string) {
|
||||||
cmd.BoolVar(&options.latency, "latency", false, "Display the latency of ping")
|
cmd.BoolVar(&options.latency, "latency", false, "Display the latency of ping")
|
||||||
cmd.Parse(args)
|
cmd.Parse(args)
|
||||||
|
|
||||||
|
var content string
|
||||||
if options.latency {
|
if options.latency {
|
||||||
h.Session.ChannelMessageSend(
|
content = fmt.Sprintf("Pong! %dms", h.Session.HeartbeatLatency().Milliseconds())
|
||||||
h.Message.ChannelID,
|
|
||||||
fmt.Sprintf("Pong! %dms", h.Session.HeartbeatLatency().Milliseconds()),
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
h.Session.ChannelMessageSend(
|
content = "Pong!"
|
||||||
h.Message.ChannelID,
|
|
||||||
"Pong!",
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h.Session.ChannelMessageSendComplex(h.Message.ChannelID, &discordgo.MessageSend{
|
||||||
|
Embed: &discordgo.MessageEmbed{
|
||||||
|
Description: content,
|
||||||
|
Color: utils.ColorFromRGB(255, 255, 255),
|
||||||
|
},
|
||||||
|
Reference: h.Reference,
|
||||||
|
})
|
||||||
|
|
||||||
|
return app.Error{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerDebug(a *app.App) func(h *app.Handler, args []string) {
|
func registerDebug(a *app.App) app.Callback {
|
||||||
return func(h *app.Handler, args []string) {
|
return func(h *app.Handler, args []string) app.Error {
|
||||||
modified := false
|
modified := false
|
||||||
revision := "-"
|
revision := "-"
|
||||||
tags := "-"
|
tags := "-"
|
||||||
|
@ -65,17 +72,26 @@ func registerDebug(a *app.App) func(h *app.Handler, args []string) {
|
||||||
revision += " (uncommitted changes)"
|
revision += " (uncommitted changes)"
|
||||||
}
|
}
|
||||||
|
|
||||||
h.Session.ChannelMessageSend(
|
h.Session.ChannelMessageSendComplex(h.Message.ChannelID, &discordgo.MessageSend{
|
||||||
h.Message.ChannelID,
|
Embed: &discordgo.MessageEmbed{
|
||||||
fmt.Sprintf(
|
Description: strings.Join(
|
||||||
"``` Revision :: %s\nBuild Tags :: %s\nGo version :: %s\n OS/Arch :: %s\n GC Count :: %d\nLocal Time :: %s```",
|
[]string{
|
||||||
revision,
|
"```",
|
||||||
tags,
|
"Revision: " + revision,
|
||||||
_go,
|
"Build Tags: " + tags,
|
||||||
runtime.GOOS+"/"+runtime.GOARCH,
|
"Go version: " + _go,
|
||||||
gcCount,
|
"OS/Arch: " + runtime.GOOS + "/" + runtime.GOARCH,
|
||||||
localTime,
|
"GC Count: " + fmt.Sprint(gcCount),
|
||||||
|
"Local Time: " + localTime,
|
||||||
|
"```",
|
||||||
|
},
|
||||||
|
"\n",
|
||||||
),
|
),
|
||||||
)
|
Color: utils.ColorFromRGB(255, 255, 255),
|
||||||
|
},
|
||||||
|
Reference: h.Reference,
|
||||||
|
})
|
||||||
|
|
||||||
|
return app.Error{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,46 +1,90 @@
|
||||||
package commands
|
package commands
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Fluffy-Bean/lynxie/app"
|
"github.com/Fluffy-Bean/lynxie/app"
|
||||||
|
"github.com/Fluffy-Bean/lynxie/utils"
|
||||||
|
"github.com/bwmarrin/discordgo"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RegisterTinyfoxCommands(a *app.App) {
|
func RegisterTinyfoxCommands(a *app.App) {
|
||||||
a.RegisterCommand("animal", registerAnimal(a))
|
a.RegisterCommand("animal", registerAnimal(a))
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerAnimal(a *app.App) func(h *app.Handler, args []string) {
|
func registerAnimal(a *app.App) app.Callback {
|
||||||
|
animals := []string{
|
||||||
|
"fox", "yeen", "dog", "guara", "serval", "ott", "jackal", "bleat", "woof", "chi", "puma", "skunk", "tig", "wah",
|
||||||
|
"manul", "snep", "jaguar", "badger", "chee", "racc", "bear", "capy", "bun", "marten", "caracal", "snek",
|
||||||
|
"shiba", "dook", "leo", "yote", "poss", "chee", "lynx",
|
||||||
|
}
|
||||||
|
|
||||||
client := http.Client{
|
client := http.Client{
|
||||||
Timeout: 10 * time.Second,
|
Timeout: 10 * time.Second,
|
||||||
}
|
}
|
||||||
|
|
||||||
return func(h *app.Handler, args []string) {
|
return func(h *app.Handler, args []string) app.Error {
|
||||||
var options struct {
|
var options struct {
|
||||||
animal string
|
animal string
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := flag.NewFlagSet("pong", flag.ContinueOnError)
|
cmd := flag.NewFlagSet("pong", flag.ContinueOnError)
|
||||||
cmd.StringVar(&options.animal, "animal", "wah", "Get an image of an animal!")
|
cmd.StringVar(&options.animal, "animal", "", "Get an image of an animal!")
|
||||||
cmd.Parse(args)
|
cmd.Parse(args)
|
||||||
|
|
||||||
|
if options.animal == "" {
|
||||||
|
return app.Error{
|
||||||
|
Msg: "Animal name is required!",
|
||||||
|
Err: errors.New("animal name is required"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !slices.Contains(animals, options.animal) {
|
||||||
|
return app.Error{
|
||||||
|
Msg: fmt.Sprintf("Animal %s is invalid", options.animal),
|
||||||
|
Err: errors.New("entered invalid animal name"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodGet, "https://api.tinyfox.dev/img?animal="+options.animal, nil)
|
req, err := http.NewRequest(http.MethodGet, "https://api.tinyfox.dev/img?animal="+options.animal, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return app.Error{
|
||||||
|
Msg: "Failed to make request",
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := client.Do(req)
|
res, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return app.Error{
|
||||||
|
Msg: "Failed to do request",
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
|
|
||||||
h.Session.ChannelFileSend(
|
h.Session.ChannelMessageSendComplex(h.Message.ChannelID, &discordgo.MessageSend{
|
||||||
h.Message.ChannelID,
|
Embed: &discordgo.MessageEmbed{
|
||||||
"animal__"+options.animal+".png",
|
Title: "Animal",
|
||||||
res.Body,
|
Image: &discordgo.MessageEmbedImage{
|
||||||
)
|
URL: "attachment://image.png",
|
||||||
|
},
|
||||||
|
Color: utils.ColorFromRGB(255, 255, 255),
|
||||||
|
},
|
||||||
|
Files: []*discordgo.File{
|
||||||
|
{
|
||||||
|
Name: "image.png",
|
||||||
|
ContentType: "",
|
||||||
|
Reader: res.Body,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Reference: h.Reference,
|
||||||
|
})
|
||||||
|
|
||||||
|
return app.Error{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
2
main.go
2
main.go
|
@ -10,7 +10,7 @@ import (
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
a := app.NewApp(app.Config{
|
a := app.NewApp(app.Config{
|
||||||
Prefix: "?",
|
Prefix: ">",
|
||||||
Token: os.Getenv("TOKEN"),
|
Token: os.Getenv("TOKEN"),
|
||||||
Intents: discordgo.IntentsGuildMessages,
|
Intents: discordgo.IntentsGuildMessages,
|
||||||
})
|
})
|
||||||
|
|
5
utils/color.go
Normal file
5
utils/color.go
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
func ColorFromRGB(r, g, b int) int {
|
||||||
|
return (r << 16) + (g << 8) + b
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue