mirror of
https://github.com/diamondburned/arikawa.git
synced 2025-01-07 12:38:05 +00:00
Bot: Added EditableCommands
This commit is contained in:
parent
6b8628804f
commit
795a69ca7d
10
README.md
10
README.md
|
@ -63,16 +63,6 @@ custom remote or local state storage.
|
||||||
things in the state, which is useful for keeping it updated.
|
things in the state, which is useful for keeping it updated.
|
||||||
- No code generation: just so the library is a lot easier to maintain.
|
- No code generation: just so the library is a lot easier to maintain.
|
||||||
|
|
||||||
## You-should-knows
|
|
||||||
|
|
||||||
- ~~The bot will fatally exit if it fails to reconnect to the Gateway after a
|
|
||||||
certain amount of times. This is changeable in `gateway.WSFatal`, or
|
|
||||||
`(*Gateway).FatalLog`.~~
|
|
||||||
- ~~The bot will error out if the initial connection fails. However,
|
|
||||||
reconnections will be retried forever until it succeeds.~~ This is no longer
|
|
||||||
true. The bot will retry until `WSRetries` is reached, then the error will go
|
|
||||||
to `(*Gateway).FatalError` or `(*Gateway).Wait()`.
|
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
The package includes integration tests that require `$BOT_TOKEN`. To run these
|
The package includes integration tests that require `$BOT_TOKEN`. To run these
|
||||||
|
|
|
@ -19,6 +19,7 @@ func main() {
|
||||||
|
|
||||||
wait, err := bot.Start(token, commands, func(ctx *bot.Context) error {
|
wait, err := bot.Start(token, commands, func(ctx *bot.Context) error {
|
||||||
ctx.HasPrefix = bot.NewPrefix("!", "~")
|
ctx.HasPrefix = bot.NewPrefix("!", "~")
|
||||||
|
ctx.EditableCommands = true
|
||||||
|
|
||||||
// Subcommand demo, but this can be in another package.
|
// Subcommand demo, but this can be in another package.
|
||||||
ctx.MustRegisterSubcommand(&Debug{})
|
ctx.MustRegisterSubcommand(&Debug{})
|
||||||
|
|
|
@ -124,6 +124,11 @@ type Context struct {
|
||||||
// MessageCreate events.
|
// MessageCreate events.
|
||||||
ReplyError bool
|
ReplyError bool
|
||||||
|
|
||||||
|
// EditableCommands when true will also listen for MessageUpdateEvent and
|
||||||
|
// treat them as newly created messages. This is convenient if you want
|
||||||
|
// to quickly edit a message and re-execute the command.
|
||||||
|
EditableCommands bool
|
||||||
|
|
||||||
// Subcommands contains all the registered subcommands. This is not
|
// Subcommands contains all the registered subcommands. This is not
|
||||||
// exported, as it shouldn't be used directly.
|
// exported, as it shouldn't be used directly.
|
||||||
subcommands []*Subcommand
|
subcommands []*Subcommand
|
||||||
|
|
|
@ -58,19 +58,51 @@ func (ctx *Context) callCmd(ev interface{}) (bottomError error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var msc *gateway.MessageCreateEvent
|
||||||
|
|
||||||
// We call the messages later, since we want MessageCreate middlewares to
|
// We call the messages later, since we want MessageCreate middlewares to
|
||||||
// run as well.
|
// run as well.
|
||||||
if evT == typeMessageCreate {
|
switch {
|
||||||
// safe assertion always
|
case evT == typeMessageCreate:
|
||||||
err := ctx.callMessageCreate(ev.(*gateway.MessageCreateEvent), evV)
|
msc = ev.(*gateway.MessageCreateEvent)
|
||||||
// There's no need for an errNoBreak here, as the method already checked
|
|
||||||
// for that.
|
case evT == typeMessageUpdate && ctx.EditableCommands:
|
||||||
if err != nil {
|
up := ev.(*gateway.MessageUpdateEvent)
|
||||||
bottomError = err
|
// Message updates could have empty contents when only their embeds are
|
||||||
|
// filled. We don't need that here.
|
||||||
|
if up.Content == "" {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Query the updated message.
|
||||||
|
m, err := ctx.Store.Message(up.ChannelID, up.ID)
|
||||||
|
if err != nil {
|
||||||
|
// It's probably safe to ignore this.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Treat the message update as a message create event to avoid breaking
|
||||||
|
// changes.
|
||||||
|
msc = &gateway.MessageCreateEvent{Message: *m, Member: up.Member}
|
||||||
|
|
||||||
|
// Fill up member, if available.
|
||||||
|
if m.GuildID.Valid() && up.Member == nil {
|
||||||
|
if mem, err := ctx.Store.Member(m.GuildID, m.Author.ID); err == nil {
|
||||||
|
msc.Member = mem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the reflect value as well.
|
||||||
|
evV = reflect.ValueOf(msc)
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Unknown event, return.
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
// There's no need for an errNoBreak here, as the method already checked
|
||||||
|
// for that.
|
||||||
|
return ctx.callMessageCreate(msc, evV)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) callMessageCreate(mc *gateway.MessageCreateEvent, value reflect.Value) error {
|
func (ctx *Context) callMessageCreate(mc *gateway.MessageCreateEvent, value reflect.Value) error {
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
typeMessageCreate = reflect.TypeOf((*gateway.MessageCreateEvent)(nil))
|
typeMessageCreate = reflect.TypeOf((*gateway.MessageCreateEvent)(nil))
|
||||||
|
typeMessageUpdate = reflect.TypeOf((*gateway.MessageUpdateEvent)(nil))
|
||||||
|
|
||||||
typeString = reflect.TypeOf("")
|
typeString = reflect.TypeOf("")
|
||||||
typeEmbed = reflect.TypeOf((*discord.Embed)(nil))
|
typeEmbed = reflect.TypeOf((*discord.Embed)(nil))
|
||||||
|
|
Loading…
Reference in a new issue