From c6155d63dc699dd3cbdca0f203078a48788e151b Mon Sep 17 00:00:00 2001 From: "diamondburned (Forefront)" Date: Wed, 22 Jan 2020 19:52:07 -0800 Subject: [PATCH] Added the Wait API into Handler and example --- _example/advanced_bot/context.go | 35 ++++++++++++++++++++++++++++++++ handler/handler.go | 20 ++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/_example/advanced_bot/context.go b/_example/advanced_bot/context.go index 33a16a1..13d373f 100644 --- a/_example/advanced_bot/context.go +++ b/_example/advanced_bot/context.go @@ -1,10 +1,12 @@ package main import ( + "context" "errors" "fmt" "strconv" "strings" + "time" "github.com/diamondburned/arikawa/bot" "github.com/diamondburned/arikawa/bot/extras/arguments" @@ -45,6 +47,39 @@ func (bot *Bot) Say(m *gateway.MessageCreateEvent, f *arguments.Flag) error { return err } +// Repeat tells the bot to wait for the user's response, then repeat what they +// said. +func (bot *Bot) Repeat(m *gateway.MessageCreateEvent) error { + _, err := bot.Ctx.SendMessage(m.ChannelID, + "What do you want me to say?", nil) + if err != nil { + return err + } + + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + v := bot.Ctx.WaitFor(ctx, func(v interface{}) bool { + // Incoming event is a message create event: + mg, ok := v.(*gateway.MessageCreateEvent) + if !ok { + return false + } + + // Message is from the same author: + return mg.Author.ID == m.Author.ID + }) + + if v == nil { + return errors.New("Timed out waiting for response.") + } + + ev := v.(*gateway.MessageCreateEvent) + + _, err = bot.Ctx.SendMessage(m.ChannelID, ev.Content, nil) + return err +} + func (bot *Bot) Embed( m *gateway.MessageCreateEvent, f *arguments.Flag) error { diff --git a/handler/handler.go b/handler/handler.go index f45bd23..a871f1f 100644 --- a/handler/handler.go +++ b/handler/handler.go @@ -24,6 +24,7 @@ package handler import ( + "context" "fmt" "reflect" "sync" @@ -67,6 +68,25 @@ func (h *Handler) Call(ev interface{}) { } } +func (h *Handler) WaitFor(ctx context.Context, fn func(interface{}) bool) interface{} { + var result = make(chan interface{}) + + cancel := h.AddHandler(func(v interface{}) { + if fn(v) { + result <- v + } + }) + + defer cancel() + + select { + case r := <-result: + return r + case <-ctx.Done(): + return nil + } +} + func (h *Handler) AddHandler(handler interface{}) (rm func()) { rm, err := h.addHandler(handler) if err != nil {