examples: Update commands to use cmdroute
This commit is contained in:
parent
080c734b37
commit
ced922d377
|
@ -2,7 +2,6 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"log"
|
"log"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -10,12 +9,12 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/diamondburned/arikawa/v3/api"
|
"github.com/diamondburned/arikawa/v3/api"
|
||||||
|
"github.com/diamondburned/arikawa/v3/api/cmdroute"
|
||||||
"github.com/diamondburned/arikawa/v3/api/webhook"
|
"github.com/diamondburned/arikawa/v3/api/webhook"
|
||||||
"github.com/diamondburned/arikawa/v3/discord"
|
"github.com/diamondburned/arikawa/v3/discord"
|
||||||
"github.com/diamondburned/arikawa/v3/gateway"
|
"github.com/diamondburned/arikawa/v3/gateway"
|
||||||
"github.com/diamondburned/arikawa/v3/state"
|
"github.com/diamondburned/arikawa/v3/state"
|
||||||
"github.com/diamondburned/arikawa/v3/utils/json/option"
|
"github.com/diamondburned/arikawa/v3/utils/json/option"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var commands = []api.CreateCommandData{
|
var commands = []api.CreateCommandData{
|
||||||
|
@ -46,37 +45,39 @@ func main() {
|
||||||
log.Fatalln("No $BOT_TOKEN given.")
|
log.Fatalln("No $BOT_TOKEN given.")
|
||||||
}
|
}
|
||||||
|
|
||||||
var h handler
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
webhookAddr = os.Getenv("WEBHOOK_ADDR")
|
webhookAddr = os.Getenv("WEBHOOK_ADDR")
|
||||||
webhookPubkey = os.Getenv("WEBHOOK_PUBKEY")
|
webhookPubkey = os.Getenv("WEBHOOK_PUBKEY")
|
||||||
)
|
)
|
||||||
|
|
||||||
if webhookAddr != "" {
|
if webhookAddr != "" {
|
||||||
h.s = state.NewAPIOnlyState(token, nil)
|
state := state.NewAPIOnlyState(token, nil)
|
||||||
|
|
||||||
srv, err := webhook.NewInteractionServer(webhookPubkey, &h)
|
h := newHandler(state)
|
||||||
if err != nil {
|
|
||||||
log.Fatalln("cannot create interaction server:", err)
|
if err := overwriteCommands(state); err != nil {
|
||||||
|
log.Fatalln("cannot update commands:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := overwriteCommands(h.s); err != nil {
|
srv, err := webhook.NewInteractionServer(webhookPubkey, h)
|
||||||
log.Fatalln("cannot update commands:", err)
|
if err != nil {
|
||||||
|
log.Fatalln("cannot create interaction server:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("listening and serving at", webhookAddr+"/")
|
log.Println("listening and serving at", webhookAddr+"/")
|
||||||
log.Fatalln(http.ListenAndServe(webhookAddr, srv))
|
log.Fatalln(http.ListenAndServe(webhookAddr, srv))
|
||||||
} else {
|
} else {
|
||||||
h.s = state.New("Bot " + token)
|
state := state.New("Bot " + token)
|
||||||
h.s.AddInteractionHandler(&h)
|
state.AddIntents(gateway.IntentGuilds)
|
||||||
h.s.AddIntents(gateway.IntentGuilds)
|
state.AddHandler(func(*gateway.ReadyEvent) {
|
||||||
h.s.AddHandler(func(*gateway.ReadyEvent) {
|
me, _ := state.Me()
|
||||||
me, _ := h.s.Me()
|
|
||||||
log.Println("connected to the gateway as", me.Tag())
|
log.Println("connected to the gateway as", me.Tag())
|
||||||
})
|
})
|
||||||
|
|
||||||
if err := overwriteCommands(h.s); err != nil {
|
h := newHandler(state)
|
||||||
|
state.AddInteractionHandler(h)
|
||||||
|
|
||||||
|
if err := overwriteCommands(state); err != nil {
|
||||||
log.Fatalln("cannot update commands:", err)
|
log.Fatalln("cannot update commands:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,47 +88,34 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func overwriteCommands(s *state.State) error {
|
func overwriteCommands(s *state.State) error {
|
||||||
app, err := s.CurrentApplication()
|
return cmdroute.OverwriteCommands(s, commands)
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "cannot get current app ID")
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = s.BulkOverwriteCommands(app.ID, commands)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type handler struct {
|
type handler struct {
|
||||||
|
*cmdroute.Router
|
||||||
s *state.State
|
s *state.State
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) HandleInteraction(ev *discord.InteractionEvent) *api.InteractionResponse {
|
func newHandler(s *state.State) *handler {
|
||||||
switch data := ev.Data.(type) {
|
h := &handler{s: s}
|
||||||
case *discord.CommandInteraction:
|
|
||||||
switch data.Name {
|
h.Router = cmdroute.NewRouter()
|
||||||
case "ping":
|
// Automatically defer handles if they're slow.
|
||||||
return h.cmdPing(ev, data)
|
h.Use(cmdroute.Deferrable(s, cmdroute.DeferOpts{}))
|
||||||
case "echo":
|
h.AddFunc("ping", h.cmdPing)
|
||||||
return h.cmdEcho(ev, data)
|
h.AddFunc("echo", h.cmdEcho)
|
||||||
case "thonk":
|
h.AddFunc("thonk", h.cmdThonk)
|
||||||
return h.cmdThonk(ev, data)
|
|
||||||
default:
|
return h
|
||||||
return errorResponse(fmt.Errorf("unknown command %q", data.Name))
|
}
|
||||||
}
|
|
||||||
default:
|
func (h *handler) cmdPing(ctx context.Context, cmd cmdroute.CommandData) *api.InteractionResponseData {
|
||||||
return errorResponse(fmt.Errorf("unknown interaction %T", ev.Data))
|
return &api.InteractionResponseData{
|
||||||
|
Content: option.NewNullableString("Pong!"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) cmdPing(ev *discord.InteractionEvent, _ *discord.CommandInteraction) *api.InteractionResponse {
|
func (h *handler) cmdEcho(ctx context.Context, data cmdroute.CommandData) *api.InteractionResponseData {
|
||||||
return &api.InteractionResponse{
|
|
||||||
Type: api.MessageInteractionWithSource,
|
|
||||||
Data: &api.InteractionResponseData{
|
|
||||||
Content: option.NewNullableString("Pong!"),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *handler) cmdEcho(ev *discord.InteractionEvent, data *discord.CommandInteraction) *api.InteractionResponse {
|
|
||||||
var options struct {
|
var options struct {
|
||||||
Arg string `discord:"argument"`
|
Arg string `discord:"argument"`
|
||||||
}
|
}
|
||||||
|
@ -136,43 +124,23 @@ func (h *handler) cmdEcho(ev *discord.InteractionEvent, data *discord.CommandInt
|
||||||
return errorResponse(err)
|
return errorResponse(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &api.InteractionResponse{
|
return &api.InteractionResponseData{
|
||||||
Type: api.MessageInteractionWithSource,
|
Content: option.NewNullableString(options.Arg),
|
||||||
Data: &api.InteractionResponseData{
|
AllowedMentions: &api.AllowedMentions{}, // don't mention anyone
|
||||||
Content: option.NewNullableString(options.Arg),
|
|
||||||
AllowedMentions: &api.AllowedMentions{},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) cmdThonk(ev *discord.InteractionEvent, data *discord.CommandInteraction) *api.InteractionResponse {
|
func (h *handler) cmdThonk(ctx context.Context, data cmdroute.CommandData) *api.InteractionResponseData {
|
||||||
go func() {
|
time.Sleep(time.Duration(3+rand.Intn(5)) * time.Second)
|
||||||
time.Sleep(time.Duration(3+rand.Intn(5)) * time.Second)
|
return &api.InteractionResponseData{
|
||||||
|
Content: option.NewNullableString("https://tenor.com/view/thonk-thinking-sun-thonk-sun-thinking-sun-gif-14999983"),
|
||||||
h.s.FollowUpInteraction(ev.AppID, ev.Token, api.InteractionResponseData{
|
|
||||||
Content: option.NewNullableString("https://tenor.com/view/thonk-thinking-sun-thonk-sun-thinking-sun-gif-14999983"),
|
|
||||||
})
|
|
||||||
}()
|
|
||||||
|
|
||||||
return deferResponse(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func errorResponse(err error) *api.InteractionResponse {
|
|
||||||
return &api.InteractionResponse{
|
|
||||||
Type: api.MessageInteractionWithSource,
|
|
||||||
Data: &api.InteractionResponseData{
|
|
||||||
Content: option.NewNullableString("**Error:** " + err.Error()),
|
|
||||||
Flags: discord.EphemeralMessage,
|
|
||||||
AllowedMentions: &api.AllowedMentions{ /* none */ },
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func deferResponse(flags discord.MessageFlags) *api.InteractionResponse {
|
func errorResponse(err error) *api.InteractionResponseData {
|
||||||
return &api.InteractionResponse{
|
return &api.InteractionResponseData{
|
||||||
Type: api.DeferredMessageInteractionWithSource,
|
Content: option.NewNullableString("**Error:** " + err.Error()),
|
||||||
Data: &api.InteractionResponseData{
|
Flags: discord.EphemeralMessage,
|
||||||
Flags: flags,
|
AllowedMentions: &api.AllowedMentions{ /* none */ },
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/diamondburned/arikawa/v3/api"
|
||||||
|
"github.com/diamondburned/arikawa/v3/api/cmdroute"
|
||||||
|
"github.com/diamondburned/arikawa/v3/gateway"
|
||||||
|
"github.com/diamondburned/arikawa/v3/state"
|
||||||
|
"github.com/diamondburned/arikawa/v3/utils/json/option"
|
||||||
|
)
|
||||||
|
|
||||||
|
var commands = []api.CreateCommandData{{Name: "ping", Description: "Ping!"}}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
r := cmdroute.NewRouter()
|
||||||
|
r.AddFunc("ping", func(ctx context.Context, data cmdroute.CommandData) *api.InteractionResponseData {
|
||||||
|
return &api.InteractionResponseData{Content: option.NewNullableString("Pong!")}
|
||||||
|
})
|
||||||
|
|
||||||
|
s := state.New("Bot " + os.Getenv("BOT_TOKEN"))
|
||||||
|
s.AddInteractionHandler(r)
|
||||||
|
s.AddIntents(gateway.IntentGuilds)
|
||||||
|
|
||||||
|
if err := cmdroute.OverwriteCommands(s, commands); err != nil {
|
||||||
|
log.Fatalln("cannot update commands:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.Connect(context.TODO()); err != nil {
|
||||||
|
log.Println("cannot connect:", err)
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,18 +2,18 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"log"
|
"log"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
|
"os/signal"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/diamondburned/arikawa/v3/api"
|
"github.com/diamondburned/arikawa/v3/api"
|
||||||
|
"github.com/diamondburned/arikawa/v3/api/cmdroute"
|
||||||
"github.com/diamondburned/arikawa/v3/discord"
|
"github.com/diamondburned/arikawa/v3/discord"
|
||||||
"github.com/diamondburned/arikawa/v3/gateway"
|
"github.com/diamondburned/arikawa/v3/gateway"
|
||||||
"github.com/diamondburned/arikawa/v3/state"
|
"github.com/diamondburned/arikawa/v3/state"
|
||||||
"github.com/diamondburned/arikawa/v3/utils/json/option"
|
"github.com/diamondburned/arikawa/v3/utils/json/option"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// To run, do `BOT_TOKEN="TOKEN HERE" go run .`
|
// To run, do `BOT_TOKEN="TOKEN HERE" go run .`
|
||||||
|
@ -46,9 +46,8 @@ func main() {
|
||||||
log.Fatalln("No $BOT_TOKEN given.")
|
log.Fatalln("No $BOT_TOKEN given.")
|
||||||
}
|
}
|
||||||
|
|
||||||
var h handler
|
h := newHandler(state.New("Bot " + token))
|
||||||
h.s = state.New("Bot " + token)
|
h.s.AddInteractionHandler(h)
|
||||||
h.s.AddInteractionHandler(&h)
|
|
||||||
h.s.AddIntents(gateway.IntentGuilds)
|
h.s.AddIntents(gateway.IntentGuilds)
|
||||||
h.s.AddHandler(func(*gateway.ReadyEvent) {
|
h.s.AddHandler(func(*gateway.ReadyEvent) {
|
||||||
me, _ := h.s.Me()
|
me, _ := h.s.Me()
|
||||||
|
@ -59,53 +58,43 @@ func main() {
|
||||||
log.Fatalln("cannot update commands:", err)
|
log.Fatalln("cannot update commands:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := h.s.Connect(context.Background()); err != nil {
|
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
if err := h.s.Connect(ctx); err != nil {
|
||||||
log.Fatalln("cannot connect:", err)
|
log.Fatalln("cannot connect:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func overwriteCommands(s *state.State) error {
|
func overwriteCommands(s *state.State) error {
|
||||||
app, err := s.CurrentApplication()
|
return cmdroute.OverwriteCommands(s, commands)
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "cannot get current app ID")
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = s.BulkOverwriteCommands(app.ID, commands)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type handler struct {
|
type handler struct {
|
||||||
|
*cmdroute.Router
|
||||||
s *state.State
|
s *state.State
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) HandleInteraction(ev *discord.InteractionEvent) *api.InteractionResponse {
|
func newHandler(s *state.State) *handler {
|
||||||
switch data := ev.Data.(type) {
|
h := &handler{s: s}
|
||||||
case *discord.CommandInteraction:
|
|
||||||
switch data.Name {
|
h.Router = cmdroute.NewRouter()
|
||||||
case "ping":
|
// Automatically defer handles if they're slow.
|
||||||
return h.cmdPing(ev, data)
|
h.Use(cmdroute.Deferrable(s, cmdroute.DeferOpts{}))
|
||||||
case "echo":
|
h.AddFunc("ping", h.cmdPing)
|
||||||
return h.cmdEcho(ev, data)
|
h.AddFunc("echo", h.cmdEcho)
|
||||||
case "thonk":
|
h.AddFunc("thonk", h.cmdThonk)
|
||||||
return h.cmdThonk(ev, data)
|
|
||||||
default:
|
return h
|
||||||
return errorResponse(fmt.Errorf("unknown command %q", data.Name))
|
}
|
||||||
}
|
|
||||||
default:
|
func (h *handler) cmdPing(ctx context.Context, cmd cmdroute.CommandData) *api.InteractionResponseData {
|
||||||
return errorResponse(fmt.Errorf("unknown interaction %T", ev.Data))
|
return &api.InteractionResponseData{
|
||||||
|
Content: option.NewNullableString("Pong!"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) cmdPing(ev *discord.InteractionEvent, _ *discord.CommandInteraction) *api.InteractionResponse {
|
func (h *handler) cmdEcho(ctx context.Context, data cmdroute.CommandData) *api.InteractionResponseData {
|
||||||
return &api.InteractionResponse{
|
|
||||||
Type: api.MessageInteractionWithSource,
|
|
||||||
Data: &api.InteractionResponseData{
|
|
||||||
Content: option.NewNullableString("Pong!"),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *handler) cmdEcho(ev *discord.InteractionEvent, data *discord.CommandInteraction) *api.InteractionResponse {
|
|
||||||
var options struct {
|
var options struct {
|
||||||
Arg string `discord:"argument"`
|
Arg string `discord:"argument"`
|
||||||
}
|
}
|
||||||
|
@ -114,43 +103,23 @@ func (h *handler) cmdEcho(ev *discord.InteractionEvent, data *discord.CommandInt
|
||||||
return errorResponse(err)
|
return errorResponse(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &api.InteractionResponse{
|
return &api.InteractionResponseData{
|
||||||
Type: api.MessageInteractionWithSource,
|
Content: option.NewNullableString(options.Arg),
|
||||||
Data: &api.InteractionResponseData{
|
AllowedMentions: &api.AllowedMentions{}, // don't mention anyone
|
||||||
Content: option.NewNullableString(options.Arg),
|
|
||||||
AllowedMentions: &api.AllowedMentions{},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) cmdThonk(ev *discord.InteractionEvent, data *discord.CommandInteraction) *api.InteractionResponse {
|
func (h *handler) cmdThonk(ctx context.Context, data cmdroute.CommandData) *api.InteractionResponseData {
|
||||||
go func() {
|
time.Sleep(time.Duration(3+rand.Intn(5)) * time.Second)
|
||||||
time.Sleep(time.Duration(3+rand.Intn(5)) * time.Second)
|
return &api.InteractionResponseData{
|
||||||
|
Content: option.NewNullableString("https://tenor.com/view/thonk-thinking-sun-thonk-sun-thinking-sun-gif-14999983"),
|
||||||
h.s.FollowUpInteraction(ev.AppID, ev.Token, api.InteractionResponseData{
|
|
||||||
Content: option.NewNullableString("https://tenor.com/view/thonk-thinking-sun-thonk-sun-thinking-sun-gif-14999983"),
|
|
||||||
})
|
|
||||||
}()
|
|
||||||
|
|
||||||
return deferResponse(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func errorResponse(err error) *api.InteractionResponse {
|
|
||||||
return &api.InteractionResponse{
|
|
||||||
Type: api.MessageInteractionWithSource,
|
|
||||||
Data: &api.InteractionResponseData{
|
|
||||||
Content: option.NewNullableString("**Error:** " + err.Error()),
|
|
||||||
Flags: discord.EphemeralMessage,
|
|
||||||
AllowedMentions: &api.AllowedMentions{ /* none */ },
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func deferResponse(flags discord.MessageFlags) *api.InteractionResponse {
|
func errorResponse(err error) *api.InteractionResponseData {
|
||||||
return &api.InteractionResponse{
|
return &api.InteractionResponseData{
|
||||||
Type: api.DeferredMessageInteractionWithSource,
|
Content: option.NewNullableString("**Error:** " + err.Error()),
|
||||||
Data: &api.InteractionResponseData{
|
Flags: discord.EphemeralMessage,
|
||||||
Flags: flags,
|
AllowedMentions: &api.AllowedMentions{ /* none */ },
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
24
README.md
24
README.md
|
@ -93,23 +93,31 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
|
||||||
|
|
||||||
|
"github.com/diamondburned/arikawa/v3/api"
|
||||||
|
"github.com/diamondburned/arikawa/v3/api/cmdroute"
|
||||||
"github.com/diamondburned/arikawa/v3/gateway"
|
"github.com/diamondburned/arikawa/v3/gateway"
|
||||||
"github.com/diamondburned/arikawa/v3/state"
|
"github.com/diamondburned/arikawa/v3/state"
|
||||||
|
"github.com/diamondburned/arikawa/v3/utils/json/option"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var commands = []api.CreateCommandData{{Name: "ping", Description: "Ping!"}}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s := state.New("Bot " + os.Getenv("BOT_TOKEN"))
|
r := cmdroute.NewRouter()
|
||||||
s.AddIntents(gateway.IntentGuilds | gateway.IntentGuildMessages)
|
r.AddFunc("ping", func(ctx context.Context, data cmdroute.CommandData) *api.InteractionResponseData {
|
||||||
s.AddHandler(func(m *gateway.MessageCreateEvent) {
|
return &api.InteractionResponseData{Content: option.NewNullableString("Pong!")}
|
||||||
log.Printf("%s: %s", m.Author.Username, m.Content)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
|
s := state.New("Bot " + os.Getenv("BOT_TOKEN"))
|
||||||
defer cancel()
|
s.AddInteractionHandler(r)
|
||||||
|
s.AddIntents(gateway.IntentGuilds)
|
||||||
|
|
||||||
if err := s.Connect(ctx); err != nil {
|
if err := cmdroute.OverwriteCommands(s, commands); err != nil {
|
||||||
|
log.Fatalln("cannot update commands:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.Connect(context.TODO()); err != nil {
|
||||||
log.Println("cannot connect:", err)
|
log.Println("cannot connect:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue