package interactions import ( "crypto/ed25519" "log" "net/http" "os" "github.com/gofiber/fiber/v3" "git.sapphic.engineer/roleypoly/v4/discord" "git.sapphic.engineer/roleypoly/v4/types" ) type Interactions struct { PublicKey ed25519.PublicKey Guilds discord.IGuildService Router *InteractionRouter // if interactions are able to be used OK bool } func NewInteractions(publicKey string, guildsService discord.IGuildService) *Interactions { if publicKey == "" { publicKey = os.Getenv("DISCORD_PUBLIC_KEY") } return &Interactions{ PublicKey: ed25519.PublicKey(publicKey), 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) } 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) }