forked from pothtonswer/discordmuffin
Improve handling of invalid interaction situations
This commit is contained in:
parent
421e149650
commit
083bf5c1d9
1 changed files with 68 additions and 27 deletions
|
@ -5,6 +5,7 @@ import (
|
||||||
"crypto/ed25519"
|
"crypto/ed25519"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -40,6 +41,30 @@ const (
|
||||||
ApplicationCommandOptionMentionable ApplicationCommandOptionType = 9
|
ApplicationCommandOptionMentionable ApplicationCommandOptionType = 9
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (t ApplicationCommandOptionType) String() string {
|
||||||
|
switch t {
|
||||||
|
case ApplicationCommandOptionSubCommand:
|
||||||
|
return "SubCommand"
|
||||||
|
case ApplicationCommandOptionSubCommandGroup:
|
||||||
|
return "SubCommandGroup"
|
||||||
|
case ApplicationCommandOptionString:
|
||||||
|
return "String"
|
||||||
|
case ApplicationCommandOptionInteger:
|
||||||
|
return "Integer"
|
||||||
|
case ApplicationCommandOptionBoolean:
|
||||||
|
return "Boolean"
|
||||||
|
case ApplicationCommandOptionUser:
|
||||||
|
return "User"
|
||||||
|
case ApplicationCommandOptionChannel:
|
||||||
|
return "Channel"
|
||||||
|
case ApplicationCommandOptionRole:
|
||||||
|
return "Role"
|
||||||
|
case ApplicationCommandOptionMentionable:
|
||||||
|
return "Mentionable"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("ApplicationCommandOptionType(%d)", t)
|
||||||
|
}
|
||||||
|
|
||||||
// ApplicationCommandOption represents an option/subcommand/subcommands group.
|
// ApplicationCommandOption represents an option/subcommand/subcommands group.
|
||||||
type ApplicationCommandOption struct {
|
type ApplicationCommandOption struct {
|
||||||
Type ApplicationCommandOptionType `json:"type"`
|
Type ApplicationCommandOptionType `json:"type"`
|
||||||
|
@ -69,6 +94,18 @@ const (
|
||||||
InteractionMessageComponent InteractionType = 3
|
InteractionMessageComponent InteractionType = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (t InteractionType) String() string {
|
||||||
|
switch t {
|
||||||
|
case InteractionPing:
|
||||||
|
return "Ping"
|
||||||
|
case InteractionApplicationCommand:
|
||||||
|
return "ApplicationCommand"
|
||||||
|
case InteractionMessageComponent:
|
||||||
|
return "MessageComponent"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("InteractionType(%d)", t)
|
||||||
|
}
|
||||||
|
|
||||||
// Interaction represents data of an interaction.
|
// Interaction represents data of an interaction.
|
||||||
type Interaction struct {
|
type Interaction struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
|
@ -135,12 +172,18 @@ func (i *Interaction) UnmarshalJSON(raw []byte) error {
|
||||||
// MessageComponentData is helper function to assert the inner InteractionData to MessageComponentInteractionData.
|
// MessageComponentData is helper function to assert the inner InteractionData to MessageComponentInteractionData.
|
||||||
// Make sure to check that the Type of the interaction is InteractionMessageComponent before calling.
|
// Make sure to check that the Type of the interaction is InteractionMessageComponent before calling.
|
||||||
func (i Interaction) MessageComponentData() (data MessageComponentInteractionData) {
|
func (i Interaction) MessageComponentData() (data MessageComponentInteractionData) {
|
||||||
|
if i.Type != InteractionMessageComponent {
|
||||||
|
panic("MessageComponentData called on interaction of type " + i.Type.String())
|
||||||
|
}
|
||||||
return i.Data.(MessageComponentInteractionData)
|
return i.Data.(MessageComponentInteractionData)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ApplicationCommandData is helper function to assert the inner InteractionData to ApplicationCommandInteractionData.
|
// ApplicationCommandData is helper function to assert the inner InteractionData to ApplicationCommandInteractionData.
|
||||||
// Make sure to check that the Type of the interaction is InteractionApplicationCommand before calling.
|
// Make sure to check that the Type of the interaction is InteractionApplicationCommand before calling.
|
||||||
func (i Interaction) ApplicationCommandData() (data ApplicationCommandInteractionData) {
|
func (i Interaction) ApplicationCommandData() (data ApplicationCommandInteractionData) {
|
||||||
|
if i.Type != InteractionApplicationCommand {
|
||||||
|
panic("ApplicationCommandData called on interaction of type " + i.Type.String())
|
||||||
|
}
|
||||||
return i.Data.(ApplicationCommandInteractionData)
|
return i.Data.(ApplicationCommandInteractionData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,31 +229,31 @@ func (MessageComponentInteractionData) Type() InteractionType {
|
||||||
// ApplicationCommandInteractionDataOption represents an option of a slash command.
|
// ApplicationCommandInteractionDataOption represents an option of a slash command.
|
||||||
type ApplicationCommandInteractionDataOption struct {
|
type ApplicationCommandInteractionDataOption struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
// NOTE: Contains the value specified by InteractionType.
|
Type ApplicationCommandOptionType `json:"type"`
|
||||||
|
// NOTE: Contains the value specified by Type.
|
||||||
Value interface{} `json:"value,omitempty"`
|
Value interface{} `json:"value,omitempty"`
|
||||||
Options []*ApplicationCommandInteractionDataOption `json:"options,omitempty"`
|
Options []*ApplicationCommandInteractionDataOption `json:"options,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// IntValue is a utility function for casting option value to integer
|
// IntValue is a utility function for casting option value to integer
|
||||||
func (o ApplicationCommandInteractionDataOption) IntValue() int64 {
|
func (o ApplicationCommandInteractionDataOption) IntValue() int64 {
|
||||||
if v, ok := o.Value.(float64); ok {
|
if o.Type != ApplicationCommandOptionInteger {
|
||||||
return int64(v)
|
panic("IntValue called on data option of type " + o.Type.String())
|
||||||
}
|
}
|
||||||
|
return int64(o.Value.(float64))
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UintValue is a utility function for casting option value to unsigned integer
|
// UintValue is a utility function for casting option value to unsigned integer
|
||||||
func (o ApplicationCommandInteractionDataOption) UintValue() uint64 {
|
func (o ApplicationCommandInteractionDataOption) UintValue() uint64 {
|
||||||
if v, ok := o.Value.(float64); ok {
|
if o.Type != ApplicationCommandOptionInteger {
|
||||||
return uint64(v)
|
panic("UintValue called on data option of type " + o.Type.String())
|
||||||
}
|
}
|
||||||
|
return uint64(o.Value.(float64))
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FloatValue is a utility function for casting option value to float
|
// FloatValue is a utility function for casting option value to float
|
||||||
func (o ApplicationCommandInteractionDataOption) FloatValue() float64 {
|
func (o ApplicationCommandInteractionDataOption) FloatValue() float64 {
|
||||||
|
// TODO: limit calls to Number type once it is released
|
||||||
if v, ok := o.Value.(float64); ok {
|
if v, ok := o.Value.(float64); ok {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
@ -220,29 +263,27 @@ func (o ApplicationCommandInteractionDataOption) FloatValue() float64 {
|
||||||
|
|
||||||
// StringValue is a utility function for casting option value to string
|
// StringValue is a utility function for casting option value to string
|
||||||
func (o ApplicationCommandInteractionDataOption) StringValue() string {
|
func (o ApplicationCommandInteractionDataOption) StringValue() string {
|
||||||
if v, ok := o.Value.(string); ok {
|
if o.Type != ApplicationCommandOptionString {
|
||||||
return v
|
panic("StringValue called on data option of type " + o.Type.String())
|
||||||
}
|
}
|
||||||
|
return o.Value.(string)
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// BoolValue is a utility function for casting option value to bool
|
// BoolValue is a utility function for casting option value to bool
|
||||||
func (o ApplicationCommandInteractionDataOption) BoolValue() bool {
|
func (o ApplicationCommandInteractionDataOption) BoolValue() bool {
|
||||||
if v, ok := o.Value.(bool); ok {
|
if o.Type != ApplicationCommandOptionBoolean {
|
||||||
return v
|
panic("BoolValue called on data option of type " + o.Type.String())
|
||||||
}
|
}
|
||||||
|
return o.Value.(bool)
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChannelValue is a utility function for casting option value to channel object.
|
// ChannelValue is a utility function for casting option value to channel object.
|
||||||
// s : Session object, if not nil, function additionally fetches all channel's data
|
// s : Session object, if not nil, function additionally fetches all channel's data
|
||||||
func (o ApplicationCommandInteractionDataOption) ChannelValue(s *Session) *Channel {
|
func (o ApplicationCommandInteractionDataOption) ChannelValue(s *Session) *Channel {
|
||||||
chanID := o.StringValue()
|
if o.Type != ApplicationCommandOptionChannel {
|
||||||
if chanID == "" {
|
panic("ChannelValue called on data option of type " + o.Type.String())
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
chanID := o.Value.(string)
|
||||||
|
|
||||||
if s == nil {
|
if s == nil {
|
||||||
return &Channel{ID: chanID}
|
return &Channel{ID: chanID}
|
||||||
|
@ -262,10 +303,10 @@ func (o ApplicationCommandInteractionDataOption) ChannelValue(s *Session) *Chann
|
||||||
// RoleValue is a utility function for casting option value to role object.
|
// RoleValue is a utility function for casting option value to role object.
|
||||||
// s : Session object, if not nil, function additionally fetches all role's data
|
// s : Session object, if not nil, function additionally fetches all role's data
|
||||||
func (o ApplicationCommandInteractionDataOption) RoleValue(s *Session, gID string) *Role {
|
func (o ApplicationCommandInteractionDataOption) RoleValue(s *Session, gID string) *Role {
|
||||||
roleID := o.StringValue()
|
if o.Type != ApplicationCommandOptionRole && o.Type != ApplicationCommandOptionMentionable {
|
||||||
if roleID == "" {
|
panic("RoleValue called on data option of type " + o.Type.String())
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
roleID := o.Value.(string)
|
||||||
|
|
||||||
if s == nil || gID == "" {
|
if s == nil || gID == "" {
|
||||||
return &Role{ID: roleID}
|
return &Role{ID: roleID}
|
||||||
|
@ -290,10 +331,10 @@ func (o ApplicationCommandInteractionDataOption) RoleValue(s *Session, gID strin
|
||||||
// UserValue is a utility function for casting option value to user object.
|
// UserValue is a utility function for casting option value to user object.
|
||||||
// s : Session object, if not nil, function additionally fetches all user's data
|
// s : Session object, if not nil, function additionally fetches all user's data
|
||||||
func (o ApplicationCommandInteractionDataOption) UserValue(s *Session) *User {
|
func (o ApplicationCommandInteractionDataOption) UserValue(s *Session) *User {
|
||||||
userID := o.StringValue()
|
if o.Type != ApplicationCommandOptionUser && o.Type != ApplicationCommandOptionMentionable {
|
||||||
if userID == "" {
|
panic("UserValue called on data option of type " + o.Type.String())
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
userID := o.Value.(string)
|
||||||
|
|
||||||
if s == nil {
|
if s == nil {
|
||||||
return &User{ID: userID}
|
return &User{ID: userID}
|
||||||
|
|
Loading…
Reference in a new issue