107 lines
2.7 KiB
Go
107 lines
2.7 KiB
Go
package interactions
|
|
|
|
import (
|
|
"crypto/ed25519"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
|
|
"github.com/gofiber/fiber/v3"
|
|
|
|
"git.sapphic.engineer/roleypoly/v4/discord"
|
|
"git.sapphic.engineer/roleypoly/v4/types"
|
|
"git.sapphic.engineer/roleypoly/v4/utils"
|
|
)
|
|
|
|
type Interactions struct {
|
|
PublicKey ed25519.PublicKey
|
|
PublicBaseURL string
|
|
Guilds *discord.GuildService
|
|
Router *InteractionRouter
|
|
|
|
// if interactions are able to be used
|
|
OK bool
|
|
|
|
commandsMap []InteractionCommand
|
|
commandsMentions map[string]string
|
|
}
|
|
|
|
func NewInteractions(publicKey string, publicBaseURL string, guildsService *discord.GuildService) *Interactions {
|
|
return &Interactions{
|
|
PublicKey: ed25519.PublicKey(publicKey),
|
|
PublicBaseURL: publicBaseURL,
|
|
Guilds: guildsService,
|
|
Router: NewInteractionRouter(),
|
|
OK: len(publicKey) != 0,
|
|
}
|
|
}
|
|
|
|
func (i *Interactions) Routes(r fiber.Router) {
|
|
r.Post("/", i.PostHandler)
|
|
|
|
i.Router.Add("hello-world", i.CmdHelloWorld)
|
|
i.Router.Add("roleypoly", i.CmdRoleypoly)
|
|
}
|
|
|
|
func (i *Interactions) PostHandler(c fiber.Ctx) error {
|
|
if !i.OK {
|
|
return types.NewAPIError(http.StatusUnauthorized, "interactions not enabled").Send(c)
|
|
}
|
|
|
|
signature := c.Get("X-Signature-Ed25519")
|
|
timestamp := c.Get("X-Signature-Timestamp")
|
|
err := i.Verify(signature, timestamp, c.BodyRaw())
|
|
if err != nil {
|
|
log.Println("interactions: verification failed, ", err)
|
|
return types.NewAPIError(http.StatusUnauthorized, "verification failed").Send(c)
|
|
}
|
|
|
|
ix := Interaction{}
|
|
err = c.Bind().JSON(&ix)
|
|
if err != nil {
|
|
log.Println("interactions: json body parse failed, ", err)
|
|
return types.NewAPIError(http.StatusBadRequest, "bad request").Send(c)
|
|
}
|
|
|
|
if ix.Type == TypePing {
|
|
return c.JSON(InteractionResponse{
|
|
Type: ResponsePong,
|
|
})
|
|
}
|
|
|
|
if ix.Type == TypeApplicationCommand {
|
|
return i.Router.Handle(c, ix)
|
|
}
|
|
|
|
return types.NewAPIError(http.StatusNotImplemented, "not implemented").Send(c)
|
|
}
|
|
|
|
func (i *Interactions) CommandsMap() map[string]string {
|
|
if i.commandsMentions != nil {
|
|
return i.commandsMentions
|
|
}
|
|
|
|
dc := i.Guilds.Client()
|
|
req := discord.NewRequest("GET", utils.J("applications", i.Guilds.Client().GetClientID(), "commands"))
|
|
dc.BotAuth(req)
|
|
|
|
resp, err := dc.Do(req)
|
|
if err != nil {
|
|
log.Println("interactions: commands map fetch failed")
|
|
return nil
|
|
}
|
|
|
|
i.commandsMap = []InteractionCommand{}
|
|
err = discord.OutputResponse(resp, &i.commandsMap)
|
|
if err != nil {
|
|
log.Println("interactions: commands map parse failed")
|
|
return nil
|
|
}
|
|
|
|
i.commandsMentions = map[string]string{}
|
|
for _, command := range i.commandsMap {
|
|
i.commandsMentions[command.Name] = fmt.Sprintf("</%s:%s>", command.ID, command.Name)
|
|
}
|
|
|
|
return i.commandsMentions
|
|
}
|