packages feed

discord-haskell 1.11.0 → 1.12.0

raw patch · 23 files changed

+1442/−1304 lines, 23 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Discord.Internal.Rest.Channel: [CreateMessageEmbed] :: ChannelId -> Text -> CreateEmbed -> ChannelRequest Message
- Discord.Internal.Rest.Channel: [messageDetailedEmbed] :: MessageDetailedOpts -> Maybe CreateEmbed
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionTypeBoolean :: ApplicationCommandOptionType
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionTypeChannel :: ApplicationCommandOptionType
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionTypeInteger :: ApplicationCommandOptionType
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionTypeMentionable :: ApplicationCommandOptionType
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionTypeNumber :: ApplicationCommandOptionType
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionTypeRole :: ApplicationCommandOptionType
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionTypeString :: ApplicationCommandOptionType
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionTypeSubcommand :: ApplicationCommandOptionType
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionTypeSubcommandGroup :: ApplicationCommandOptionType
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionTypeUser :: ApplicationCommandOptionType
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandPermissionTypeRole :: ApplicationCommandPermissionType
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandPermissionTypeUser :: ApplicationCommandPermissionType
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandTypeChatInput :: ApplicationCommandType
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandTypeMessage :: ApplicationCommandType
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandTypeUser :: ApplicationCommandType
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandUnknown :: InternalApplicationCommand -> ApplicationCommand
- Discord.Internal.Types.ApplicationCommands: CreateApplicationCommand :: Text -> Text -> Maybe [InternalApplicationCommandOption] -> Maybe Bool -> Maybe ApplicationCommandType -> CreateApplicationCommand
- Discord.Internal.Types.ApplicationCommands: EditApplicationCommand :: Maybe Text -> Maybe Text -> Maybe [InternalApplicationCommandOption] -> Maybe Bool -> Maybe ApplicationCommandType -> EditApplicationCommand
- Discord.Internal.Types.ApplicationCommands: InternalApplicationCommand :: ApplicationCommandId -> Maybe ApplicationCommandType -> ApplicationId -> Maybe GuildId -> Text -> Text -> Maybe [InternalApplicationCommandOption] -> Maybe Bool -> Snowflake -> InternalApplicationCommand
- Discord.Internal.Types.ApplicationCommands: InternalApplicationCommandOption :: ApplicationCommandOptionType -> Text -> Text -> Maybe Bool -> Maybe [InternalApplicationCommandOptionChoice] -> Maybe [InternalApplicationCommandOption] -> Maybe [ApplicationCommandChannelType] -> Maybe Scientific -> Maybe Scientific -> Maybe Bool -> InternalApplicationCommandOption
- Discord.Internal.Types.ApplicationCommands: StringNumberValueInteger :: Integer -> StringNumberValue
- Discord.Internal.Types.ApplicationCommands: StringNumberValueNumber :: Scientific -> StringNumberValue
- Discord.Internal.Types.ApplicationCommands: StringNumberValueString :: Text -> StringNumberValue
- Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionValueAutocomplete] :: ApplicationCommandOptionValue -> Maybe Bool
- Discord.Internal.Types.ApplicationCommands: [createApplicationCommandType] :: CreateApplicationCommand -> Maybe ApplicationCommandType
- Discord.Internal.Types.ApplicationCommands: [editApplicationCommandType] :: EditApplicationCommand -> Maybe ApplicationCommandType
- Discord.Internal.Types.ApplicationCommands: [internalApplicationCommandApplicationId] :: InternalApplicationCommand -> ApplicationId
- Discord.Internal.Types.ApplicationCommands: [internalApplicationCommandDefaultPermission] :: InternalApplicationCommand -> Maybe Bool
- Discord.Internal.Types.ApplicationCommands: [internalApplicationCommandDescription] :: InternalApplicationCommand -> Text
- Discord.Internal.Types.ApplicationCommands: [internalApplicationCommandGuildId] :: InternalApplicationCommand -> Maybe GuildId
- Discord.Internal.Types.ApplicationCommands: [internalApplicationCommandId] :: InternalApplicationCommand -> ApplicationCommandId
- Discord.Internal.Types.ApplicationCommands: [internalApplicationCommandName] :: InternalApplicationCommand -> Text
- Discord.Internal.Types.ApplicationCommands: [internalApplicationCommandOptionAutocomplete] :: InternalApplicationCommandOption -> Maybe Bool
- Discord.Internal.Types.ApplicationCommands: [internalApplicationCommandOptionChannelTypes] :: InternalApplicationCommandOption -> Maybe [ApplicationCommandChannelType]
- Discord.Internal.Types.ApplicationCommands: [internalApplicationCommandOptionChoices] :: InternalApplicationCommandOption -> Maybe [InternalApplicationCommandOptionChoice]
- Discord.Internal.Types.ApplicationCommands: [internalApplicationCommandOptionDescription] :: InternalApplicationCommandOption -> Text
- Discord.Internal.Types.ApplicationCommands: [internalApplicationCommandOptionMaxVal] :: InternalApplicationCommandOption -> Maybe Scientific
- Discord.Internal.Types.ApplicationCommands: [internalApplicationCommandOptionMinVal] :: InternalApplicationCommandOption -> Maybe Scientific
- Discord.Internal.Types.ApplicationCommands: [internalApplicationCommandOptionName] :: InternalApplicationCommandOption -> Text
- Discord.Internal.Types.ApplicationCommands: [internalApplicationCommandOptionOptions] :: InternalApplicationCommandOption -> Maybe [InternalApplicationCommandOption]
- Discord.Internal.Types.ApplicationCommands: [internalApplicationCommandOptionRequired] :: InternalApplicationCommandOption -> Maybe Bool
- Discord.Internal.Types.ApplicationCommands: [internalApplicationCommandOptionType] :: InternalApplicationCommandOption -> ApplicationCommandOptionType
- Discord.Internal.Types.ApplicationCommands: [internalApplicationCommandOptions] :: InternalApplicationCommand -> Maybe [InternalApplicationCommandOption]
- Discord.Internal.Types.ApplicationCommands: [internalApplicationCommandType] :: InternalApplicationCommand -> Maybe ApplicationCommandType
- Discord.Internal.Types.ApplicationCommands: [internalApplicationCommandVersion] :: InternalApplicationCommand -> Snowflake
- Discord.Internal.Types.ApplicationCommands: data ApplicationCommandOptionType
- Discord.Internal.Types.ApplicationCommands: data ApplicationCommandPermissionType
- Discord.Internal.Types.ApplicationCommands: data ApplicationCommandType
- Discord.Internal.Types.ApplicationCommands: data InternalApplicationCommand
- Discord.Internal.Types.ApplicationCommands: data InternalApplicationCommandOption
- Discord.Internal.Types.ApplicationCommands: data StringNumberValue
- Discord.Internal.Types.ApplicationCommands: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptionType
- Discord.Internal.Types.ApplicationCommands: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.ApplicationCommands.ApplicationCommandPermissionType
- Discord.Internal.Types.ApplicationCommands: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.ApplicationCommands.ApplicationCommandType
- Discord.Internal.Types.ApplicationCommands: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.ApplicationCommands.InternalApplicationCommand
- Discord.Internal.Types.ApplicationCommands: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.ApplicationCommands.InternalApplicationCommandOption
- Discord.Internal.Types.ApplicationCommands: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.ApplicationCommands.StringNumberValue
- Discord.Internal.Types.ApplicationCommands: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptionType
- Discord.Internal.Types.ApplicationCommands: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.ApplicationCommands.ApplicationCommandPermissionType
- Discord.Internal.Types.ApplicationCommands: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.ApplicationCommands.ApplicationCommandType
- Discord.Internal.Types.ApplicationCommands: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.ApplicationCommands.InternalApplicationCommandOption
- Discord.Internal.Types.ApplicationCommands: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.ApplicationCommands.StringNumberValue
- Discord.Internal.Types.ApplicationCommands: instance Data.Data.Data Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptionType
- Discord.Internal.Types.ApplicationCommands: instance Data.Data.Data Discord.Internal.Types.ApplicationCommands.ApplicationCommandPermissionType
- Discord.Internal.Types.ApplicationCommands: instance Data.Data.Data Discord.Internal.Types.ApplicationCommands.ApplicationCommandType
- Discord.Internal.Types.ApplicationCommands: instance Data.Default.Class.Default Discord.Internal.Types.ApplicationCommands.EditApplicationCommand
- Discord.Internal.Types.ApplicationCommands: instance Discord.Internal.Types.Prelude.Internals Discord.Internal.Types.ApplicationCommands.ApplicationCommand Discord.Internal.Types.ApplicationCommands.InternalApplicationCommand
- Discord.Internal.Types.ApplicationCommands: instance Discord.Internal.Types.Prelude.Internals Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptionSubcommand Discord.Internal.Types.ApplicationCommands.InternalApplicationCommandOption
- Discord.Internal.Types.ApplicationCommands: instance Discord.Internal.Types.Prelude.Internals Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptionSubcommandOrGroup Discord.Internal.Types.ApplicationCommands.InternalApplicationCommandOption
- Discord.Internal.Types.ApplicationCommands: instance Discord.Internal.Types.Prelude.Internals Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptionValue Discord.Internal.Types.ApplicationCommands.InternalApplicationCommandOption
- Discord.Internal.Types.ApplicationCommands: instance Discord.Internal.Types.Prelude.Internals Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptions [Discord.Internal.Types.ApplicationCommands.InternalApplicationCommandOption]
- Discord.Internal.Types.ApplicationCommands: instance GHC.Classes.Eq Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptionType
- Discord.Internal.Types.ApplicationCommands: instance GHC.Classes.Eq Discord.Internal.Types.ApplicationCommands.ApplicationCommandPermissionType
- Discord.Internal.Types.ApplicationCommands: instance GHC.Classes.Eq Discord.Internal.Types.ApplicationCommands.ApplicationCommandType
- Discord.Internal.Types.ApplicationCommands: instance GHC.Classes.Eq Discord.Internal.Types.ApplicationCommands.InternalApplicationCommand
- Discord.Internal.Types.ApplicationCommands: instance GHC.Classes.Eq Discord.Internal.Types.ApplicationCommands.InternalApplicationCommandOption
- Discord.Internal.Types.ApplicationCommands: instance GHC.Classes.Eq Discord.Internal.Types.ApplicationCommands.StringNumberValue
- Discord.Internal.Types.ApplicationCommands: instance GHC.Classes.Ord Discord.Internal.Types.ApplicationCommands.ApplicationCommandPermissionType
- Discord.Internal.Types.ApplicationCommands: instance GHC.Enum.Enum Discord.Internal.Types.ApplicationCommands.ApplicationCommandChannelType
- Discord.Internal.Types.ApplicationCommands: instance GHC.Enum.Enum Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptionType
- Discord.Internal.Types.ApplicationCommands: instance GHC.Enum.Enum Discord.Internal.Types.ApplicationCommands.ApplicationCommandPermissionType
- Discord.Internal.Types.ApplicationCommands: instance GHC.Enum.Enum Discord.Internal.Types.ApplicationCommands.ApplicationCommandType
- Discord.Internal.Types.ApplicationCommands: instance GHC.Read.Read Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptionType
- Discord.Internal.Types.ApplicationCommands: instance GHC.Read.Read Discord.Internal.Types.ApplicationCommands.ApplicationCommandPermissionType
- Discord.Internal.Types.ApplicationCommands: instance GHC.Read.Read Discord.Internal.Types.ApplicationCommands.ApplicationCommandType
- Discord.Internal.Types.ApplicationCommands: instance GHC.Read.Read Discord.Internal.Types.ApplicationCommands.InternalApplicationCommand
- Discord.Internal.Types.ApplicationCommands: instance GHC.Read.Read Discord.Internal.Types.ApplicationCommands.InternalApplicationCommandOption
- Discord.Internal.Types.ApplicationCommands: instance GHC.Read.Read Discord.Internal.Types.ApplicationCommands.StringNumberValue
- Discord.Internal.Types.ApplicationCommands: instance GHC.Show.Show Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptionType
- Discord.Internal.Types.ApplicationCommands: instance GHC.Show.Show Discord.Internal.Types.ApplicationCommands.ApplicationCommandPermissionType
- Discord.Internal.Types.ApplicationCommands: instance GHC.Show.Show Discord.Internal.Types.ApplicationCommands.ApplicationCommandType
- Discord.Internal.Types.ApplicationCommands: instance GHC.Show.Show Discord.Internal.Types.ApplicationCommands.InternalApplicationCommand
- Discord.Internal.Types.ApplicationCommands: instance GHC.Show.Show Discord.Internal.Types.ApplicationCommands.InternalApplicationCommandOption
- Discord.Internal.Types.ApplicationCommands: instance GHC.Show.Show Discord.Internal.Types.ApplicationCommands.StringNumberValue
- Discord.Internal.Types.ApplicationCommands: type InternalApplicationCommandOptionChoice = Choice StringNumberValue
- Discord.Internal.Types.Channel: instance GHC.Enum.Enum Discord.Internal.Types.Channel.MessageActivityType
- Discord.Internal.Types.Channel: instance GHC.Enum.Enum Discord.Internal.Types.Channel.MessageFlag
- Discord.Internal.Types.Channel: instance GHC.Enum.Enum Discord.Internal.Types.Channel.MessageType
- Discord.Internal.Types.Channel: instance GHC.Enum.Enum Discord.Internal.Types.Channel.StickerFormatType
- Discord.Internal.Types.Components: Component :: ComponentType -> Maybe Text -> Maybe Bool -> Maybe InternalButtonStyle -> Maybe Text -> Maybe Emoji -> Maybe Text -> Maybe [SelectOption] -> Maybe Text -> Maybe Integer -> Maybe Integer -> Maybe [Component] -> Component
- Discord.Internal.Types.Components: ComponentTypeActionRow :: ComponentType
- Discord.Internal.Types.Components: ComponentTypeButton :: ComponentType
- Discord.Internal.Types.Components: ComponentTypeSelectMenu :: ComponentType
- Discord.Internal.Types.Components: InternalButtonStyleDanger :: InternalButtonStyle
- Discord.Internal.Types.Components: InternalButtonStyleLink :: InternalButtonStyle
- Discord.Internal.Types.Components: InternalButtonStylePrimary :: InternalButtonStyle
- Discord.Internal.Types.Components: InternalButtonStyleSecondary :: InternalButtonStyle
- Discord.Internal.Types.Components: InternalButtonStyleSuccess :: InternalButtonStyle
- Discord.Internal.Types.Components: [componentComponents] :: Component -> Maybe [Component]
- Discord.Internal.Types.Components: [componentCustomId] :: Component -> Maybe Text
- Discord.Internal.Types.Components: [componentDisabled] :: Component -> Maybe Bool
- Discord.Internal.Types.Components: [componentEmoji] :: Component -> Maybe Emoji
- Discord.Internal.Types.Components: [componentLabel] :: Component -> Maybe Text
- Discord.Internal.Types.Components: [componentMaxValues] :: Component -> Maybe Integer
- Discord.Internal.Types.Components: [componentMinValues] :: Component -> Maybe Integer
- Discord.Internal.Types.Components: [componentOptions] :: Component -> Maybe [SelectOption]
- Discord.Internal.Types.Components: [componentPlaceholder] :: Component -> Maybe Text
- Discord.Internal.Types.Components: [componentStyle] :: Component -> Maybe InternalButtonStyle
- Discord.Internal.Types.Components: [componentType] :: Component -> ComponentType
- Discord.Internal.Types.Components: [componentUrl] :: Component -> Maybe Text
- Discord.Internal.Types.Components: buttonStyles :: [(ButtonStyle, InternalButtonStyle)]
- Discord.Internal.Types.Components: data Component
- Discord.Internal.Types.Components: data ComponentType
- Discord.Internal.Types.Components: data InternalButtonStyle
- Discord.Internal.Types.Components: filterOutIncorrectEmoji :: Component -> Component
- Discord.Internal.Types.Components: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Components.Component
- Discord.Internal.Types.Components: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Components.ComponentType
- Discord.Internal.Types.Components: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Components.InternalButtonStyle
- Discord.Internal.Types.Components: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Components.Component
- Discord.Internal.Types.Components: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Components.ComponentType
- Discord.Internal.Types.Components: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Components.InternalButtonStyle
- Discord.Internal.Types.Components: instance Data.Data.Data Discord.Internal.Types.Components.ComponentType
- Discord.Internal.Types.Components: instance Data.Data.Data Discord.Internal.Types.Components.InternalButtonStyle
- Discord.Internal.Types.Components: instance Discord.Internal.Types.Prelude.Internals Discord.Internal.Types.Components.ButtonStyle Discord.Internal.Types.Components.InternalButtonStyle
- Discord.Internal.Types.Components: instance Discord.Internal.Types.Prelude.Internals Discord.Internal.Types.Components.ComponentActionRow Discord.Internal.Types.Components.Component
- Discord.Internal.Types.Components: instance GHC.Classes.Eq Discord.Internal.Types.Components.Component
- Discord.Internal.Types.Components: instance GHC.Classes.Eq Discord.Internal.Types.Components.ComponentType
- Discord.Internal.Types.Components: instance GHC.Classes.Eq Discord.Internal.Types.Components.InternalButtonStyle
- Discord.Internal.Types.Components: instance GHC.Classes.Ord Discord.Internal.Types.Components.Component
- Discord.Internal.Types.Components: instance GHC.Classes.Ord Discord.Internal.Types.Components.ComponentType
- Discord.Internal.Types.Components: instance GHC.Classes.Ord Discord.Internal.Types.Components.InternalButtonStyle
- Discord.Internal.Types.Components: instance GHC.Enum.Enum Discord.Internal.Types.Components.ComponentType
- Discord.Internal.Types.Components: instance GHC.Enum.Enum Discord.Internal.Types.Components.InternalButtonStyle
- Discord.Internal.Types.Components: instance GHC.Read.Read Discord.Internal.Types.Components.Component
- Discord.Internal.Types.Components: instance GHC.Read.Read Discord.Internal.Types.Components.ComponentType
- Discord.Internal.Types.Components: instance GHC.Read.Read Discord.Internal.Types.Components.InternalButtonStyle
- Discord.Internal.Types.Components: instance GHC.Show.Show Discord.Internal.Types.Components.Component
- Discord.Internal.Types.Components: instance GHC.Show.Show Discord.Internal.Types.Components.ComponentType
- Discord.Internal.Types.Components: instance GHC.Show.Show Discord.Internal.Types.Components.InternalButtonStyle
- Discord.Internal.Types.Components: validPartialEmoji :: Emoji -> Maybe Emoji
- Discord.Internal.Types.Embed: [embedType] :: Embed -> Maybe Text
- Discord.Internal.Types.Events: instance GHC.Read.Read Discord.Internal.Types.Events.Event
- Discord.Internal.Types.Interactions: ApplicationCommandInteractionDataValueBoolean :: Bool -> ApplicationCommandInteractionDataValue
- Discord.Internal.Types.Interactions: ApplicationCommandInteractionDataValueChannel :: Snowflake -> ApplicationCommandInteractionDataValue
- Discord.Internal.Types.Interactions: ApplicationCommandInteractionDataValueInteger :: Integer -> ApplicationCommandInteractionDataValue
- Discord.Internal.Types.Interactions: ApplicationCommandInteractionDataValueMentionable :: Snowflake -> ApplicationCommandInteractionDataValue
- Discord.Internal.Types.Interactions: ApplicationCommandInteractionDataValueNumber :: Scientific -> ApplicationCommandInteractionDataValue
- Discord.Internal.Types.Interactions: ApplicationCommandInteractionDataValueRole :: Snowflake -> ApplicationCommandInteractionDataValue
- Discord.Internal.Types.Interactions: ApplicationCommandInteractionDataValueString :: Text -> ApplicationCommandInteractionDataValue
- Discord.Internal.Types.Interactions: ApplicationCommandInteractionDataValueUser :: Snowflake -> ApplicationCommandInteractionDataValue
- Discord.Internal.Types.Interactions: InteractionCallbackDataAutocomplete :: InteractionCallbackAutocomplete -> InteractionCallbackData
- Discord.Internal.Types.Interactions: InteractionCallbackDataFlagEphermeral :: InteractionCallbackDataFlag
- Discord.Internal.Types.Interactions: InteractionCallbackDataFlags :: [InteractionCallbackDataFlag] -> InteractionCallbackDataFlags
- Discord.Internal.Types.Interactions: InteractionCallbackDataMessages :: InteractionCallbackMessages -> InteractionCallbackData
- Discord.Internal.Types.Interactions: InteractionCallbackMessages :: Maybe Bool -> Maybe Text -> Maybe [Embed] -> Maybe AllowedMentions -> Maybe InteractionCallbackDataFlags -> Maybe [Component] -> Maybe [Attachment] -> InteractionCallbackMessages
- Discord.Internal.Types.Interactions: InteractionCallbackTypeApplicationCommandAutocompleteResult :: InteractionCallbackType
- Discord.Internal.Types.Interactions: InteractionCallbackTypeChannelMessageWithSource :: InteractionCallbackType
- Discord.Internal.Types.Interactions: InteractionCallbackTypeDeferredChannelMessageWithSource :: InteractionCallbackType
- Discord.Internal.Types.Interactions: InteractionCallbackTypeDeferredUpdateMessage :: InteractionCallbackType
- Discord.Internal.Types.Interactions: InteractionCallbackTypePong :: InteractionCallbackType
- Discord.Internal.Types.Interactions: InteractionCallbackTypeUpdateMessage :: InteractionCallbackType
- Discord.Internal.Types.Interactions: InteractionDataApplicationCommandOptionValue :: Text -> ApplicationCommandInteractionDataValue -> Maybe Bool -> InteractionDataApplicationCommandOptionValue
- Discord.Internal.Types.Interactions: InteractionResponse :: InteractionCallbackType -> Maybe InteractionCallbackData -> InteractionResponse
- Discord.Internal.Types.Interactions: InteractionUnknown :: InternalInteraction -> Interaction
- Discord.Internal.Types.Interactions: InternalInteraction :: InteractionId -> ApplicationId -> InteractionType -> Maybe InternalInteractionData -> Maybe GuildId -> Maybe ChannelId -> Maybe GuildMember -> Maybe User -> InteractionToken -> Int -> Maybe Message -> InternalInteraction
- Discord.Internal.Types.Interactions: InternalInteractionData :: Maybe ApplicationCommandId -> Maybe Text -> Maybe ApplicationCommandType -> Maybe ResolvedData -> Maybe [InternalInteractionDataApplicationCommandOption] -> Maybe Text -> Maybe ComponentType -> Maybe [Text] -> Maybe Snowflake -> InternalInteractionData
- Discord.Internal.Types.Interactions: InternalInteractionDataApplicationCommandOption :: Text -> ApplicationCommandOptionType -> Maybe ApplicationCommandInteractionDataValue -> Maybe [InternalInteractionDataApplicationCommandOption] -> Maybe Bool -> InternalInteractionDataApplicationCommandOption
- Discord.Internal.Types.Interactions: [interactionCallbackMessagesAllowedMentions] :: InteractionCallbackMessages -> Maybe AllowedMentions
- Discord.Internal.Types.Interactions: [interactionCallbackMessagesAttachments] :: InteractionCallbackMessages -> Maybe [Attachment]
- Discord.Internal.Types.Interactions: [interactionCallbackMessagesComponents] :: InteractionCallbackMessages -> Maybe [Component]
- Discord.Internal.Types.Interactions: [interactionCallbackMessagesContent] :: InteractionCallbackMessages -> Maybe Text
- Discord.Internal.Types.Interactions: [interactionCallbackMessagesEmbeds] :: InteractionCallbackMessages -> Maybe [Embed]
- Discord.Internal.Types.Interactions: [interactionCallbackMessagesFlags] :: InteractionCallbackMessages -> Maybe InteractionCallbackDataFlags
- Discord.Internal.Types.Interactions: [interactionCallbackMessagesTTS] :: InteractionCallbackMessages -> Maybe Bool
- Discord.Internal.Types.Interactions: [interactionDataApplicationCommandOptionValueFocused] :: InteractionDataApplicationCommandOptionValue -> Maybe Bool
- Discord.Internal.Types.Interactions: [interactionDataApplicationCommandOptionValueValue] :: InteractionDataApplicationCommandOptionValue -> ApplicationCommandInteractionDataValue
- Discord.Internal.Types.Interactions: [interactionMember] :: Interaction -> Maybe GuildMember
- Discord.Internal.Types.Interactions: [interactionResponseData] :: InteractionResponse -> Maybe InteractionCallbackData
- Discord.Internal.Types.Interactions: [interactionResponseType] :: InteractionResponse -> InteractionCallbackType
- Discord.Internal.Types.Interactions: [internalInteractionApplicationId] :: InternalInteraction -> ApplicationId
- Discord.Internal.Types.Interactions: [internalInteractionChannelId] :: InternalInteraction -> Maybe ChannelId
- Discord.Internal.Types.Interactions: [internalInteractionDataApplicationCommandId] :: InternalInteractionData -> Maybe ApplicationCommandId
- Discord.Internal.Types.Interactions: [internalInteractionDataApplicationCommandName] :: InternalInteractionData -> Maybe Text
- Discord.Internal.Types.Interactions: [internalInteractionDataApplicationCommandOptionFocused] :: InternalInteractionDataApplicationCommandOption -> Maybe Bool
- Discord.Internal.Types.Interactions: [internalInteractionDataApplicationCommandOptionName] :: InternalInteractionDataApplicationCommandOption -> Text
- Discord.Internal.Types.Interactions: [internalInteractionDataApplicationCommandOptionOptions] :: InternalInteractionDataApplicationCommandOption -> Maybe [InternalInteractionDataApplicationCommandOption]
- Discord.Internal.Types.Interactions: [internalInteractionDataApplicationCommandOptionType] :: InternalInteractionDataApplicationCommandOption -> ApplicationCommandOptionType
- Discord.Internal.Types.Interactions: [internalInteractionDataApplicationCommandOptionValue] :: InternalInteractionDataApplicationCommandOption -> Maybe ApplicationCommandInteractionDataValue
- Discord.Internal.Types.Interactions: [internalInteractionDataApplicationCommandType] :: InternalInteractionData -> Maybe ApplicationCommandType
- Discord.Internal.Types.Interactions: [internalInteractionDataComponentType] :: InternalInteractionData -> Maybe ComponentType
- Discord.Internal.Types.Interactions: [internalInteractionDataCustomId] :: InternalInteractionData -> Maybe Text
- Discord.Internal.Types.Interactions: [internalInteractionDataOptions] :: InternalInteractionData -> Maybe [InternalInteractionDataApplicationCommandOption]
- Discord.Internal.Types.Interactions: [internalInteractionDataResolved] :: InternalInteractionData -> Maybe ResolvedData
- Discord.Internal.Types.Interactions: [internalInteractionDataTargetId] :: InternalInteractionData -> Maybe Snowflake
- Discord.Internal.Types.Interactions: [internalInteractionDataValues] :: InternalInteractionData -> Maybe [Text]
- Discord.Internal.Types.Interactions: [internalInteractionData] :: InternalInteraction -> Maybe InternalInteractionData
- Discord.Internal.Types.Interactions: [internalInteractionGuildId] :: InternalInteraction -> Maybe GuildId
- Discord.Internal.Types.Interactions: [internalInteractionId] :: InternalInteraction -> InteractionId
- Discord.Internal.Types.Interactions: [internalInteractionMember] :: InternalInteraction -> Maybe GuildMember
- Discord.Internal.Types.Interactions: [internalInteractionMessage] :: InternalInteraction -> Maybe Message
- Discord.Internal.Types.Interactions: [internalInteractionToken] :: InternalInteraction -> InteractionToken
- Discord.Internal.Types.Interactions: [internalInteractionType] :: InternalInteraction -> InteractionType
- Discord.Internal.Types.Interactions: [internalInteractionUser] :: InternalInteraction -> Maybe User
- Discord.Internal.Types.Interactions: [internalInteractionVersion] :: InternalInteraction -> Int
- Discord.Internal.Types.Interactions: data ApplicationCommandInteractionDataValue
- Discord.Internal.Types.Interactions: data InteractionCallbackData
- Discord.Internal.Types.Interactions: data InteractionCallbackDataFlag
- Discord.Internal.Types.Interactions: data InteractionCallbackMessages
- Discord.Internal.Types.Interactions: data InteractionCallbackType
- Discord.Internal.Types.Interactions: data InteractionType
- Discord.Internal.Types.Interactions: data InternalInteraction
- Discord.Internal.Types.Interactions: data InternalInteractionData
- Discord.Internal.Types.Interactions: data InternalInteractionDataApplicationCommandOption
- Discord.Internal.Types.Interactions: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Interactions.InternalInteraction
- Discord.Internal.Types.Interactions: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Interactions.InternalInteractionData
- Discord.Internal.Types.Interactions: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Interactions.InternalInteractionDataApplicationCommandOption
- Discord.Internal.Types.Interactions: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Interactions.ApplicationCommandInteractionDataValue
- Discord.Internal.Types.Interactions: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Interactions.InteractionCallbackData
- Discord.Internal.Types.Interactions: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Interactions.InteractionCallbackDataFlags
- Discord.Internal.Types.Interactions: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Interactions.InteractionCallbackMessages
- Discord.Internal.Types.Interactions: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Interactions.InteractionCallbackType
- Discord.Internal.Types.Interactions: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Interactions.InternalInteraction
- Discord.Internal.Types.Interactions: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Interactions.InternalInteractionData
- Discord.Internal.Types.Interactions: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Interactions.InternalInteractionDataApplicationCommandOption
- Discord.Internal.Types.Interactions: instance Data.Data.Data Discord.Internal.Types.Interactions.InteractionCallbackType
- Discord.Internal.Types.Interactions: instance Discord.Internal.Types.Prelude.Internals Discord.Internal.Types.Interactions.Interaction Discord.Internal.Types.Interactions.InternalInteraction
- Discord.Internal.Types.Interactions: instance Discord.Internal.Types.Prelude.Internals Discord.Internal.Types.Interactions.InteractionDataApplicationCommand Discord.Internal.Types.Interactions.InternalInteractionData
- Discord.Internal.Types.Interactions: instance Discord.Internal.Types.Prelude.Internals Discord.Internal.Types.Interactions.InteractionDataApplicationCommandOptionSubcommand Discord.Internal.Types.Interactions.InternalInteractionDataApplicationCommandOption
- Discord.Internal.Types.Interactions: instance Discord.Internal.Types.Prelude.Internals Discord.Internal.Types.Interactions.InteractionDataApplicationCommandOptionSubcommandOrGroup Discord.Internal.Types.Interactions.InternalInteractionDataApplicationCommandOption
- Discord.Internal.Types.Interactions: instance Discord.Internal.Types.Prelude.Internals Discord.Internal.Types.Interactions.InteractionDataApplicationCommandOptionValue Discord.Internal.Types.Interactions.InternalInteractionDataApplicationCommandOption
- Discord.Internal.Types.Interactions: instance Discord.Internal.Types.Prelude.Internals Discord.Internal.Types.Interactions.InteractionDataApplicationCommandOptions [Discord.Internal.Types.Interactions.InternalInteractionDataApplicationCommandOption]
- Discord.Internal.Types.Interactions: instance Discord.Internal.Types.Prelude.Internals Discord.Internal.Types.Interactions.InteractionDataComponent Discord.Internal.Types.Interactions.InternalInteractionData
- Discord.Internal.Types.Interactions: instance GHC.Classes.Eq Discord.Internal.Types.Interactions.ApplicationCommandInteractionDataValue
- Discord.Internal.Types.Interactions: instance GHC.Classes.Eq Discord.Internal.Types.Interactions.InteractionCallbackData
- Discord.Internal.Types.Interactions: instance GHC.Classes.Eq Discord.Internal.Types.Interactions.InteractionCallbackDataFlag
- Discord.Internal.Types.Interactions: instance GHC.Classes.Eq Discord.Internal.Types.Interactions.InteractionCallbackDataFlags
- Discord.Internal.Types.Interactions: instance GHC.Classes.Eq Discord.Internal.Types.Interactions.InteractionCallbackMessages
- Discord.Internal.Types.Interactions: instance GHC.Classes.Eq Discord.Internal.Types.Interactions.InteractionCallbackType
- Discord.Internal.Types.Interactions: instance GHC.Classes.Eq Discord.Internal.Types.Interactions.InteractionResponse
- Discord.Internal.Types.Interactions: instance GHC.Classes.Eq Discord.Internal.Types.Interactions.InternalInteraction
- Discord.Internal.Types.Interactions: instance GHC.Classes.Eq Discord.Internal.Types.Interactions.InternalInteractionData
- Discord.Internal.Types.Interactions: instance GHC.Classes.Eq Discord.Internal.Types.Interactions.InternalInteractionDataApplicationCommandOption
- Discord.Internal.Types.Interactions: instance GHC.Classes.Ord Discord.Internal.Types.Interactions.ApplicationCommandInteractionDataValue
- Discord.Internal.Types.Interactions: instance GHC.Enum.Enum Discord.Internal.Types.Interactions.InteractionCallbackDataFlag
- Discord.Internal.Types.Interactions: instance GHC.Enum.Enum Discord.Internal.Types.Interactions.InteractionCallbackType
- Discord.Internal.Types.Interactions: instance GHC.Read.Read Discord.Internal.Types.Interactions.ApplicationCommandInteractionDataValue
- Discord.Internal.Types.Interactions: instance GHC.Read.Read Discord.Internal.Types.Interactions.InteractionCallbackData
- Discord.Internal.Types.Interactions: instance GHC.Read.Read Discord.Internal.Types.Interactions.InteractionCallbackDataFlag
- Discord.Internal.Types.Interactions: instance GHC.Read.Read Discord.Internal.Types.Interactions.InteractionCallbackDataFlags
- Discord.Internal.Types.Interactions: instance GHC.Read.Read Discord.Internal.Types.Interactions.InteractionCallbackMessages
- Discord.Internal.Types.Interactions: instance GHC.Read.Read Discord.Internal.Types.Interactions.InteractionCallbackType
- Discord.Internal.Types.Interactions: instance GHC.Read.Read Discord.Internal.Types.Interactions.InteractionResponse
- Discord.Internal.Types.Interactions: instance GHC.Read.Read Discord.Internal.Types.Interactions.InternalInteraction
- Discord.Internal.Types.Interactions: instance GHC.Read.Read Discord.Internal.Types.Interactions.InternalInteractionData
- Discord.Internal.Types.Interactions: instance GHC.Read.Read Discord.Internal.Types.Interactions.InternalInteractionDataApplicationCommandOption
- Discord.Internal.Types.Interactions: instance GHC.Show.Show Discord.Internal.Types.Interactions.ApplicationCommandInteractionDataValue
- Discord.Internal.Types.Interactions: instance GHC.Show.Show Discord.Internal.Types.Interactions.InteractionCallbackData
- Discord.Internal.Types.Interactions: instance GHC.Show.Show Discord.Internal.Types.Interactions.InteractionCallbackDataFlag
- Discord.Internal.Types.Interactions: instance GHC.Show.Show Discord.Internal.Types.Interactions.InteractionCallbackDataFlags
- Discord.Internal.Types.Interactions: instance GHC.Show.Show Discord.Internal.Types.Interactions.InteractionCallbackMessages
- Discord.Internal.Types.Interactions: instance GHC.Show.Show Discord.Internal.Types.Interactions.InteractionCallbackType
- Discord.Internal.Types.Interactions: instance GHC.Show.Show Discord.Internal.Types.Interactions.InteractionResponse
- Discord.Internal.Types.Interactions: instance GHC.Show.Show Discord.Internal.Types.Interactions.InternalInteraction
- Discord.Internal.Types.Interactions: instance GHC.Show.Show Discord.Internal.Types.Interactions.InternalInteractionData
- Discord.Internal.Types.Interactions: instance GHC.Show.Show Discord.Internal.Types.Interactions.InternalInteractionDataApplicationCommandOption
- Discord.Internal.Types.Interactions: interactionCallbackMessagesBasic :: Text -> InteractionCallbackMessages
- Discord.Internal.Types.Interactions: newtype InteractionCallbackDataFlags
- Discord.Internal.Types.Interactions: type InteractionCallbackAutocomplete = [InternalApplicationCommandOptionChoice]
- Discord.Internal.Types.Prelude: InteractionTypeApplicationCommand :: InteractionType
- Discord.Internal.Types.Prelude: InteractionTypeApplicationCommandAutocomplete :: InteractionType
- Discord.Internal.Types.Prelude: InteractionTypeMessageComponent :: InteractionType
- Discord.Internal.Types.Prelude: InteractionTypePing :: InteractionType
- Discord.Internal.Types.Prelude: class Internals a b
- Discord.Internal.Types.Prelude: data Auth
- Discord.Internal.Types.Prelude: data InteractionType
- Discord.Internal.Types.Prelude: fromInternal :: Internals a b => b -> Maybe a
- Discord.Internal.Types.Prelude: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Prelude.InteractionType
- Discord.Internal.Types.Prelude: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Prelude.InteractionType
- Discord.Internal.Types.Prelude: instance Data.Data.Data Discord.Internal.Types.Prelude.InteractionType
- Discord.Internal.Types.Prelude: instance Discord.Internal.Types.Prelude.Internals a a
- Discord.Internal.Types.Prelude: instance GHC.Classes.Eq Discord.Internal.Types.Prelude.InteractionType
- Discord.Internal.Types.Prelude: instance GHC.Classes.Ord Discord.Internal.Types.Prelude.InteractionType
- Discord.Internal.Types.Prelude: instance GHC.Enum.Enum Discord.Internal.Types.Prelude.InteractionType
- Discord.Internal.Types.Prelude: instance GHC.Read.Read Discord.Internal.Types.Prelude.InteractionType
- Discord.Internal.Types.Prelude: instance GHC.Show.Show Discord.Internal.Types.Prelude.InteractionType
- Discord.Internal.Types.Prelude: makeTable :: (Data t, Enum t) => t -> [(Int, t)]
- Discord.Internal.Types.Prelude: toInternal :: Internals a b => a -> b
- Discord.Internal.Types.Prelude: type ColorInteger = Integer
- Discord.Types: Component :: ComponentType -> Maybe Text -> Maybe Bool -> Maybe InternalButtonStyle -> Maybe Text -> Maybe Emoji -> Maybe Text -> Maybe [SelectOption] -> Maybe Text -> Maybe Integer -> Maybe Integer -> Maybe [Component] -> Component
- Discord.Types: ComponentTypeActionRow :: ComponentType
- Discord.Types: ComponentTypeButton :: ComponentType
- Discord.Types: ComponentTypeSelectMenu :: ComponentType
- Discord.Types: InteractionTypeApplicationCommand :: InteractionType
- Discord.Types: InteractionTypeApplicationCommandAutocomplete :: InteractionType
- Discord.Types: InteractionTypeMessageComponent :: InteractionType
- Discord.Types: InteractionTypePing :: InteractionType
- Discord.Types: InternalButtonStyleDanger :: InternalButtonStyle
- Discord.Types: InternalButtonStyleLink :: InternalButtonStyle
- Discord.Types: InternalButtonStylePrimary :: InternalButtonStyle
- Discord.Types: InternalButtonStyleSecondary :: InternalButtonStyle
- Discord.Types: InternalButtonStyleSuccess :: InternalButtonStyle
- Discord.Types: [componentComponents] :: Component -> Maybe [Component]
- Discord.Types: [componentCustomId] :: Component -> Maybe Text
- Discord.Types: [componentDisabled] :: Component -> Maybe Bool
- Discord.Types: [componentEmoji] :: Component -> Maybe Emoji
- Discord.Types: [componentLabel] :: Component -> Maybe Text
- Discord.Types: [componentMaxValues] :: Component -> Maybe Integer
- Discord.Types: [componentMinValues] :: Component -> Maybe Integer
- Discord.Types: [componentOptions] :: Component -> Maybe [SelectOption]
- Discord.Types: [componentPlaceholder] :: Component -> Maybe Text
- Discord.Types: [componentStyle] :: Component -> Maybe InternalButtonStyle
- Discord.Types: [componentType] :: Component -> ComponentType
- Discord.Types: [componentUrl] :: Component -> Maybe Text
- Discord.Types: [embedType] :: Embed -> Maybe Text
- Discord.Types: buttonStyles :: [(ButtonStyle, InternalButtonStyle)]
- Discord.Types: class Internals a b
- Discord.Types: data Auth
- Discord.Types: data Component
- Discord.Types: data ComponentType
- Discord.Types: data InteractionType
- Discord.Types: data InternalButtonStyle
- Discord.Types: filterOutIncorrectEmoji :: Component -> Component
- Discord.Types: fromInternal :: Internals a b => b -> Maybe a
- Discord.Types: makeTable :: (Data t, Enum t) => t -> [(Int, t)]
- Discord.Types: toInternal :: Internals a b => a -> b
- Discord.Types: type ColorInteger = Integer
- Discord.Types: validPartialEmoji :: Emoji -> Maybe Emoji
+ Discord.Internal.Rest.Channel: [messageDetailedEmbeds] :: MessageDetailedOpts -> Maybe [CreateEmbed]
+ Discord.Internal.Types: class ToJSON a
+ Discord.Internal.Types: toJSON :: ToJSON a => a -> Value
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionsSubcommands :: [ApplicationCommandOptionSubcommandOrGroup] -> ApplicationCommandOptions
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionsValues :: [ApplicationCommandOptionValue] -> ApplicationCommandOptions
+ Discord.Internal.Types.ApplicationCommands: CreateApplicationCommandChatInput :: Text -> Text -> Maybe ApplicationCommandOptions -> Bool -> CreateApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: CreateApplicationCommandMessage :: Text -> Bool -> CreateApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: CreateApplicationCommandUser :: Text -> Bool -> CreateApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: EditApplicationCommandChatInput :: Maybe Text -> Maybe Text -> Maybe ApplicationCommandOptions -> Maybe Bool -> EditApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: EditApplicationCommandMessage :: Maybe Text -> Maybe Bool -> EditApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: EditApplicationCommandUser :: Maybe Text -> Maybe Bool -> EditApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: data ApplicationCommandOptions
+ Discord.Internal.Types.ApplicationCommands: defaultEditApplicationCommand :: Int -> EditApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.ApplicationCommands.ApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptionSubcommand
+ Discord.Internal.Types.ApplicationCommands: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptionSubcommandOrGroup
+ Discord.Internal.Types.ApplicationCommands: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptionValue
+ Discord.Internal.Types.ApplicationCommands: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptions
+ Discord.Internal.Types.ApplicationCommands: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Discord.Internal.Types.ApplicationCommands.AutocompleteOrChoice a)
+ Discord.Internal.Types.ApplicationCommands: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptionSubcommand
+ Discord.Internal.Types.ApplicationCommands: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptionSubcommandOrGroup
+ Discord.Internal.Types.ApplicationCommands: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptionValue
+ Discord.Internal.Types.ApplicationCommands: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptions
+ Discord.Internal.Types.ApplicationCommands: instance Discord.Internal.Types.Prelude.InternalDiscordEnum Discord.Internal.Types.ApplicationCommands.ApplicationCommandChannelType
+ Discord.Internal.Types.Channel: instance Discord.Internal.Types.Prelude.InternalDiscordEnum Discord.Internal.Types.Channel.MessageActivityType
+ Discord.Internal.Types.Channel: instance Discord.Internal.Types.Prelude.InternalDiscordEnum Discord.Internal.Types.Channel.MessageFlag
+ Discord.Internal.Types.Channel: instance Discord.Internal.Types.Prelude.InternalDiscordEnum Discord.Internal.Types.Channel.MessageType
+ Discord.Internal.Types.Channel: instance Discord.Internal.Types.Prelude.InternalDiscordEnum Discord.Internal.Types.Channel.StickerFormatType
+ Discord.Internal.Types.Color: DiscordColorAqua :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorBlue :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorDarkAqua :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorDarkBlue :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorDarkGold :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorDarkGray :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorDarkGreen :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorDarkNavy :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorDarkOrange :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorDarkPurple :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorDarkRed :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorDarkVividPink :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorDarkerGray :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorDefault :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorDiscordBlack :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorDiscordBlurple :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorDiscordDarkButNotBlack :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorDiscordFuschia :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorDiscordGrayple :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorDiscordGreen :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorDiscordNotQuiteBlack :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorDiscordRed :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorDiscordWhite :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorDiscordYellow :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorGold :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorGray :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorGreen :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorLightGray :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorLuminousVividPink :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorNavy :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorOrange :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorPurple :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorRGB :: Integer -> Integer -> Integer -> DiscordColor
+ Discord.Internal.Types.Color: DiscordColorRed :: DiscordColor
+ Discord.Internal.Types.Color: DiscordColorYellow :: DiscordColor
+ Discord.Internal.Types.Color: colorToInternal :: DiscordColor -> Integer
+ Discord.Internal.Types.Color: convertToRGB :: Integer -> DiscordColor
+ Discord.Internal.Types.Color: data DiscordColor
+ Discord.Internal.Types.Color: hexToDiscordColor :: String -> DiscordColor
+ Discord.Internal.Types.Color: hexToRGB :: String -> Maybe (Integer, Integer, Integer)
+ Discord.Internal.Types.Color: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Color.DiscordColor
+ Discord.Internal.Types.Color: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Color.DiscordColor
+ Discord.Internal.Types.Color: instance Data.Data.Data Discord.Internal.Types.Color.DiscordColor
+ Discord.Internal.Types.Color: instance Discord.Internal.Types.Prelude.InternalDiscordEnum Discord.Internal.Types.Color.DiscordColor
+ Discord.Internal.Types.Color: instance GHC.Classes.Eq Discord.Internal.Types.Color.DiscordColor
+ Discord.Internal.Types.Color: instance GHC.Classes.Ord Discord.Internal.Types.Color.DiscordColor
+ Discord.Internal.Types.Color: instance GHC.Read.Read Discord.Internal.Types.Color.DiscordColor
+ Discord.Internal.Types.Color: instance GHC.Show.Show Discord.Internal.Types.Color.DiscordColor
+ Discord.Internal.Types.Components: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Components.ButtonStyle
+ Discord.Internal.Types.Components: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Components.ComponentActionRow
+ Discord.Internal.Types.Components: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Components.ComponentButton
+ Discord.Internal.Types.Components: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Components.ComponentSelectMenu
+ Discord.Internal.Types.Components: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Components.ButtonStyle
+ Discord.Internal.Types.Components: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Components.ComponentActionRow
+ Discord.Internal.Types.Components: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Components.ComponentButton
+ Discord.Internal.Types.Components: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Components.ComponentSelectMenu
+ Discord.Internal.Types.Components: instance GHC.Classes.Ord Discord.Internal.Types.Components.ButtonStyle
+ Discord.Internal.Types.Components: instance GHC.Classes.Ord Discord.Internal.Types.Components.ComponentActionRow
+ Discord.Internal.Types.Components: instance GHC.Classes.Ord Discord.Internal.Types.Components.ComponentButton
+ Discord.Internal.Types.Components: instance GHC.Classes.Ord Discord.Internal.Types.Components.ComponentSelectMenu
+ Discord.Internal.Types.Components: instance GHC.Read.Read Discord.Internal.Types.Components.ComponentActionRow
+ Discord.Internal.Types.Components: instance GHC.Read.Read Discord.Internal.Types.Components.ComponentButton
+ Discord.Internal.Types.Components: mkButton :: Text -> Text -> ComponentButton
+ Discord.Internal.Types.Components: mkEmoji :: Text -> Emoji
+ Discord.Internal.Types.Components: mkSelectMenu :: Text -> [SelectOption] -> ComponentSelectMenu
+ Discord.Internal.Types.Components: mkSelectOption :: Text -> Text -> SelectOption
+ Discord.Internal.Types.Embed: [createEmbedTimestamp] :: CreateEmbed -> Maybe UTCTime
+ Discord.Internal.Types.Embed: [embedProxyUrl] :: EmbedVideo -> Maybe Text
+ Discord.Internal.Types.Embed: maybeEmbed :: Maybe CreateEmbed -> [PartM IO]
+ Discord.Internal.Types.Interactions: InteractionDataApplicationCommandOptionValueBoolean :: Text -> Bool -> InteractionDataApplicationCommandOptionValue
+ Discord.Internal.Types.Interactions: InteractionDataApplicationCommandOptionValueChannel :: Text -> ChannelId -> InteractionDataApplicationCommandOptionValue
+ Discord.Internal.Types.Interactions: InteractionDataApplicationCommandOptionValueInteger :: Text -> Either Text Integer -> InteractionDataApplicationCommandOptionValue
+ Discord.Internal.Types.Interactions: InteractionDataApplicationCommandOptionValueMentionable :: Text -> Snowflake -> InteractionDataApplicationCommandOptionValue
+ Discord.Internal.Types.Interactions: InteractionDataApplicationCommandOptionValueNumber :: Text -> Either Text Scientific -> InteractionDataApplicationCommandOptionValue
+ Discord.Internal.Types.Interactions: InteractionDataApplicationCommandOptionValueRole :: Text -> RoleId -> InteractionDataApplicationCommandOptionValue
+ Discord.Internal.Types.Interactions: InteractionDataApplicationCommandOptionValueString :: Text -> Either Text Text -> InteractionDataApplicationCommandOptionValue
+ Discord.Internal.Types.Interactions: InteractionDataApplicationCommandOptionValueUser :: Text -> UserId -> InteractionDataApplicationCommandOptionValue
+ Discord.Internal.Types.Interactions: InteractionResponseAutocompleteInteger :: [Choice Integer] -> InteractionResponseAutocomplete
+ Discord.Internal.Types.Interactions: InteractionResponseAutocompleteNumber :: [Choice Scientific] -> InteractionResponseAutocomplete
+ Discord.Internal.Types.Interactions: InteractionResponseAutocompleteResult :: InteractionResponseAutocomplete -> InteractionResponse
+ Discord.Internal.Types.Interactions: InteractionResponseAutocompleteString :: [Choice Text] -> InteractionResponseAutocomplete
+ Discord.Internal.Types.Interactions: InteractionResponseChannelMessage :: InteractionResponseMessage -> InteractionResponse
+ Discord.Internal.Types.Interactions: InteractionResponseDeferChannelMessage :: InteractionResponse
+ Discord.Internal.Types.Interactions: InteractionResponseDeferUpdateMessage :: InteractionResponse
+ Discord.Internal.Types.Interactions: InteractionResponseMessage :: Maybe Bool -> Maybe Text -> Maybe [CreateEmbed] -> Maybe AllowedMentions -> Maybe InteractionResponseMessageFlags -> Maybe [ComponentActionRow] -> Maybe [Attachment] -> InteractionResponseMessage
+ Discord.Internal.Types.Interactions: InteractionResponseMessageFlagEphermeral :: InteractionResponseMessageFlag
+ Discord.Internal.Types.Interactions: InteractionResponseMessageFlags :: [InteractionResponseMessageFlag] -> InteractionResponseMessageFlags
+ Discord.Internal.Types.Interactions: InteractionResponsePong :: InteractionResponse
+ Discord.Internal.Types.Interactions: InteractionResponseUpdateMessage :: InteractionResponseMessage -> InteractionResponse
+ Discord.Internal.Types.Interactions: MemberOrUser :: Either GuildMember User -> MemberOrUser
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommandOptionValueBooleanValue] :: InteractionDataApplicationCommandOptionValue -> Bool
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommandOptionValueChannelValue] :: InteractionDataApplicationCommandOptionValue -> ChannelId
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommandOptionValueIntegerValue] :: InteractionDataApplicationCommandOptionValue -> Either Text Integer
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommandOptionValueMentionableValue] :: InteractionDataApplicationCommandOptionValue -> Snowflake
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommandOptionValueNumberValue] :: InteractionDataApplicationCommandOptionValue -> Either Text Scientific
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommandOptionValueRoleValue] :: InteractionDataApplicationCommandOptionValue -> RoleId
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommandOptionValueStringValue] :: InteractionDataApplicationCommandOptionValue -> Either Text Text
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommandOptionValueUserValue] :: InteractionDataApplicationCommandOptionValue -> UserId
+ Discord.Internal.Types.Interactions: [interactionGuildLocale] :: Interaction -> Maybe Text
+ Discord.Internal.Types.Interactions: [interactionLocale] :: Interaction -> Text
+ Discord.Internal.Types.Interactions: [interactionResponseMessageAllowedMentions] :: InteractionResponseMessage -> Maybe AllowedMentions
+ Discord.Internal.Types.Interactions: [interactionResponseMessageAttachments] :: InteractionResponseMessage -> Maybe [Attachment]
+ Discord.Internal.Types.Interactions: [interactionResponseMessageComponents] :: InteractionResponseMessage -> Maybe [ComponentActionRow]
+ Discord.Internal.Types.Interactions: [interactionResponseMessageContent] :: InteractionResponseMessage -> Maybe Text
+ Discord.Internal.Types.Interactions: [interactionResponseMessageEmbeds] :: InteractionResponseMessage -> Maybe [CreateEmbed]
+ Discord.Internal.Types.Interactions: [interactionResponseMessageFlags] :: InteractionResponseMessage -> Maybe InteractionResponseMessageFlags
+ Discord.Internal.Types.Interactions: [interactionResponseMessageTTS] :: InteractionResponseMessage -> Maybe Bool
+ Discord.Internal.Types.Interactions: data InteractionResponseAutocomplete
+ Discord.Internal.Types.Interactions: data InteractionResponseMessage
+ Discord.Internal.Types.Interactions: data InteractionResponseMessageFlag
+ Discord.Internal.Types.Interactions: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Interactions.Interaction
+ Discord.Internal.Types.Interactions: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Interactions.InteractionDataApplicationCommand
+ Discord.Internal.Types.Interactions: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Interactions.InteractionDataApplicationCommandOptionSubcommand
+ Discord.Internal.Types.Interactions: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Interactions.InteractionDataApplicationCommandOptionSubcommandOrGroup
+ Discord.Internal.Types.Interactions: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Interactions.InteractionDataApplicationCommandOptionValue
+ Discord.Internal.Types.Interactions: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Interactions.InteractionDataApplicationCommandOptions
+ Discord.Internal.Types.Interactions: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Interactions.InteractionDataComponent
+ Discord.Internal.Types.Interactions: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Interactions.MemberOrUser
+ Discord.Internal.Types.Interactions: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Interactions.InteractionResponseAutocomplete
+ Discord.Internal.Types.Interactions: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Interactions.InteractionResponseMessage
+ Discord.Internal.Types.Interactions: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Interactions.InteractionResponseMessageFlags
+ Discord.Internal.Types.Interactions: instance GHC.Classes.Eq Discord.Internal.Types.Interactions.InteractionResponseAutocomplete
+ Discord.Internal.Types.Interactions: instance GHC.Classes.Eq Discord.Internal.Types.Interactions.InteractionResponseMessage
+ Discord.Internal.Types.Interactions: instance GHC.Classes.Eq Discord.Internal.Types.Interactions.InteractionResponseMessageFlag
+ Discord.Internal.Types.Interactions: instance GHC.Classes.Eq Discord.Internal.Types.Interactions.InteractionResponseMessageFlags
+ Discord.Internal.Types.Interactions: instance GHC.Classes.Eq Discord.Internal.Types.Interactions.MemberOrUser
+ Discord.Internal.Types.Interactions: instance GHC.Enum.Enum Discord.Internal.Types.Interactions.InteractionResponseMessageFlag
+ Discord.Internal.Types.Interactions: instance GHC.Read.Read Discord.Internal.Types.Interactions.InteractionResponseMessageFlag
+ Discord.Internal.Types.Interactions: instance GHC.Read.Read Discord.Internal.Types.Interactions.InteractionResponseMessageFlags
+ Discord.Internal.Types.Interactions: instance GHC.Read.Read Discord.Internal.Types.Interactions.MemberOrUser
+ Discord.Internal.Types.Interactions: instance GHC.Show.Show Discord.Internal.Types.Interactions.InteractionResponseAutocomplete
+ Discord.Internal.Types.Interactions: instance GHC.Show.Show Discord.Internal.Types.Interactions.InteractionResponseMessage
+ Discord.Internal.Types.Interactions: instance GHC.Show.Show Discord.Internal.Types.Interactions.InteractionResponseMessageFlag
+ Discord.Internal.Types.Interactions: instance GHC.Show.Show Discord.Internal.Types.Interactions.InteractionResponseMessageFlags
+ Discord.Internal.Types.Interactions: instance GHC.Show.Show Discord.Internal.Types.Interactions.MemberOrUser
+ Discord.Internal.Types.Interactions: interactionResponseMessageBasic :: Text -> InteractionResponseMessage
+ Discord.Internal.Types.Interactions: newtype InteractionResponseMessageFlags
+ Discord.Internal.Types.Interactions: newtype MemberOrUser
+ Discord.Internal.Types.Prelude: class Data a => InternalDiscordEnum a
+ Discord.Internal.Types.Prelude: discordTypeParseJSON :: InternalDiscordEnum a => String -> Value -> Parser a
+ Discord.Internal.Types.Prelude: discordTypeStartValue :: InternalDiscordEnum a => a
+ Discord.Internal.Types.Prelude: discordTypeTable :: InternalDiscordEnum a => [(Int, a)]
+ Discord.Internal.Types.Prelude: fromDiscordType :: InternalDiscordEnum a => a -> Int
+ Discord.Internal.Types.Prelude: newtype Auth
+ Discord.Types: DiscordColorAqua :: DiscordColor
+ Discord.Types: DiscordColorBlue :: DiscordColor
+ Discord.Types: DiscordColorDarkAqua :: DiscordColor
+ Discord.Types: DiscordColorDarkBlue :: DiscordColor
+ Discord.Types: DiscordColorDarkGold :: DiscordColor
+ Discord.Types: DiscordColorDarkGray :: DiscordColor
+ Discord.Types: DiscordColorDarkGreen :: DiscordColor
+ Discord.Types: DiscordColorDarkNavy :: DiscordColor
+ Discord.Types: DiscordColorDarkOrange :: DiscordColor
+ Discord.Types: DiscordColorDarkPurple :: DiscordColor
+ Discord.Types: DiscordColorDarkRed :: DiscordColor
+ Discord.Types: DiscordColorDarkVividPink :: DiscordColor
+ Discord.Types: DiscordColorDarkerGray :: DiscordColor
+ Discord.Types: DiscordColorDefault :: DiscordColor
+ Discord.Types: DiscordColorDiscordBlack :: DiscordColor
+ Discord.Types: DiscordColorDiscordBlurple :: DiscordColor
+ Discord.Types: DiscordColorDiscordDarkButNotBlack :: DiscordColor
+ Discord.Types: DiscordColorDiscordFuschia :: DiscordColor
+ Discord.Types: DiscordColorDiscordGrayple :: DiscordColor
+ Discord.Types: DiscordColorDiscordGreen :: DiscordColor
+ Discord.Types: DiscordColorDiscordNotQuiteBlack :: DiscordColor
+ Discord.Types: DiscordColorDiscordRed :: DiscordColor
+ Discord.Types: DiscordColorDiscordWhite :: DiscordColor
+ Discord.Types: DiscordColorDiscordYellow :: DiscordColor
+ Discord.Types: DiscordColorGold :: DiscordColor
+ Discord.Types: DiscordColorGray :: DiscordColor
+ Discord.Types: DiscordColorGreen :: DiscordColor
+ Discord.Types: DiscordColorLightGray :: DiscordColor
+ Discord.Types: DiscordColorLuminousVividPink :: DiscordColor
+ Discord.Types: DiscordColorNavy :: DiscordColor
+ Discord.Types: DiscordColorOrange :: DiscordColor
+ Discord.Types: DiscordColorPurple :: DiscordColor
+ Discord.Types: DiscordColorRGB :: Integer -> Integer -> Integer -> DiscordColor
+ Discord.Types: DiscordColorRed :: DiscordColor
+ Discord.Types: DiscordColorYellow :: DiscordColor
+ Discord.Types: [createEmbedTimestamp] :: CreateEmbed -> Maybe UTCTime
+ Discord.Types: [embedProxyUrl] :: EmbedVideo -> Maybe Text
+ Discord.Types: class ToJSON a
+ Discord.Types: data DiscordColor
+ Discord.Types: hexToDiscordColor :: String -> DiscordColor
+ Discord.Types: maybeEmbed :: Maybe CreateEmbed -> [PartM IO]
+ Discord.Types: mkButton :: Text -> Text -> ComponentButton
+ Discord.Types: mkEmoji :: Text -> Emoji
+ Discord.Types: mkSelectMenu :: Text -> [SelectOption] -> ComponentSelectMenu
+ Discord.Types: mkSelectOption :: Text -> Text -> SelectOption
+ Discord.Types: newtype Auth
+ Discord.Types: toJSON :: ToJSON a => a -> Value
- Discord.Internal.Rest.ApplicationCommands: [CreateGlobalApplicationCommand] :: ApplicationId -> CreateApplicationCommand -> ApplicationCommandRequest InternalApplicationCommand
+ Discord.Internal.Rest.ApplicationCommands: [CreateGlobalApplicationCommand] :: ApplicationId -> CreateApplicationCommand -> ApplicationCommandRequest ApplicationCommand
- Discord.Internal.Rest.ApplicationCommands: [CreateGuildApplicationCommand] :: ApplicationId -> GuildId -> CreateApplicationCommand -> ApplicationCommandRequest InternalApplicationCommand
+ Discord.Internal.Rest.ApplicationCommands: [CreateGuildApplicationCommand] :: ApplicationId -> GuildId -> CreateApplicationCommand -> ApplicationCommandRequest ApplicationCommand
- Discord.Internal.Rest.ApplicationCommands: [EditGlobalApplicationCommand] :: ApplicationId -> ApplicationCommandId -> EditApplicationCommand -> ApplicationCommandRequest InternalApplicationCommand
+ Discord.Internal.Rest.ApplicationCommands: [EditGlobalApplicationCommand] :: ApplicationId -> ApplicationCommandId -> EditApplicationCommand -> ApplicationCommandRequest ApplicationCommand
- Discord.Internal.Rest.ApplicationCommands: [EditGuildApplicationCommand] :: ApplicationId -> GuildId -> ApplicationCommandId -> CreateApplicationCommand -> ApplicationCommandRequest InternalApplicationCommand
+ Discord.Internal.Rest.ApplicationCommands: [EditGuildApplicationCommand] :: ApplicationId -> GuildId -> ApplicationCommandId -> CreateApplicationCommand -> ApplicationCommandRequest ApplicationCommand
- Discord.Internal.Rest.ApplicationCommands: [GetGlobalApplicationCommand] :: ApplicationId -> ApplicationCommandId -> ApplicationCommandRequest InternalApplicationCommand
+ Discord.Internal.Rest.ApplicationCommands: [GetGlobalApplicationCommand] :: ApplicationId -> ApplicationCommandId -> ApplicationCommandRequest ApplicationCommand
- Discord.Internal.Rest.ApplicationCommands: [GetGlobalApplicationCommands] :: ApplicationId -> ApplicationCommandRequest [InternalApplicationCommand]
+ Discord.Internal.Rest.ApplicationCommands: [GetGlobalApplicationCommands] :: ApplicationId -> ApplicationCommandRequest [ApplicationCommand]
- Discord.Internal.Rest.ApplicationCommands: [GetGuildApplicationCommand] :: ApplicationId -> GuildId -> ApplicationCommandId -> ApplicationCommandRequest InternalApplicationCommand
+ Discord.Internal.Rest.ApplicationCommands: [GetGuildApplicationCommand] :: ApplicationId -> GuildId -> ApplicationCommandId -> ApplicationCommandRequest ApplicationCommand
- Discord.Internal.Rest.ApplicationCommands: [GetGuildApplicationCommands] :: ApplicationId -> GuildId -> ApplicationCommandRequest [InternalApplicationCommand]
+ Discord.Internal.Rest.ApplicationCommands: [GetGuildApplicationCommands] :: ApplicationId -> GuildId -> ApplicationCommandRequest [ApplicationCommand]
- Discord.Internal.Rest.Channel: MessageDetailedOpts :: Text -> Bool -> Maybe CreateEmbed -> Maybe (Text, ByteString) -> Maybe AllowedMentions -> Maybe MessageReference -> Maybe [Component] -> Maybe [StickerId] -> MessageDetailedOpts
+ Discord.Internal.Rest.Channel: MessageDetailedOpts :: Text -> Bool -> Maybe [CreateEmbed] -> Maybe (Text, ByteString) -> Maybe AllowedMentions -> Maybe MessageReference -> Maybe [ComponentActionRow] -> Maybe [StickerId] -> MessageDetailedOpts
- Discord.Internal.Rest.Channel: [messageDetailedComponents] :: MessageDetailedOpts -> Maybe [Component]
+ Discord.Internal.Rest.Channel: [messageDetailedComponents] :: MessageDetailedOpts -> Maybe [ComponentActionRow]
- Discord.Internal.Rest.Guild: ModifyGuildRoleOpts :: Maybe Text -> Maybe Text -> Maybe ColorInteger -> Maybe Bool -> Maybe Bool -> ModifyGuildRoleOpts
+ Discord.Internal.Rest.Guild: ModifyGuildRoleOpts :: Maybe Text -> Maybe Text -> Maybe DiscordColor -> Maybe Bool -> Maybe Bool -> ModifyGuildRoleOpts
- Discord.Internal.Rest.Guild: [modifyGuildRoleOptsColor] :: ModifyGuildRoleOpts -> Maybe ColorInteger
+ Discord.Internal.Rest.Guild: [modifyGuildRoleOptsColor] :: ModifyGuildRoleOpts -> Maybe DiscordColor
- Discord.Internal.Rest.Interactions: [CreateFollowupInteractionMessage] :: ApplicationId -> InteractionToken -> InteractionCallbackMessages -> InteractionResponseRequest Message
+ Discord.Internal.Rest.Interactions: [CreateFollowupInteractionMessage] :: ApplicationId -> InteractionToken -> InteractionResponseMessage -> InteractionResponseRequest Message
- Discord.Internal.Rest.Interactions: [EditOriginalInteractionResponse] :: ApplicationId -> InteractionToken -> InteractionCallbackMessages -> InteractionResponseRequest Message
+ Discord.Internal.Rest.Interactions: [EditOriginalInteractionResponse] :: ApplicationId -> InteractionToken -> InteractionResponseMessage -> InteractionResponseRequest Message
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandChatInput :: ApplicationCommandId -> ApplicationId -> Maybe GuildId -> Text -> Text -> Maybe ApplicationCommandOptions -> Maybe Bool -> Snowflake -> ApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandChatInput :: ApplicationCommandId -> ApplicationId -> Maybe GuildId -> Text -> Text -> Maybe ApplicationCommandOptions -> Bool -> Snowflake -> ApplicationCommand
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandMessage :: ApplicationCommandId -> ApplicationId -> Maybe GuildId -> Text -> Maybe Bool -> Snowflake -> ApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandMessage :: ApplicationCommandId -> ApplicationId -> Maybe GuildId -> Text -> Bool -> Snowflake -> ApplicationCommand
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionValueBoolean :: Text -> Text -> Maybe Bool -> ApplicationCommandOptionValue
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionValueBoolean :: Text -> Text -> Bool -> ApplicationCommandOptionValue
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionValueChannel :: Text -> Text -> Maybe Bool -> Maybe [ApplicationCommandChannelType] -> ApplicationCommandOptionValue
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionValueChannel :: Text -> Text -> Bool -> Maybe [ApplicationCommandChannelType] -> ApplicationCommandOptionValue
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionValueInteger :: Text -> Text -> Maybe Bool -> Maybe [Choice Integer] -> Maybe Integer -> Maybe Integer -> Maybe Bool -> ApplicationCommandOptionValue
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionValueInteger :: Text -> Text -> Bool -> AutocompleteOrChoice Integer -> Maybe Integer -> Maybe Integer -> ApplicationCommandOptionValue
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionValueMentionable :: Text -> Text -> Maybe Bool -> ApplicationCommandOptionValue
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionValueMentionable :: Text -> Text -> Bool -> ApplicationCommandOptionValue
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionValueNumber :: Text -> Text -> Maybe Bool -> Maybe [Choice Scientific] -> Maybe Scientific -> Maybe Scientific -> Maybe Bool -> ApplicationCommandOptionValue
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionValueNumber :: Text -> Text -> Bool -> AutocompleteOrChoice Scientific -> Maybe Scientific -> Maybe Scientific -> ApplicationCommandOptionValue
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionValueRole :: Text -> Text -> Maybe Bool -> ApplicationCommandOptionValue
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionValueRole :: Text -> Text -> Bool -> ApplicationCommandOptionValue
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionValueString :: Text -> Text -> Maybe Bool -> Maybe [Choice Text] -> Maybe Bool -> ApplicationCommandOptionValue
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionValueString :: Text -> Text -> Bool -> AutocompleteOrChoice Text -> ApplicationCommandOptionValue
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionValueUser :: Text -> Text -> Maybe Bool -> ApplicationCommandOptionValue
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionValueUser :: Text -> Text -> Bool -> ApplicationCommandOptionValue
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandPermissions :: Snowflake -> ApplicationCommandPermissionType -> Bool -> ApplicationCommandPermissions
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandPermissions :: Snowflake -> Integer -> Bool -> ApplicationCommandPermissions
- Discord.Internal.Types.ApplicationCommands: ApplicationCommandUser :: ApplicationCommandId -> ApplicationId -> Maybe GuildId -> Text -> Maybe Bool -> Snowflake -> ApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandUser :: ApplicationCommandId -> ApplicationId -> Maybe GuildId -> Text -> Bool -> Snowflake -> ApplicationCommand
- Discord.Internal.Types.ApplicationCommands: [applicationCommandDefaultPermission] :: ApplicationCommand -> Maybe Bool
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandDefaultPermission] :: ApplicationCommand -> Bool
- Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionValueIntegerChoices] :: ApplicationCommandOptionValue -> Maybe [Choice Integer]
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionValueIntegerChoices] :: ApplicationCommandOptionValue -> AutocompleteOrChoice Integer
- Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionValueNumberChoices] :: ApplicationCommandOptionValue -> Maybe [Choice Scientific]
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionValueNumberChoices] :: ApplicationCommandOptionValue -> AutocompleteOrChoice Scientific
- Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionValueRequired] :: ApplicationCommandOptionValue -> Maybe Bool
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionValueRequired] :: ApplicationCommandOptionValue -> Bool
- Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionValueStringChoices] :: ApplicationCommandOptionValue -> Maybe [Choice Text]
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionValueStringChoices] :: ApplicationCommandOptionValue -> AutocompleteOrChoice Text
- Discord.Internal.Types.ApplicationCommands: [applicationCommandPermissionsType] :: ApplicationCommandPermissions -> ApplicationCommandPermissionType
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandPermissionsType] :: ApplicationCommandPermissions -> Integer
- Discord.Internal.Types.ApplicationCommands: [createApplicationCommandDefaultPermission] :: CreateApplicationCommand -> Maybe Bool
+ Discord.Internal.Types.ApplicationCommands: [createApplicationCommandDefaultPermission] :: CreateApplicationCommand -> Bool
- Discord.Internal.Types.ApplicationCommands: [createApplicationCommandOptions] :: CreateApplicationCommand -> Maybe [InternalApplicationCommandOption]
+ Discord.Internal.Types.ApplicationCommands: [createApplicationCommandOptions] :: CreateApplicationCommand -> Maybe ApplicationCommandOptions
- Discord.Internal.Types.ApplicationCommands: [editApplicationCommandOptions] :: EditApplicationCommand -> Maybe [InternalApplicationCommandOption]
+ Discord.Internal.Types.ApplicationCommands: [editApplicationCommandOptions] :: EditApplicationCommand -> Maybe ApplicationCommandOptions
- Discord.Internal.Types.Channel: Message :: MessageId -> ChannelId -> Maybe GuildId -> User -> Maybe GuildMember -> Text -> UTCTime -> Maybe UTCTime -> Bool -> Bool -> [User] -> [RoleId] -> [Attachment] -> [Embed] -> [MessageReaction] -> Maybe Nonce -> Bool -> Maybe WebhookId -> MessageType -> Maybe MessageActivity -> Maybe ApplicationId -> Maybe MessageReference -> Maybe MessageFlags -> Maybe Message -> Maybe MessageInteraction -> Maybe Channel -> Maybe [Component] -> Maybe [StickerItem] -> Message
+ Discord.Internal.Types.Channel: Message :: MessageId -> ChannelId -> Maybe GuildId -> User -> Maybe GuildMember -> Text -> UTCTime -> Maybe UTCTime -> Bool -> Bool -> [User] -> [RoleId] -> [Attachment] -> [Embed] -> [MessageReaction] -> Maybe Nonce -> Bool -> Maybe WebhookId -> MessageType -> Maybe MessageActivity -> Maybe ApplicationId -> Maybe MessageReference -> Maybe MessageFlags -> Maybe Message -> Maybe MessageInteraction -> Maybe Channel -> Maybe [ComponentActionRow] -> Maybe [StickerItem] -> Message
- Discord.Internal.Types.Channel: MessageInteraction :: InteractionId -> InteractionType -> Text -> User -> MessageInteraction
+ Discord.Internal.Types.Channel: MessageInteraction :: InteractionId -> Integer -> Text -> User -> MessageInteraction
- Discord.Internal.Types.Channel: [messageComponents] :: Message -> Maybe [Component]
+ Discord.Internal.Types.Channel: [messageComponents] :: Message -> Maybe [ComponentActionRow]
- Discord.Internal.Types.Channel: [messageInteractionType] :: MessageInteraction -> InteractionType
+ Discord.Internal.Types.Channel: [messageInteractionType] :: MessageInteraction -> Integer
- Discord.Internal.Types.Components: ComponentButtonUrl :: Url 'Https -> Bool -> Text -> Maybe Emoji -> ComponentButton
+ Discord.Internal.Types.Components: ComponentButtonUrl :: Text -> Bool -> Text -> Maybe Emoji -> ComponentButton
- Discord.Internal.Types.Components: [componentButtonUrl] :: ComponentButton -> Url 'Https
+ Discord.Internal.Types.Components: [componentButtonUrl] :: ComponentButton -> Text
- Discord.Internal.Types.Embed: CreateEmbed :: Text -> Text -> Maybe CreateEmbedImage -> Text -> Text -> Maybe CreateEmbedImage -> Text -> [EmbedField] -> Maybe CreateEmbedImage -> Text -> Maybe CreateEmbedImage -> Maybe ColorInteger -> CreateEmbed
+ Discord.Internal.Types.Embed: CreateEmbed :: Text -> Text -> Maybe CreateEmbedImage -> Text -> Text -> Maybe CreateEmbedImage -> Text -> [EmbedField] -> Maybe CreateEmbedImage -> Text -> Maybe CreateEmbedImage -> Maybe DiscordColor -> Maybe UTCTime -> CreateEmbed
- Discord.Internal.Types.Embed: Embed :: Maybe EmbedAuthor -> Maybe Text -> Maybe Text -> Maybe EmbedThumbnail -> Maybe Text -> [EmbedField] -> Maybe EmbedImage -> Maybe EmbedFooter -> Maybe ColorInteger -> Maybe UTCTime -> Maybe Text -> Maybe EmbedVideo -> Maybe EmbedProvider -> Embed
+ Discord.Internal.Types.Embed: Embed :: Maybe EmbedAuthor -> Maybe Text -> Maybe Text -> Maybe EmbedThumbnail -> Maybe Text -> [EmbedField] -> Maybe EmbedImage -> Maybe EmbedFooter -> Maybe DiscordColor -> Maybe UTCTime -> Maybe EmbedVideo -> Maybe EmbedProvider -> Embed
- Discord.Internal.Types.Embed: EmbedAuthor :: Maybe Text -> Maybe Text -> Maybe Text -> Maybe Text -> EmbedAuthor
+ Discord.Internal.Types.Embed: EmbedAuthor :: Text -> Maybe Text -> Maybe Text -> Maybe Text -> EmbedAuthor
- Discord.Internal.Types.Embed: EmbedImage :: Maybe Text -> Maybe Text -> Maybe Integer -> Maybe Integer -> EmbedImage
+ Discord.Internal.Types.Embed: EmbedImage :: Text -> Maybe Text -> Maybe Integer -> Maybe Integer -> EmbedImage
- Discord.Internal.Types.Embed: EmbedThumbnail :: Maybe Text -> Maybe Text -> Maybe Integer -> Maybe Integer -> EmbedThumbnail
+ Discord.Internal.Types.Embed: EmbedThumbnail :: Text -> Maybe Text -> Maybe Integer -> Maybe Integer -> EmbedThumbnail
- Discord.Internal.Types.Embed: EmbedVideo :: Maybe Text -> Maybe Integer -> Maybe Integer -> EmbedVideo
+ Discord.Internal.Types.Embed: EmbedVideo :: Maybe Text -> Maybe Text -> Maybe Integer -> Maybe Integer -> EmbedVideo
- Discord.Internal.Types.Embed: [createEmbedColor] :: CreateEmbed -> Maybe ColorInteger
+ Discord.Internal.Types.Embed: [createEmbedColor] :: CreateEmbed -> Maybe DiscordColor
- Discord.Internal.Types.Embed: [embedAuthorName] :: EmbedAuthor -> Maybe Text
+ Discord.Internal.Types.Embed: [embedAuthorName] :: EmbedAuthor -> Text
- Discord.Internal.Types.Embed: [embedColor] :: Embed -> Maybe ColorInteger
+ Discord.Internal.Types.Embed: [embedColor] :: Embed -> Maybe DiscordColor
- Discord.Internal.Types.Embed: [embedImageUrl] :: EmbedImage -> Maybe Text
+ Discord.Internal.Types.Embed: [embedImageUrl] :: EmbedImage -> Text
- Discord.Internal.Types.Embed: [embedThumbnailUrl] :: EmbedThumbnail -> Maybe Text
+ Discord.Internal.Types.Embed: [embedThumbnailUrl] :: EmbedThumbnail -> Text
- Discord.Internal.Types.Events: InternalInteractionCreate :: InternalInteraction -> EventInternalParse
+ Discord.Internal.Types.Events: InternalInteractionCreate :: Interaction -> EventInternalParse
- Discord.Internal.Types.Guild: Role :: RoleId -> Text -> ColorInteger -> Bool -> Integer -> Text -> Bool -> Bool -> Role
+ Discord.Internal.Types.Guild: Role :: RoleId -> Text -> DiscordColor -> Bool -> Integer -> Text -> Bool -> Bool -> Role
- Discord.Internal.Types.Guild: [roleColor] :: Role -> ColorInteger
+ Discord.Internal.Types.Guild: [roleColor] :: Role -> DiscordColor
- Discord.Internal.Types.Interactions: InteractionApplicationCommand :: InteractionId -> ApplicationId -> Maybe InteractionDataApplicationCommand -> Maybe GuildId -> Maybe ChannelId -> Maybe GuildMember -> Maybe User -> InteractionToken -> Int -> Interaction
+ Discord.Internal.Types.Interactions: InteractionApplicationCommand :: InteractionId -> ApplicationId -> InteractionDataApplicationCommand -> Maybe GuildId -> Maybe ChannelId -> MemberOrUser -> InteractionToken -> Int -> Text -> Maybe Text -> Interaction
- Discord.Internal.Types.Interactions: InteractionApplicationCommandAutocomplete :: InteractionId -> ApplicationId -> Maybe InteractionDataApplicationCommand -> Maybe GuildId -> Maybe ChannelId -> Maybe GuildMember -> Maybe User -> InteractionToken -> Int -> Interaction
+ Discord.Internal.Types.Interactions: InteractionApplicationCommandAutocomplete :: InteractionId -> ApplicationId -> InteractionDataApplicationCommand -> Maybe GuildId -> Maybe ChannelId -> MemberOrUser -> InteractionToken -> Int -> Text -> Maybe Text -> Interaction
- Discord.Internal.Types.Interactions: InteractionComponent :: InteractionId -> ApplicationId -> Maybe InteractionDataComponent -> Maybe GuildId -> Maybe ChannelId -> Maybe GuildMember -> Maybe User -> InteractionToken -> Int -> Message -> Interaction
+ Discord.Internal.Types.Interactions: InteractionComponent :: InteractionId -> ApplicationId -> InteractionDataComponent -> Maybe GuildId -> Maybe ChannelId -> MemberOrUser -> InteractionToken -> Int -> Message -> Text -> Maybe Text -> Interaction
- Discord.Internal.Types.Interactions: InteractionDataApplicationCommandOptionSubcommand :: Text -> [InteractionDataApplicationCommandOptionValue] -> Maybe Bool -> InteractionDataApplicationCommandOptionSubcommand
+ Discord.Internal.Types.Interactions: InteractionDataApplicationCommandOptionSubcommand :: Text -> [InteractionDataApplicationCommandOptionValue] -> Bool -> InteractionDataApplicationCommandOptionSubcommand
- Discord.Internal.Types.Interactions: InteractionDataApplicationCommandOptionSubcommandGroup :: Text -> [InteractionDataApplicationCommandOptionSubcommand] -> Maybe Bool -> InteractionDataApplicationCommandOptionSubcommandOrGroup
+ Discord.Internal.Types.Interactions: InteractionDataApplicationCommandOptionSubcommandGroup :: Text -> [InteractionDataApplicationCommandOptionSubcommand] -> Bool -> InteractionDataApplicationCommandOptionSubcommandOrGroup
- Discord.Internal.Types.Interactions: [interactionDataApplicationCommandOptionSubcommandFocused] :: InteractionDataApplicationCommandOptionSubcommand -> Maybe Bool
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommandOptionSubcommandFocused] :: InteractionDataApplicationCommandOptionSubcommand -> Bool
- Discord.Internal.Types.Interactions: [interactionDataApplicationCommandOptionSubcommandGroupFocused] :: InteractionDataApplicationCommandOptionSubcommandOrGroup -> Maybe Bool
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommandOptionSubcommandGroupFocused] :: InteractionDataApplicationCommandOptionSubcommandOrGroup -> Bool
- Discord.Internal.Types.Interactions: [interactionDataApplicationCommand] :: Interaction -> Maybe InteractionDataApplicationCommand
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommand] :: Interaction -> InteractionDataApplicationCommand
- Discord.Internal.Types.Interactions: [interactionDataComponent] :: Interaction -> Maybe InteractionDataComponent
+ Discord.Internal.Types.Interactions: [interactionDataComponent] :: Interaction -> InteractionDataComponent
- Discord.Internal.Types.Interactions: [interactionUser] :: Interaction -> Maybe User
+ Discord.Internal.Types.Interactions: [interactionUser] :: Interaction -> MemberOrUser
- Discord.Types: ComponentButtonUrl :: Url 'Https -> Bool -> Text -> Maybe Emoji -> ComponentButton
+ Discord.Types: ComponentButtonUrl :: Text -> Bool -> Text -> Maybe Emoji -> ComponentButton
- Discord.Types: CreateEmbed :: Text -> Text -> Maybe CreateEmbedImage -> Text -> Text -> Maybe CreateEmbedImage -> Text -> [EmbedField] -> Maybe CreateEmbedImage -> Text -> Maybe CreateEmbedImage -> Maybe ColorInteger -> CreateEmbed
+ Discord.Types: CreateEmbed :: Text -> Text -> Maybe CreateEmbedImage -> Text -> Text -> Maybe CreateEmbedImage -> Text -> [EmbedField] -> Maybe CreateEmbedImage -> Text -> Maybe CreateEmbedImage -> Maybe DiscordColor -> Maybe UTCTime -> CreateEmbed
- Discord.Types: Embed :: Maybe EmbedAuthor -> Maybe Text -> Maybe Text -> Maybe EmbedThumbnail -> Maybe Text -> [EmbedField] -> Maybe EmbedImage -> Maybe EmbedFooter -> Maybe ColorInteger -> Maybe UTCTime -> Maybe Text -> Maybe EmbedVideo -> Maybe EmbedProvider -> Embed
+ Discord.Types: Embed :: Maybe EmbedAuthor -> Maybe Text -> Maybe Text -> Maybe EmbedThumbnail -> Maybe Text -> [EmbedField] -> Maybe EmbedImage -> Maybe EmbedFooter -> Maybe DiscordColor -> Maybe UTCTime -> Maybe EmbedVideo -> Maybe EmbedProvider -> Embed
- Discord.Types: EmbedAuthor :: Maybe Text -> Maybe Text -> Maybe Text -> Maybe Text -> EmbedAuthor
+ Discord.Types: EmbedAuthor :: Text -> Maybe Text -> Maybe Text -> Maybe Text -> EmbedAuthor
- Discord.Types: EmbedImage :: Maybe Text -> Maybe Text -> Maybe Integer -> Maybe Integer -> EmbedImage
+ Discord.Types: EmbedImage :: Text -> Maybe Text -> Maybe Integer -> Maybe Integer -> EmbedImage
- Discord.Types: EmbedThumbnail :: Maybe Text -> Maybe Text -> Maybe Integer -> Maybe Integer -> EmbedThumbnail
+ Discord.Types: EmbedThumbnail :: Text -> Maybe Text -> Maybe Integer -> Maybe Integer -> EmbedThumbnail
- Discord.Types: EmbedVideo :: Maybe Text -> Maybe Integer -> Maybe Integer -> EmbedVideo
+ Discord.Types: EmbedVideo :: Maybe Text -> Maybe Text -> Maybe Integer -> Maybe Integer -> EmbedVideo
- Discord.Types: Message :: MessageId -> ChannelId -> Maybe GuildId -> User -> Maybe GuildMember -> Text -> UTCTime -> Maybe UTCTime -> Bool -> Bool -> [User] -> [RoleId] -> [Attachment] -> [Embed] -> [MessageReaction] -> Maybe Nonce -> Bool -> Maybe WebhookId -> MessageType -> Maybe MessageActivity -> Maybe ApplicationId -> Maybe MessageReference -> Maybe MessageFlags -> Maybe Message -> Maybe MessageInteraction -> Maybe Channel -> Maybe [Component] -> Maybe [StickerItem] -> Message
+ Discord.Types: Message :: MessageId -> ChannelId -> Maybe GuildId -> User -> Maybe GuildMember -> Text -> UTCTime -> Maybe UTCTime -> Bool -> Bool -> [User] -> [RoleId] -> [Attachment] -> [Embed] -> [MessageReaction] -> Maybe Nonce -> Bool -> Maybe WebhookId -> MessageType -> Maybe MessageActivity -> Maybe ApplicationId -> Maybe MessageReference -> Maybe MessageFlags -> Maybe Message -> Maybe MessageInteraction -> Maybe Channel -> Maybe [ComponentActionRow] -> Maybe [StickerItem] -> Message
- Discord.Types: MessageInteraction :: InteractionId -> InteractionType -> Text -> User -> MessageInteraction
+ Discord.Types: MessageInteraction :: InteractionId -> Integer -> Text -> User -> MessageInteraction
- Discord.Types: Role :: RoleId -> Text -> ColorInteger -> Bool -> Integer -> Text -> Bool -> Bool -> Role
+ Discord.Types: Role :: RoleId -> Text -> DiscordColor -> Bool -> Integer -> Text -> Bool -> Bool -> Role
- Discord.Types: [componentButtonUrl] :: ComponentButton -> Url 'Https
+ Discord.Types: [componentButtonUrl] :: ComponentButton -> Text
- Discord.Types: [createEmbedColor] :: CreateEmbed -> Maybe ColorInteger
+ Discord.Types: [createEmbedColor] :: CreateEmbed -> Maybe DiscordColor
- Discord.Types: [embedAuthorName] :: EmbedAuthor -> Maybe Text
+ Discord.Types: [embedAuthorName] :: EmbedAuthor -> Text
- Discord.Types: [embedColor] :: Embed -> Maybe ColorInteger
+ Discord.Types: [embedColor] :: Embed -> Maybe DiscordColor
- Discord.Types: [embedImageUrl] :: EmbedImage -> Maybe Text
+ Discord.Types: [embedImageUrl] :: EmbedImage -> Text
- Discord.Types: [embedThumbnailUrl] :: EmbedThumbnail -> Maybe Text
+ Discord.Types: [embedThumbnailUrl] :: EmbedThumbnail -> Text
- Discord.Types: [messageComponents] :: Message -> Maybe [Component]
+ Discord.Types: [messageComponents] :: Message -> Maybe [ComponentActionRow]
- Discord.Types: [messageInteractionType] :: MessageInteraction -> InteractionType
+ Discord.Types: [messageInteractionType] :: MessageInteraction -> Integer
- Discord.Types: [roleColor] :: Role -> ColorInteger
+ Discord.Types: [roleColor] :: Role -> DiscordColor

Files

changelog.md view
@@ -6,6 +6,10 @@  ## master +## 1.12.0++[L0neGamer](https://github.com/aquarial/discord-haskell/pull/96) breaking changes and fixes to application commands, interactions, and components, and updates elsewhere+ ## 1.11.0  [L0neGamer](https://github.com/aquarial/discord-haskell/pull/88) did a LOT of work wrangling the discord API for interactions and commands!
discord-haskell.cabal view
@@ -1,7 +1,7 @@ cabal-version:       2.0 name:                discord-haskell -- library version is also noted at src/Discord/Rest/Prelude.hs-version:             1.11.0+version:             1.12.0 description:         Functions and data types to write discord bots.                      Official discord docs <https://discord.com/developers/docs/reference>.                      .@@ -34,8 +34,19 @@                      , text                      , unliftio                      , discord-haskell-                     -- , req               {- needed for slash commands -} +-- executable interaction-commands+--   main-is:             examples/interaction-commands.hs+--   default-language:    Haskell2010+--   ghc-options:         -Wall+--                        -fno-warn-type-defaults -fno-warn-unused-record-wildcards+--                        -threaded+--   build-depends:       base+--                      , text+--                      , unliftio+--                      , discord-haskell+--                      , bytestring+ library   ghc-options:         -Wall                        -fno-warn-type-defaults -fno-warn-unused-record-wildcards@@ -73,6 +84,7 @@                      , Discord.Internal.Types.ApplicationCommands                      , Discord.Internal.Types.Interactions                      , Discord.Internal.Types.Components+                     , Discord.Internal.Types.Color   build-depends:                        base >= 4 && <5                      , aeson
examples/ping-pong.hs view
@@ -23,7 +23,7 @@ --                                <server id>           <channel id> -- https://discord.com/channels/2385235298674262408/4286572469284672046 testserverid :: Snowflake-testserverid = 453207241294610442+testserverid = -1  -- | Replies "pong" to every message that starts with "ping" pingpongExample :: IO ()
src/Discord/Interactions.hs view
@@ -1,7 +1,8 @@ module Discord.Interactions-  ( module Discord.Internal.Types.ApplicationCommands-  , module Discord.Internal.Types.Interactions-  ) where+  ( module Discord.Internal.Types.ApplicationCommands,+    module Discord.Internal.Types.Interactions,+  )+where  import Discord.Internal.Types.ApplicationCommands import Discord.Internal.Types.Interactions
src/Discord/Internal/Gateway/Cache.hs view
@@ -54,9 +54,6 @@  adjustCache :: Cache -> EventInternalParse -> Cache adjustCache minfo event = case event of-  --InternalChannelCreate Channel-  --InternalChannelUpdate Channel-  --InternalChannelDelete Channel   InternalGuildCreate guild info ->     let newChans = map (setChanGuildID (guildId guild)) $ guildChannels info         g = M.insert (guildId guild) (guild, info { guildChannels = newChans }) (cacheGuilds minfo)
src/Discord/Internal/Rest.hs view
@@ -44,7 +44,7 @@   r <- readMVar m   pure $ case eitherDecode <$> r of     Right (Right o) -> Right o-    (Right (Left er)) -> Left (RestCallInternalNoParse er (case r of +    (Right (Left er)) -> Left (RestCallInternalNoParse er (case r of       Right x -> x       Left _ -> ""))     Left e -> Left e
src/Discord/Internal/Rest/ApplicationCommands.hs view
@@ -1,35 +1,36 @@ {-# LANGUAGE DataKinds #-}-{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TypeApplications #-}  module Discord.Internal.Rest.ApplicationCommands where -import Data.Aeson (ToJSON (toJSON), Value)-import Network.HTTP.Req as R-+import Data.Aeson (Value) import Discord.Internal.Rest.Prelude import Discord.Internal.Types import Discord.Internal.Types.ApplicationCommands-+    ( ApplicationCommandPermissions,+      GuildApplicationCommandPermissions(GuildApplicationCommandPermissions),+      EditApplicationCommand,+      CreateApplicationCommand,+      ApplicationCommand )+import Network.HTTP.Req as R  instance Request (ApplicationCommandRequest a) where   jsonRequest = applicationCommandJsonRequest   majorRoute = applicationCommandMajorRoute  data ApplicationCommandRequest a where-  GetGlobalApplicationCommands :: ApplicationId -> ApplicationCommandRequest [InternalApplicationCommand]-  CreateGlobalApplicationCommand :: ApplicationId -> CreateApplicationCommand -> ApplicationCommandRequest InternalApplicationCommand-  GetGlobalApplicationCommand :: ApplicationId -> ApplicationCommandId -> ApplicationCommandRequest InternalApplicationCommand-  EditGlobalApplicationCommand :: ApplicationId -> ApplicationCommandId -> EditApplicationCommand -> ApplicationCommandRequest InternalApplicationCommand+  GetGlobalApplicationCommands :: ApplicationId -> ApplicationCommandRequest [ApplicationCommand]+  CreateGlobalApplicationCommand :: ApplicationId -> CreateApplicationCommand -> ApplicationCommandRequest ApplicationCommand+  GetGlobalApplicationCommand :: ApplicationId -> ApplicationCommandId -> ApplicationCommandRequest ApplicationCommand+  EditGlobalApplicationCommand :: ApplicationId -> ApplicationCommandId -> EditApplicationCommand -> ApplicationCommandRequest ApplicationCommand   DeleteGlobalApplicationCommand :: ApplicationId -> ApplicationCommandId -> ApplicationCommandRequest ()   BulkOverWriteGlobalApplicationCommand :: ApplicationId -> [CreateApplicationCommand] -> ApplicationCommandRequest ()-  GetGuildApplicationCommands :: ApplicationId -> GuildId -> ApplicationCommandRequest [InternalApplicationCommand]-  CreateGuildApplicationCommand :: ApplicationId -> GuildId -> CreateApplicationCommand -> ApplicationCommandRequest InternalApplicationCommand-  GetGuildApplicationCommand :: ApplicationId -> GuildId -> ApplicationCommandId -> ApplicationCommandRequest InternalApplicationCommand-  EditGuildApplicationCommand :: ApplicationId -> GuildId -> ApplicationCommandId -> CreateApplicationCommand -> ApplicationCommandRequest InternalApplicationCommand+  GetGuildApplicationCommands :: ApplicationId -> GuildId -> ApplicationCommandRequest [ApplicationCommand]+  CreateGuildApplicationCommand :: ApplicationId -> GuildId -> CreateApplicationCommand -> ApplicationCommandRequest ApplicationCommand+  GetGuildApplicationCommand :: ApplicationId -> GuildId -> ApplicationCommandId -> ApplicationCommandRequest ApplicationCommand+  EditGuildApplicationCommand :: ApplicationId -> GuildId -> ApplicationCommandId -> CreateApplicationCommand -> ApplicationCommandRequest ApplicationCommand   DeleteGuildApplicationCommand :: ApplicationId -> GuildId -> ApplicationCommandId -> ApplicationCommandRequest ()   BulkOverWriteGuildApplicationCommand :: ApplicationId -> GuildId -> [CreateApplicationCommand] -> ApplicationCommandRequest ()   GetGuildApplicationCommandPermissions :: ApplicationId -> GuildId -> ApplicationCommandRequest GuildApplicationCommandPermissions@@ -38,9 +39,6 @@   -- | The only parameters needed in the GuildApplicationCommandPermissions   -- objects are id and permissions.   BatchEditApplicationCommandPermissions :: ApplicationId -> GuildId -> [GuildApplicationCommandPermissions] -> ApplicationCommandRequest [GuildApplicationCommandPermissions]---- TODO: permissions checks--- GetGuildApplicationCommandPermissions :: ApplicationId -> GuildID -> ApplicationCommandR  applications :: ApplicationId -> R.Url 'R.Https applications s = baseUrl /: "applications" // s
src/Discord/Internal/Rest/Channel.hs view
@@ -26,12 +26,13 @@ import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as BL import Network.HTTP.Client (RequestBody (RequestBodyBS))-import Network.HTTP.Client.MultipartFormData (partFileRequestBody, partBS, PartM)+import Network.HTTP.Client.MultipartFormData (partFileRequestBody, partBS) import Network.HTTP.Req ((/:)) import qualified Network.HTTP.Req as R  import Discord.Internal.Rest.Prelude import Discord.Internal.Types+import Control.Monad (join)  instance Request (ChannelRequest a) where   majorRoute = channelMajorRoute@@ -51,8 +52,6 @@   GetChannelMessage       :: (ChannelId, MessageId) -> ChannelRequest Message   -- | Sends a message to a channel.   CreateMessage           :: ChannelId -> T.Text -> ChannelRequest Message-  -- | Sends a message with an Embed to a channel.-  CreateMessageEmbed      :: ChannelId -> T.Text -> CreateEmbed -> ChannelRequest Message   -- | Sends a message with a file to a channel.   CreateMessageUploadFile :: ChannelId -> T.Text -> B.ByteString -> ChannelRequest Message   -- | Sends a message with granular controls.@@ -102,18 +101,18 @@ data MessageDetailedOpts = MessageDetailedOpts   { messageDetailedContent                  :: T.Text   , messageDetailedTTS                      :: Bool-  , messageDetailedEmbed                    :: Maybe CreateEmbed+  , messageDetailedEmbeds                    :: Maybe [CreateEmbed]   , messageDetailedFile                     :: Maybe (T.Text, B.ByteString)   , messageDetailedAllowedMentions          :: Maybe AllowedMentions   , messageDetailedReference                :: Maybe MessageReference-  , messageDetailedComponents               :: Maybe [Component]+  , messageDetailedComponents               :: Maybe [ComponentActionRow]   , messageDetailedStickerIds               :: Maybe [StickerId]-  } deriving (Show, Read, Eq, Ord)+  } deriving (Show, Eq, Ord, Read)  instance Default MessageDetailedOpts where   def = MessageDetailedOpts { messageDetailedContent         = ""                             , messageDetailedTTS             = False-                            , messageDetailedEmbed           = Nothing+                            , messageDetailedEmbeds          = Nothing                             , messageDetailedFile            = Nothing                             , messageDetailedAllowedMentions = Nothing                             , messageDetailedReference       = Nothing@@ -217,7 +216,6 @@   (GetChannelMessages chan _) ->            "msg " <> show chan   (GetChannelMessage (chan, _)) ->      "get_msg " <> show chan   (CreateMessage chan _) ->                 "msg " <> show chan-  (CreateMessageEmbed chan _ _) ->          "msg " <> show chan   (CreateMessageUploadFile chan _ _) ->     "msg " <> show chan   (CreateMessageDetailed chan _) ->         "msg " <> show chan   (CreateReaction (chan, _) _) ->     "add_react " <> show chan@@ -249,16 +247,6 @@     (_, Just a) -> "custom:" <> a     (_, Nothing) -> noAngles -maybeEmbed :: Maybe CreateEmbed -> [PartM IO]-maybeEmbed = --maybe [] $ \embed -> ["embed" .= createEmbed embed]-      let mkPart (name,content) = partFileRequestBody name (T.unpack name) (RequestBodyBS content)-          uploads CreateEmbed{..} = [(n,c) | (n, Just (CreateEmbedImageUpload c)) <--                                          [ ("author.png", createEmbedAuthorIcon)-                                          , ("thumbnail.png", createEmbedThumbnail)-                                          , ("image.png", createEmbedImage)-                                          , ("footer.png", createEmbedFooterIcon) ]]-      in maybe [] (map mkPart . uploads)- channels :: R.Url 'R.Https channels = baseUrl /: "channels" @@ -274,7 +262,7 @@       Delete (channels // chan) mempty    (GetChannelMessages chan (n,timing)) ->-      let n' = if n < 1 then 1 else (if n > 100 then 100 else n)+      let n' = max 1 (min 100 n)           options = "limit" R.=: n' <> messageTimingToQuery timing       in Get (channels // chan /: "messages") options @@ -286,35 +274,37 @@           body = pure $ R.ReqBodyJson $ object content       in Post (channels // chan /: "messages") body mempty -  (CreateMessageEmbed chan msg embed) ->-      let partJson = partBS "payload_json" $ BL.toStrict $ encode $ toJSON $ object ["content" .= msg, "embed" .= createEmbed embed]-          body = R.reqBodyMultipart (partJson : maybeEmbed (Just embed))-      in Post (channels // chan /: "messages") body mempty-   (CreateMessageUploadFile chan fileName file) ->       let part = partFileRequestBody "file" (T.unpack fileName) $ RequestBodyBS file           body = R.reqBodyMultipart [part]       in Post (channels // chan /: "messages") body mempty    (CreateMessageDetailed chan msgOpts) ->-      let fileUpload = messageDetailedFile msgOpts-          filePart = case fileUpload of-            Nothing -> []-            Just f  -> [partFileRequestBody "file" (T.unpack $ fst f)-              $ RequestBodyBS $ snd f]+    let fileUpload = messageDetailedFile msgOpts+        filePart =+          ( case fileUpload of+              Nothing -> []+              Just f ->+                [ partFileRequestBody+                    "file"+                    (T.unpack $ fst f)+                    (RequestBodyBS $ snd f)+                ]+          )+            ++ join (maybe [] (maybeEmbed . Just <$>) (messageDetailedEmbeds msgOpts)) -          payloadData =  object $ [ "content" .= messageDetailedContent msgOpts-                                 , "tts"     .= messageDetailedTTS msgOpts ] ++-                                 [ name .= value | (name, Just value) <--                                    [ ("embed", toJSON . createEmbed <$> messageDetailedEmbed msgOpts)-                                    , ("allowed_mentions", toJSON <$> messageDetailedAllowedMentions msgOpts)-                                    , ("message_reference", toJSON <$> messageDetailedReference msgOpts)-                                    , ("components", toJSON . (filterOutIncorrectEmoji <$>) <$> messageDetailedComponents msgOpts)-                                    , ("sticker_ids", toJSON <$> messageDetailedStickerIds msgOpts)-                                    ] ]-          payloadPart = partBS "payload_json" $ BL.toStrict $ encode $ toJSON payloadData+        payloadData =  object $ [ "content" .= messageDetailedContent msgOpts+                                , "tts"     .= messageDetailedTTS msgOpts ] +++                                [ name .= value | (name, Just value) <-+                                  [ ("embeds", toJSON . (createEmbed <$>) <$> messageDetailedEmbeds msgOpts)+                                  , ("allowed_mentions", toJSON <$> messageDetailedAllowedMentions msgOpts)+                                  , ("message_reference", toJSON <$> messageDetailedReference msgOpts)+                                  , ("components", toJSON <$> messageDetailedComponents msgOpts)+                                  , ("sticker_ids", toJSON <$> messageDetailedStickerIds msgOpts)+                                  ] ]+        payloadPart = partBS "payload_json" $ BL.toStrict $ encode payloadData -          body = R.reqBodyMultipart (payloadPart : filePart)+        body = R.reqBodyMultipart (payloadPart : filePart)       in Post (channels // chan /: "messages") body mempty    (CreateReaction (chan, msgid) emoji) ->@@ -336,7 +326,7 @@    (GetReactions (chan, msgid) emoji (n, timing)) ->       let e = cleanupEmoji emoji-          n' = if n < 1 then 1 else (if n > 100 then 100 else n)+          n' = max 1 (min 100 n)           options = "limit" R.=: n' <> reactionTimingToQuery timing       in Get (channels // chan /: "messages" // msgid /: "reactions" /: e) options 
src/Discord/Internal/Rest/Guild.hs view
@@ -132,7 +132,7 @@   -- | Sync an 'Integration'. Requires the 'MANAGE_GUILD' permission.   SyncGuildIntegration     :: GuildId -> IntegrationId -> GuildRequest ()   -- | Returns the 'GuildWidget' object. Requires the 'MANAGE_GUILD' permission.-  GetGuildWidget            :: GuildId -> GuildRequest GuildWidget +  GetGuildWidget            :: GuildId -> GuildRequest GuildWidget   -- | Modify a 'GuildWidget' object for the guild. All attributes may be passed in with   --   JSON and modified. Requires the 'MANAGE_GUILD' permission. Returns the updated   --   'GuildWidget' object.@@ -174,7 +174,7 @@ data ModifyGuildRoleOpts = ModifyGuildRoleOpts   { modifyGuildRoleOptsName            :: Maybe T.Text   , modifyGuildRoleOptsPermissions     :: Maybe T.Text-  , modifyGuildRoleOptsColor           :: Maybe ColorInteger+  , modifyGuildRoleOptsColor           :: Maybe DiscordColor   , modifyGuildRoleOptsSeparateSidebar :: Maybe Bool   , modifyGuildRoleOptsMentionable     :: Maybe Bool   } deriving (Show, Read, Eq, Ord)
src/Discord/Internal/Rest/Interactions.hs view
@@ -1,25 +1,24 @@ {-# LANGUAGE DataKinds #-}-{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE TypeApplications #-}  module Discord.Internal.Rest.Interactions where -import Data.Aeson (ToJSON (toJSON), Value)-import Network.HTTP.Req as R-+import Data.Aeson (encode)+import qualified Data.ByteString.Lazy as BL import Discord.Internal.Rest.Prelude import Discord.Internal.Types import Discord.Internal.Types.Interactions+import Network.HTTP.Client.MultipartFormData (PartM, partBS)+import Network.HTTP.Req as R  data InteractionResponseRequest a where   CreateInteractionResponse :: InteractionId -> InteractionToken -> InteractionResponse -> InteractionResponseRequest ()   GetOriginalInteractionResponse :: ApplicationId -> InteractionToken -> InteractionResponseRequest Message-  EditOriginalInteractionResponse :: ApplicationId -> InteractionToken -> InteractionCallbackMessages -> InteractionResponseRequest Message+  EditOriginalInteractionResponse :: ApplicationId -> InteractionToken -> InteractionResponseMessage -> InteractionResponseRequest Message   DeleteOriginalInteractionResponse :: ApplicationId -> InteractionToken -> InteractionResponseRequest ()-  CreateFollowupInteractionMessage :: ApplicationId -> InteractionToken -> InteractionCallbackMessages  -> InteractionResponseRequest Message+  CreateFollowupInteractionMessage :: ApplicationId -> InteractionToken -> InteractionResponseMessage -> InteractionResponseRequest Message   GetFollowupInteractionMessage :: ApplicationId -> InteractionToken -> MessageId -> InteractionResponseRequest Message   EditFollowupInteractionMessage :: ApplicationId -> InteractionToken -> MessageId -> InteractionResponse -> InteractionResponseRequest Message   DeleteFollowupInteractionMessage :: ApplicationId -> InteractionToken -> MessageId -> InteractionResponseRequest ()@@ -49,11 +48,11 @@   (GetOriginalInteractionResponse aid it) ->     Get (interaction aid it /: "@original") mempty   (EditOriginalInteractionResponse aid it i) ->-    Patch (interaction aid it /: "@original") (convert i) mempty+    Patch (interaction aid it /: "@original") (convertIRM i) mempty   (DeleteOriginalInteractionResponse aid it) ->     Delete (interaction aid it /: "@original") mempty   (CreateFollowupInteractionMessage aid it i) ->-    Post (baseUrl /: "webhooks" // aid /: it) (convert i) mempty+    Post (baseUrl /: "webhooks" // aid /: it) (convertIRM i) mempty   (GetFollowupInteractionMessage aid it mid) ->     Get (interaction aid it // mid) mempty   (EditFollowupInteractionMessage aid it mid i) ->@@ -61,5 +60,13 @@   (DeleteFollowupInteractionMessage aid it mid) ->     Delete (interaction aid it // mid) mempty   where-    convert :: (ToJSON a) => a -> RestIO (ReqBodyJson Value)-    convert = (pure @RestIO) . R.ReqBodyJson . toJSON+    convert :: InteractionResponse -> RestIO ReqBodyMultipart+    convert ir@(InteractionResponseChannelMessage irm) = R.reqBodyMultipart (partBS "payload_json" (BL.toStrict $ encode ir) : convert' irm)+    convert ir@(InteractionResponseUpdateMessage irm) = R.reqBodyMultipart (partBS "payload_json" (BL.toStrict $ encode ir) : convert' irm)+    convert ir = R.reqBodyMultipart [partBS "payload_json" $ BL.toStrict $ encode ir]+    convertIRM :: InteractionResponseMessage -> RestIO ReqBodyMultipart+    convertIRM irm = R.reqBodyMultipart (partBS "payload_json" (BL.toStrict $ encode irm) : convert' irm)+    convert' :: InteractionResponseMessage -> [PartM IO]+    convert' InteractionResponseMessage {..} = case interactionResponseMessageEmbeds of+      Nothing -> []+      Just f -> (maybeEmbed . Just) =<< f
src/Discord/Internal/Rest/Prelude.hs view
@@ -12,6 +12,7 @@ import qualified Data.Text as T import qualified Data.Text.Encoding as TE + import qualified Network.HTTP.Req as R  import Discord.Internal.Types@@ -29,7 +30,7 @@   where   -- | https://discord.com/developers/docs/reference#user-agent   -- Second place where the library version is noted-  agent = "DiscordBot (https://github.com/aquarial/discord-haskell, 1.11.0)"+  agent = "DiscordBot (https://github.com/aquarial/discord-haskell, 1.12.0)"  -- Append to an URL infixl 5 //
src/Discord/Internal/Types.hs view
@@ -1,38 +1,31 @@--- | Provides types and encoding/decoding code. Types should be identical to those provided---   in the Discord API documentation.+-- | Re-export ALL the internal type modules. Hiding is in Discord.Types module Discord.Internal.Types-  ( module Discord.Internal.Types.Prelude-  , module Discord.Internal.Types.Channel-  , module Discord.Internal.Types.Events-  , module Discord.Internal.Types.Gateway-  , module Discord.Internal.Types.Guild-  , module Discord.Internal.Types.User-  , module Discord.Internal.Types.Embed-  , module Discord.Internal.Types.Components---, module Discord.Internal.Types.ApplicationCommands---, module Discord.Internal.Types.Interactions-  , module Data.Aeson-  , module Data.Time.Clock-  , userFacingEvent-  ) where+  ( module Discord.Internal.Types.Prelude,+    module Discord.Internal.Types.Channel,+    module Discord.Internal.Types.Color,+    module Discord.Internal.Types.Events,+    module Discord.Internal.Types.Gateway,+    module Discord.Internal.Types.Guild,+    module Discord.Internal.Types.User,+    module Discord.Internal.Types.Embed,+    module Discord.Internal.Types.Components,+    module Data.Aeson,+    module Data.Time.Clock,+    userFacingEvent,+  )+where +import Data.Aeson (Object, ToJSON (toJSON))+import Data.Time.Clock (UTCTime (..)) import Discord.Internal.Types.Channel+import Discord.Internal.Types.Color+import Discord.Internal.Types.Components+import Discord.Internal.Types.Embed import Discord.Internal.Types.Events import Discord.Internal.Types.Gateway import Discord.Internal.Types.Guild-import Discord.Internal.Types.User-import Discord.Internal.Types.Embed import Discord.Internal.Types.Prelude-import Discord.Internal.Types.Components---- import Discord.Internal.Types.ApplicationCommands-import Discord.Internal.Types.Interactions---import Data.Aeson (Object)-import Data.Time.Clock (UTCTime(..))-import Data.Maybe (fromMaybe)-+import Discord.Internal.Types.User  userFacingEvent :: EventInternalParse -> Event userFacingEvent event = case event of@@ -67,5 +60,5 @@   InternalPresenceUpdate a -> PresenceUpdate a   InternalTypingStart a -> TypingStart a   InternalUserUpdate a -> UserUpdate a-  InternalInteractionCreate a -> InteractionCreate (fromMaybe (InteractionUnknown a) (fromInternal a))+  InternalInteractionCreate a -> InteractionCreate a   InternalUnknownEvent a b -> UnknownEvent a b
src/Discord/Internal/Types/ApplicationCommands.hs view
@@ -10,246 +10,369 @@  module Discord.Internal.Types.ApplicationCommands   ( ApplicationCommand (..),+    ApplicationCommandOptions (..),     ApplicationCommandOptionSubcommandOrGroup (..),     ApplicationCommandOptionSubcommand (..),     ApplicationCommandOptionValue (..),-    InternalApplicationCommand (..),-    CreateApplicationCommand (..),     createApplicationCommandChatInput,     createApplicationCommandUser,     createApplicationCommandMessage,+    CreateApplicationCommand (..),     EditApplicationCommand (..),-    ApplicationCommandType (..),-    InternalApplicationCommandOption (..),-    ApplicationCommandOptionType (..),-    InternalApplicationCommandOptionChoice,+    defaultEditApplicationCommand,     Choice (..),     ApplicationCommandChannelType (..),     GuildApplicationCommandPermissions (..),     ApplicationCommandPermissions (..),-    ApplicationCommandPermissionType (..),-    StringNumberValue (..),   ) where -import Control.Applicative import Data.Aeson-import Data.Char (isLower)+import Data.Aeson.Types (Pair, Parser) import Data.Data (Data)-import Data.Default (Default (..))-import Data.Maybe (fromJust, fromMaybe)+import Data.Foldable (Foldable (toList)) import Data.Scientific (Scientific) import qualified Data.Text as T-import Discord.Internal.Types.Prelude (ApplicationCommandId, ApplicationId, GuildId, Internals (..), Snowflake, makeTable, toMaybeJSON)+import Discord.Internal.Types.Prelude (ApplicationCommandId, ApplicationId, GuildId, InternalDiscordEnum (..), Snowflake, discordTypeParseJSON, toMaybeJSON) +-- | The structure for an application command. data ApplicationCommand   = ApplicationCommandUser-      { applicationCommandId :: ApplicationCommandId,+      { -- | The id of the application command.+        applicationCommandId :: ApplicationCommandId,+        -- | The id of the application the command comes from.         applicationCommandApplicationId :: ApplicationId,+        -- | The guild the application command is registered in.         applicationCommandGuildId :: Maybe GuildId,+        -- | The name of the application command.         applicationCommandName :: T.Text,-        applicationCommandDefaultPermission :: Maybe Bool,+        -- | Whether the command is enabled by default when the app is added to a guild.+        applicationCommandDefaultPermission :: Bool,+        -- | Autoincrementing version identifier updated during substantial record changes.         applicationCommandVersion :: Snowflake       }   | ApplicationCommandMessage-      { applicationCommandId :: ApplicationCommandId,+      { -- | The id of the application command.+        applicationCommandId :: ApplicationCommandId,+        -- | The id of the application the command comes from.         applicationCommandApplicationId :: ApplicationId,+        -- | The guild the application command is registered in.         applicationCommandGuildId :: Maybe GuildId,+        -- | The name of the application command.         applicationCommandName :: T.Text,-        applicationCommandDefaultPermission :: Maybe Bool,+        -- | Whether the command is enabled by default when the app is added to a guild.+        applicationCommandDefaultPermission :: Bool,+        -- | Autoincrementing version identifier updated during substantial record changes.         applicationCommandVersion :: Snowflake       }   | ApplicationCommandChatInput-      { applicationCommandId :: ApplicationCommandId,+      { -- | The id of the application command.+        applicationCommandId :: ApplicationCommandId,+        -- | The id of the application the command comes from.         applicationCommandApplicationId :: ApplicationId,+        -- | The guild the application command is registered in.         applicationCommandGuildId :: Maybe GuildId,+        -- | The name of the application command.         applicationCommandName :: T.Text,+        -- | The description of the application command.         applicationCommandDescription :: T.Text,+        -- | The parameters for the command.         applicationCommandOptions :: Maybe ApplicationCommandOptions,-        applicationCommandDefaultPermission :: Maybe Bool,+        -- | Whether the command is enabled by default when the app is added to a guild.+        applicationCommandDefaultPermission :: Bool,+        -- | Autoincrementing version identifier updated during substantial record changes.         applicationCommandVersion :: Snowflake       }-  | ApplicationCommandUnknown InternalApplicationCommand   deriving (Show, Eq, Read) +instance FromJSON ApplicationCommand where+  parseJSON =+    withObject+      "ApplicationCommand"+      ( \v -> do+          acid <- v .: "id"+          aid <- v .: "application_id"+          gid <- v .:? "guild_id"+          name <- v .: "name"+          defPerm <- v .:? "default_permission" .!= True+          version <- v .: "version"+          t <- v .:? "type" :: Parser (Maybe Int)+          case t of+            (Just 2) -> return $ ApplicationCommandUser acid aid gid name defPerm version+            (Just 3) -> return $ ApplicationCommandMessage acid aid gid name defPerm version+            _ -> do+              desc <- v .: "description"+              options <- v .:? "options"+              return $ ApplicationCommandChatInput acid aid gid name desc options defPerm version+      )++-- | Either subcommands and groups, or values. data ApplicationCommandOptions   = ApplicationCommandOptionsSubcommands [ApplicationCommandOptionSubcommandOrGroup]   | ApplicationCommandOptionsValues [ApplicationCommandOptionValue]   deriving (Show, Eq, Read) +instance FromJSON ApplicationCommandOptions where+  parseJSON =+    withArray+      "ApplicationCommandOptions"+      ( \a -> do+          let a' = toList a+          case a' of+            [] -> return $ ApplicationCommandOptionsValues []+            (v' : _) ->+              withObject+                "ApplicationCommandOptions item"+                ( \v -> do+                    t <- v .: "type" :: Parser Int+                    if t == 1 || t == 2+                      then ApplicationCommandOptionsSubcommands <$> mapM parseJSON a'+                      else ApplicationCommandOptionsValues <$> mapM parseJSON a'+                )+                v'+      )++instance ToJSON ApplicationCommandOptions where+  toJSON (ApplicationCommandOptionsSubcommands o) = toJSON o+  toJSON (ApplicationCommandOptionsValues o) = toJSON o++-- | Either a subcommand group or a subcommand. data ApplicationCommandOptionSubcommandOrGroup   = ApplicationCommandOptionSubcommandGroup-      { applicationCommandOptionSubcommandGroupName :: T.Text,+      { -- | The name of the subcommand group+        applicationCommandOptionSubcommandGroupName :: T.Text,+        -- | The description of the subcommand group         applicationCommandOptionSubcommandGroupDescription :: T.Text,+        -- | The subcommands in this subcommand group         applicationCommandOptionSubcommandGroupOptions :: [ApplicationCommandOptionSubcommand]       }   | ApplicationCommandOptionSubcommandOrGroupSubcommand ApplicationCommandOptionSubcommand   deriving (Show, Eq, Read) +instance FromJSON ApplicationCommandOptionSubcommandOrGroup where+  parseJSON =+    withObject+      "ApplicationCommandOptionSubcommandOrGroup"+      ( \v -> do+          t <- v .: "type" :: Parser Int+          case t of+            2 ->+              ApplicationCommandOptionSubcommandGroup+                <$> v .: "name"+                <*> v .: "description"+                <*> v .: "options"+            1 -> ApplicationCommandOptionSubcommandOrGroupSubcommand <$> parseJSON (Object v)+            _ -> fail "unexpected subcommand group type"+      )++instance ToJSON ApplicationCommandOptionSubcommandOrGroup where+  toJSON ApplicationCommandOptionSubcommandGroup {..} =+    object+      [ ("type", Number 2),+        ("name", toJSON applicationCommandOptionSubcommandGroupName),+        ("description", toJSON applicationCommandOptionSubcommandGroupDescription),+        ("options", toJSON applicationCommandOptionSubcommandGroupOptions)+      ]+  toJSON (ApplicationCommandOptionSubcommandOrGroupSubcommand a) = toJSON a++-- | Data for a single subcommand. data ApplicationCommandOptionSubcommand = ApplicationCommandOptionSubcommand-  { applicationCommandOptionSubcommandName :: T.Text,+  { -- | The name of the subcommand+    applicationCommandOptionSubcommandName :: T.Text,+    -- | The description of the subcommand     applicationCommandOptionSubcommandDescription :: T.Text,+    -- | What options are there in this subcommand     applicationCommandOptionSubcommandOptions :: [ApplicationCommandOptionValue]   }   deriving (Show, Eq, Read) +instance FromJSON ApplicationCommandOptionSubcommand where+  parseJSON =+    withObject+      "ApplicationCommandOptionSubcommand"+      ( \v -> do+          t <- v .: "type" :: Parser Int+          case t of+            1 ->+              ApplicationCommandOptionSubcommand+                <$> v .: "name"+                <*> v .: "description"+                <*> v .:? "options" .!= []+            _ -> fail "unexpected subcommand type"+      )++instance ToJSON ApplicationCommandOptionSubcommand where+  toJSON ApplicationCommandOptionSubcommand {..} =+    object+      [ ("type", Number 1),+        ("name", toJSON applicationCommandOptionSubcommandName),+        ("description", toJSON applicationCommandOptionSubcommandDescription),+        ("options", toJSON applicationCommandOptionSubcommandOptions)+      ]++-- | Data for a single value. data ApplicationCommandOptionValue   = ApplicationCommandOptionValueString-      { applicationCommandOptionValueName :: T.Text,+      { -- | The name of the value+        applicationCommandOptionValueName :: T.Text,+        -- | The description of the value         applicationCommandOptionValueDescription :: T.Text,-        applicationCommandOptionValueRequired :: Maybe Bool,-        applicationCommandOptionValueStringChoices :: Maybe [Choice T.Text],-        applicationCommandOptionValueAutocomplete :: Maybe Bool+        -- | Whether this option is required+        applicationCommandOptionValueRequired :: Bool,+        -- | Whether to autocomplete or have a list of named choices. For neither option, use `Left False`+        applicationCommandOptionValueStringChoices :: AutocompleteOrChoice T.Text       }   | ApplicationCommandOptionValueInteger-      { applicationCommandOptionValueName :: T.Text,+      { -- | The name of the value+        applicationCommandOptionValueName :: T.Text,+        -- | The description of the value         applicationCommandOptionValueDescription :: T.Text,-        applicationCommandOptionValueRequired :: Maybe Bool,-        applicationCommandOptionValueIntegerChoices :: Maybe [Choice Integer],+        -- | Whether this option is required+        applicationCommandOptionValueRequired :: Bool,+        -- | Whether to autocomplete or have a list of named choices. For neither option, use `Left False`+        applicationCommandOptionValueIntegerChoices :: AutocompleteOrChoice Integer,+        -- | The lower bound of values permitted. If choices are provided or autocomplete is on, this can be ignored         applicationCommandOptionValueIntegerMinVal :: Maybe Integer,-        applicationCommandOptionValueIntegerMaxVal :: Maybe Integer,-        applicationCommandOptionValueAutocomplete :: Maybe Bool+        -- | The upper bound of values permitted. If choices are provided or autocomplete is on, this can be ignored+        applicationCommandOptionValueIntegerMaxVal :: Maybe Integer       }   | ApplicationCommandOptionValueBoolean-      { applicationCommandOptionValueName :: T.Text,+      { -- | The name of the value+        applicationCommandOptionValueName :: T.Text,+        -- | The description of the value         applicationCommandOptionValueDescription :: T.Text,-        applicationCommandOptionValueRequired :: Maybe Bool+        -- | Whether this option is required+        applicationCommandOptionValueRequired :: Bool       }   | ApplicationCommandOptionValueUser-      { applicationCommandOptionValueName :: T.Text,+      { -- | The name of the value+        applicationCommandOptionValueName :: T.Text,+        -- | The description of the value         applicationCommandOptionValueDescription :: T.Text,-        applicationCommandOptionValueRequired :: Maybe Bool+        -- | Whether this option is required+        applicationCommandOptionValueRequired :: Bool       }   | ApplicationCommandOptionValueChannel-      { applicationCommandOptionValueName :: T.Text,+      { -- | The name of the value+        applicationCommandOptionValueName :: T.Text,+        -- | The description of the value         applicationCommandOptionValueDescription :: T.Text,-        applicationCommandOptionValueRequired :: Maybe Bool,+        -- | Whether this option is required+        applicationCommandOptionValueRequired :: Bool,+        -- | What type of channel can be put in here         applicationCommandOptionValueChannelTypes :: Maybe [ApplicationCommandChannelType]       }   | ApplicationCommandOptionValueRole-      { applicationCommandOptionValueName :: T.Text,+      { -- | The name of the value+        applicationCommandOptionValueName :: T.Text,+        -- | The description of the value         applicationCommandOptionValueDescription :: T.Text,-        applicationCommandOptionValueRequired :: Maybe Bool+        -- | Whether this option is required+        applicationCommandOptionValueRequired :: Bool       }   | ApplicationCommandOptionValueMentionable-      { applicationCommandOptionValueName :: T.Text,+      { -- | The name of the value+        applicationCommandOptionValueName :: T.Text,+        -- | The description of the value         applicationCommandOptionValueDescription :: T.Text,-        applicationCommandOptionValueRequired :: Maybe Bool+        -- | Whether this option is required+        applicationCommandOptionValueRequired :: Bool       }   | ApplicationCommandOptionValueNumber-      { applicationCommandOptionValueName :: T.Text,+      { -- | The name of the value+        applicationCommandOptionValueName :: T.Text,+        -- | The description of the value         applicationCommandOptionValueDescription :: T.Text,-        applicationCommandOptionValueRequired :: Maybe Bool,-        applicationCommandOptionValueNumberChoices :: Maybe [Choice Scientific],+        -- | Whether this option is required+        applicationCommandOptionValueRequired :: Bool,+        -- | Whether to autocomplete or have a list of named choices. For neither option, use `Left False`+        applicationCommandOptionValueNumberChoices :: AutocompleteOrChoice Scientific,+        -- | The lower bound of values permitted. If choices are provided or autocomplete is on, this can be ignored         applicationCommandOptionValueNumberMinVal :: Maybe Scientific,-        applicationCommandOptionValueNumberMaxVal :: Maybe Scientific,-        applicationCommandOptionValueAutocomplete :: Maybe Bool+        -- | The upper bound of values permitted. If choices are provided or autocomplete is on, this can be ignored+        applicationCommandOptionValueNumberMaxVal :: Maybe Scientific       }   deriving (Show, Eq, Read) -instance Internals ApplicationCommandOptionValue InternalApplicationCommandOption where-  toInternal ApplicationCommandOptionValueNumber {..} = InternalApplicationCommandOption ApplicationCommandOptionTypeNumber applicationCommandOptionValueName applicationCommandOptionValueDescription applicationCommandOptionValueRequired (((StringNumberValueNumber <$>) <$>) <$> applicationCommandOptionValueNumberChoices) Nothing Nothing applicationCommandOptionValueNumberMinVal applicationCommandOptionValueNumberMaxVal applicationCommandOptionValueAutocomplete-  toInternal ApplicationCommandOptionValueInteger {..} = InternalApplicationCommandOption ApplicationCommandOptionTypeInteger applicationCommandOptionValueName applicationCommandOptionValueDescription applicationCommandOptionValueRequired (((StringNumberValueInteger <$>) <$>) <$> applicationCommandOptionValueIntegerChoices) Nothing Nothing (fromInteger <$> applicationCommandOptionValueIntegerMinVal) (fromInteger <$> applicationCommandOptionValueIntegerMaxVal) applicationCommandOptionValueAutocomplete-  toInternal ApplicationCommandOptionValueString {..} = InternalApplicationCommandOption ApplicationCommandOptionTypeInteger applicationCommandOptionValueName applicationCommandOptionValueDescription applicationCommandOptionValueRequired (((StringNumberValueString <$>) <$>) <$> applicationCommandOptionValueStringChoices) Nothing Nothing Nothing Nothing applicationCommandOptionValueAutocomplete-  toInternal ApplicationCommandOptionValueChannel {..} = InternalApplicationCommandOption ApplicationCommandOptionTypeChannel applicationCommandOptionValueName applicationCommandOptionValueDescription applicationCommandOptionValueRequired Nothing Nothing applicationCommandOptionValueChannelTypes Nothing Nothing Nothing-  toInternal ApplicationCommandOptionValueBoolean {..} = InternalApplicationCommandOption ApplicationCommandOptionTypeBoolean applicationCommandOptionValueName applicationCommandOptionValueDescription applicationCommandOptionValueRequired Nothing Nothing Nothing Nothing Nothing Nothing-  toInternal ApplicationCommandOptionValueUser {..} = InternalApplicationCommandOption ApplicationCommandOptionTypeUser applicationCommandOptionValueName applicationCommandOptionValueDescription applicationCommandOptionValueRequired Nothing Nothing Nothing Nothing Nothing Nothing-  toInternal ApplicationCommandOptionValueRole {..} = InternalApplicationCommandOption ApplicationCommandOptionTypeRole applicationCommandOptionValueName applicationCommandOptionValueDescription applicationCommandOptionValueRequired Nothing Nothing Nothing Nothing Nothing Nothing-  toInternal ApplicationCommandOptionValueMentionable {..} = InternalApplicationCommandOption ApplicationCommandOptionTypeMentionable applicationCommandOptionValueName applicationCommandOptionValueDescription applicationCommandOptionValueRequired Nothing Nothing Nothing Nothing Nothing Nothing--  fromInternal InternalApplicationCommandOption {internalApplicationCommandOptionType = ApplicationCommandOptionTypeNumber, ..} = do-    cs <- maybe (Just []) (mapM extractChoices) internalApplicationCommandOptionChoices-    return $ ApplicationCommandOptionValueNumber internalApplicationCommandOptionName internalApplicationCommandOptionDescription internalApplicationCommandOptionRequired (fromResult cs) internalApplicationCommandOptionMinVal internalApplicationCommandOptionMaxVal internalApplicationCommandOptionAutocomplete-    where-      extractChoices (Choice s (StringNumberValueNumber n)) = Just (Choice s n)-      extractChoices _ = Nothing-      fromResult [] = Nothing-      fromResult is = Just is-  fromInternal InternalApplicationCommandOption {internalApplicationCommandOptionType = ApplicationCommandOptionTypeInteger, ..} = do-    cs <- maybe (Just []) (mapM extractChoices) internalApplicationCommandOptionChoices-    return $ ApplicationCommandOptionValueInteger internalApplicationCommandOptionName internalApplicationCommandOptionDescription internalApplicationCommandOptionRequired (fromResult cs) (round <$> internalApplicationCommandOptionMinVal) (round <$> internalApplicationCommandOptionMaxVal) internalApplicationCommandOptionAutocomplete-    where-      extractChoices (Choice s (StringNumberValueInteger n)) = Just (Choice s n)-      extractChoices _ = Nothing-      fromResult [] = Nothing-      fromResult is = Just is-  -- note with the above: the bounds are rounded for simplicity but ideally they wouldn't be-  fromInternal InternalApplicationCommandOption {internalApplicationCommandOptionType = ApplicationCommandOptionTypeString, ..} = do-    cs <- maybe (Just []) (mapM extractChoices) internalApplicationCommandOptionChoices-    return $ ApplicationCommandOptionValueString internalApplicationCommandOptionName internalApplicationCommandOptionDescription internalApplicationCommandOptionRequired (fromResult cs) internalApplicationCommandOptionAutocomplete-    where-      extractChoices (Choice s (StringNumberValueString n)) = Just (Choice s n)-      extractChoices _ = Nothing-      fromResult [] = Nothing-      fromResult is = Just is-  fromInternal InternalApplicationCommandOption {internalApplicationCommandOptionType = ApplicationCommandOptionTypeBoolean, ..} = Just $ ApplicationCommandOptionValueBoolean internalApplicationCommandOptionName internalApplicationCommandOptionDescription internalApplicationCommandOptionRequired-  fromInternal InternalApplicationCommandOption {internalApplicationCommandOptionType = ApplicationCommandOptionTypeUser, ..} = Just $ ApplicationCommandOptionValueUser internalApplicationCommandOptionName internalApplicationCommandOptionDescription internalApplicationCommandOptionRequired-  fromInternal InternalApplicationCommandOption {internalApplicationCommandOptionType = ApplicationCommandOptionTypeRole, ..} = Just $ ApplicationCommandOptionValueRole internalApplicationCommandOptionName internalApplicationCommandOptionDescription internalApplicationCommandOptionRequired-  fromInternal InternalApplicationCommandOption {internalApplicationCommandOptionType = ApplicationCommandOptionTypeMentionable, ..} = Just $ ApplicationCommandOptionValueMentionable internalApplicationCommandOptionName internalApplicationCommandOptionDescription internalApplicationCommandOptionRequired-  fromInternal InternalApplicationCommandOption {internalApplicationCommandOptionType = ApplicationCommandOptionTypeChannel, ..} = Just $ ApplicationCommandOptionValueChannel internalApplicationCommandOptionName internalApplicationCommandOptionDescription internalApplicationCommandOptionRequired internalApplicationCommandOptionChannelTypes-  fromInternal _ = Nothing--instance Internals ApplicationCommandOptionSubcommand InternalApplicationCommandOption where-  toInternal ApplicationCommandOptionSubcommand {..} = InternalApplicationCommandOption ApplicationCommandOptionTypeSubcommand applicationCommandOptionSubcommandName applicationCommandOptionSubcommandDescription Nothing Nothing (Just $ toInternal <$> applicationCommandOptionSubcommandOptions) Nothing Nothing Nothing Nothing--  fromInternal InternalApplicationCommandOption {internalApplicationCommandOptionType = ApplicationCommandOptionTypeSubcommand, ..} = do-    os <- maybe (Just []) (mapM fromInternal) internalApplicationCommandOptionOptions-    return $ ApplicationCommandOptionSubcommand internalApplicationCommandOptionName internalApplicationCommandOptionDescription os-  fromInternal _ = Nothing--instance Internals ApplicationCommandOptionSubcommandOrGroup InternalApplicationCommandOption where-  toInternal (ApplicationCommandOptionSubcommandOrGroupSubcommand s) = toInternal s-  toInternal ApplicationCommandOptionSubcommandGroup {..} = InternalApplicationCommandOption ApplicationCommandOptionTypeSubcommandGroup applicationCommandOptionSubcommandGroupName applicationCommandOptionSubcommandGroupDescription Nothing Nothing (Just $ toInternal <$> applicationCommandOptionSubcommandGroupOptions) Nothing Nothing Nothing Nothing--  fromInternal io@InternalApplicationCommandOption {internalApplicationCommandOptionType = ApplicationCommandOptionTypeSubcommand, ..} = ApplicationCommandOptionSubcommandOrGroupSubcommand <$> fromInternal io-  fromInternal InternalApplicationCommandOption {internalApplicationCommandOptionType = ApplicationCommandOptionTypeSubcommandGroup, ..} = do-    os <- maybe (Just []) (mapM fromInternal) internalApplicationCommandOptionOptions-    return $ ApplicationCommandOptionSubcommandGroup internalApplicationCommandOptionName internalApplicationCommandOptionDescription os-  fromInternal _ = Nothing--instance Internals ApplicationCommandOptions [InternalApplicationCommandOption] where-  toInternal (ApplicationCommandOptionsSubcommands is) = toInternal <$> is-  toInternal (ApplicationCommandOptionsValues is) = toInternal <$> is--  fromInternal is = (ApplicationCommandOptionsSubcommands <$> mapM fromInternal is) <|> (ApplicationCommandOptionsValues <$> mapM fromInternal is)--instance Internals ApplicationCommand InternalApplicationCommand where-  toInternal ApplicationCommandUser {..} = InternalApplicationCommand applicationCommandId (Just ApplicationCommandTypeUser) applicationCommandApplicationId applicationCommandGuildId applicationCommandName "" Nothing applicationCommandDefaultPermission applicationCommandVersion-  toInternal ApplicationCommandMessage {..} = InternalApplicationCommand applicationCommandId (Just ApplicationCommandTypeMessage) applicationCommandApplicationId applicationCommandGuildId applicationCommandName "" Nothing applicationCommandDefaultPermission applicationCommandVersion-  toInternal ApplicationCommandChatInput {..} = InternalApplicationCommand applicationCommandId (Just ApplicationCommandTypeChatInput) applicationCommandApplicationId applicationCommandGuildId applicationCommandName applicationCommandDescription (toInternal <$> applicationCommandOptions) applicationCommandDefaultPermission applicationCommandVersion-  toInternal (ApplicationCommandUnknown ai) = ai--  fromInternal InternalApplicationCommand {internalApplicationCommandType = Just ApplicationCommandTypeUser, ..} = Just $ ApplicationCommandUser internalApplicationCommandId internalApplicationCommandApplicationId internalApplicationCommandGuildId internalApplicationCommandName internalApplicationCommandDefaultPermission internalApplicationCommandVersion-  fromInternal InternalApplicationCommand {internalApplicationCommandType = Just ApplicationCommandTypeMessage, ..} = Just $ ApplicationCommandMessage internalApplicationCommandId internalApplicationCommandApplicationId internalApplicationCommandGuildId internalApplicationCommandName internalApplicationCommandDefaultPermission internalApplicationCommandVersion-  fromInternal a@InternalApplicationCommand {internalApplicationCommandType = Just ApplicationCommandTypeChatInput, ..} = Just $ fromMaybe (ApplicationCommandUnknown a) $ ((internalApplicationCommandOptions <|> Just []) >>= fromInternal) >>= \iOptions -> Just $ ApplicationCommandChatInput internalApplicationCommandId internalApplicationCommandApplicationId internalApplicationCommandGuildId internalApplicationCommandName internalApplicationCommandDescription (Just iOptions) internalApplicationCommandDefaultPermission internalApplicationCommandVersion-  fromInternal a = fromInternal (a {internalApplicationCommandType = Just ApplicationCommandTypeChatInput})---- Just $ ApplicationCommandMessage internalApplicationCommandId internalApplicationCommandApplicationId internalApplicationCommandGuildId internalApplicationCommandName internalApplicationCommandDefaultPermission internalApplicationCommandVersion---- | What type of application command. Represents slash commands, right clicking--- a user, and right clicking a message respectively.-data ApplicationCommandType-  = -- | Slash commands-    ApplicationCommandTypeChatInput-  | -- | User commands-    ApplicationCommandTypeUser-  | -- | Message commands-    ApplicationCommandTypeMessage-  deriving (Show, Read, Data, Eq)+instance FromJSON ApplicationCommandOptionValue where+  parseJSON =+    withObject+      "ApplicationCommandOptionValue"+      ( \v -> do+          name <- v .: "name"+          desc <- v .: "description"+          required <- v .:? "required" .!= False+          t <- v .: "type" :: Parser Int+          case t of+            3 ->+              ApplicationCommandOptionValueString name desc required+                <$> parseJSON (Object v)+            4 ->+              ApplicationCommandOptionValueInteger name desc required+                <$> parseJSON (Object v)+                <*> v .:? "min_value"+                <*> v .:? "max_value"+            10 ->+              ApplicationCommandOptionValueNumber name desc required+                <$> parseJSON (Object v)+                <*> v .:? "min_value"+                <*> v .:? "max_value"+            7 ->+              ApplicationCommandOptionValueChannel name desc required+                <$> v .:? "channel_types"+            5 -> return $ ApplicationCommandOptionValueBoolean name desc required+            6 -> return $ ApplicationCommandOptionValueUser name desc required+            8 -> return $ ApplicationCommandOptionValueRole name desc required+            9 -> return $ ApplicationCommandOptionValueMentionable name desc required+            _ -> fail "unknown application command option value type"+      ) -instance Enum ApplicationCommandType where-  fromEnum ApplicationCommandTypeChatInput = 1-  fromEnum ApplicationCommandTypeUser = 2-  fromEnum ApplicationCommandTypeMessage = 3-  toEnum a = fromJust $ lookup a table+instance ToJSON ApplicationCommandOptionValue where+  toJSON ApplicationCommandOptionValueString {..} =+    object+      [ ("type", Number 3),+        ("name", toJSON applicationCommandOptionValueName),+        ("description", toJSON applicationCommandOptionValueDescription),+        ("required", toJSON applicationCommandOptionValueRequired),+        choiceOrAutocompleteToJSON applicationCommandOptionValueStringChoices+      ]+  toJSON ApplicationCommandOptionValueInteger {..} =+    object+      [ ("type", Number 4),+        ("name", toJSON applicationCommandOptionValueName),+        ("description", toJSON applicationCommandOptionValueDescription),+        ("required", toJSON applicationCommandOptionValueRequired),+        choiceOrAutocompleteToJSON applicationCommandOptionValueIntegerChoices+      ]+  toJSON ApplicationCommandOptionValueNumber {..} =+    object+      [ ("type", Number 10),+        ("name", toJSON applicationCommandOptionValueName),+        ("description", toJSON applicationCommandOptionValueDescription),+        ("required", toJSON applicationCommandOptionValueRequired),+        choiceOrAutocompleteToJSON applicationCommandOptionValueNumberChoices+      ]+  toJSON ApplicationCommandOptionValueChannel {..} =+    object+      [ ("type", Number 7),+        ("name", toJSON applicationCommandOptionValueName),+        ("description", toJSON applicationCommandOptionValueDescription),+        ("required", toJSON applicationCommandOptionValueRequired),+        ("channel_types", toJSON applicationCommandOptionValueChannelTypes)+      ]+  toJSON acov =+    object+      [ ("type", Number (t acov)),+        ("name", toJSON $ applicationCommandOptionValueName acov),+        ("description", toJSON $ applicationCommandOptionValueDescription acov),+        ("required", toJSON $ applicationCommandOptionValueRequired acov)+      ]     where-      table = makeTable ApplicationCommandTypeChatInput--instance ToJSON ApplicationCommandType where-  toJSON = toJSON . fromEnum--instance FromJSON ApplicationCommandType where-  parseJSON = withScientific "ApplicationCommandType" (return . toEnum . round)+      t ApplicationCommandOptionValueBoolean {} = 5+      t ApplicationCommandOptionValueUser {} = 6+      t ApplicationCommandOptionValueRole {} = 8+      t ApplicationCommandOptionValueMentionable {} = 9+      t _ = -1  -- | Data type to be used when creating application commands. The specification -- is below.@@ -267,84 +390,124 @@ -- of command nesting permitted. -- -- https://discord.com/developers/docs/interactions/application-commands#create-global-application-command-data CreateApplicationCommand = CreateApplicationCommand-  { -- | The application command name (1-32 chars).-    createApplicationCommandName :: T.Text,-    -- | The application command description (1-100 chars). Has to be empty for-    -- non-slash commands.-    createApplicationCommandDescription :: T.Text,-    -- | What options the application (max length 25). Has to be `Nothing` for-    -- non-slash commands.-    createApplicationCommandOptions :: Maybe [InternalApplicationCommandOption],-    -- | Whether the command is enabled by default when the application is added-    -- to a guild. Defaults to true if not present-    createApplicationCommandDefaultPermission :: Maybe Bool,-    -- | What the type of the command is. If `Nothing`, defaults to slash-    -- commands.-    createApplicationCommandType :: Maybe ApplicationCommandType-  }+data CreateApplicationCommand+  = CreateApplicationCommandChatInput+      { -- | The application command name (1-32 chars).+        createApplicationCommandName :: T.Text,+        -- | The application command description (1-100 chars). Has to be empty for+        -- non-slash commands.+        createApplicationCommandDescription :: T.Text,+        -- | What options the application (max length 25). Has to be `Nothing` for+        -- non-slash commands.+        createApplicationCommandOptions :: Maybe ApplicationCommandOptions,+        -- | Whether the command is enabled by default when the application is added+        -- to a guild.+        createApplicationCommandDefaultPermission :: Bool+      }+  | CreateApplicationCommandUser+      { -- | The application command name (1-32 chars).+        createApplicationCommandName :: T.Text,+        -- | Whether the command is enabled by default when the application is added+        -- to a guild.+        createApplicationCommandDefaultPermission :: Bool+      }+  | CreateApplicationCommandMessage+      { -- | The application command name (1-32 chars).+        createApplicationCommandName :: T.Text,+        -- | Whether the command is enabled by default when the application is added+        -- to a guild.+        createApplicationCommandDefaultPermission :: Bool+      }   deriving (Show, Eq, Read)  instance ToJSON CreateApplicationCommand where-  toJSON CreateApplicationCommand {..} =+  toJSON CreateApplicationCommandChatInput {..} =     object       [ (name, value)         | (name, Just value) <-             [ ("name", toMaybeJSON createApplicationCommandName),               ("description", toMaybeJSON createApplicationCommandDescription),               ("options", toJSON <$> createApplicationCommandOptions),-              ("default_permission", toJSON <$> createApplicationCommandDefaultPermission),-              ("type", toJSON <$> createApplicationCommandType)+              ("default_permission", toMaybeJSON createApplicationCommandDefaultPermission),+              ("type", Just $ Number 1)             ]       ]+  toJSON CreateApplicationCommandUser {..} =+    object+      [ (name, value)+        | (name, Just value) <-+            [ ("name", toMaybeJSON createApplicationCommandName),+              ("default_permission", toMaybeJSON createApplicationCommandDefaultPermission),+              ("type", Just $ Number 2)+            ]+      ]+  toJSON CreateApplicationCommandMessage {..} =+    object+      [ (name, value)+        | (name, Just value) <-+            [ ("name", toMaybeJSON createApplicationCommandName),+              ("default_permission", toMaybeJSON createApplicationCommandDefaultPermission),+              ("type", Just $ Number 3)+            ]+      ] +nameIsValid :: Bool -> T.Text -> Bool+nameIsValid isChatInput name = l >= 1 && l <= 32 && (isChatInput <= T.all (`elem` validChars) name)+  where+    l = T.length name+    validChars = '-' : ['a' .. 'z']+ -- | Create the basics for a chat input (slash command). Use record overwriting -- to enter the other values. The name needs to be all lower case letters, and -- between 1 and 32 characters. The description has to be non-empty and less -- than or equal to 100 characters. createApplicationCommandChatInput :: T.Text -> T.Text -> Maybe CreateApplicationCommand createApplicationCommandChatInput name desc-  | T.all isLower name && not (T.null desc) && l >= 1 && l <= 32 && T.length desc <= 100 = Just $ CreateApplicationCommand name desc Nothing Nothing (Just ApplicationCommandTypeChatInput)+  | nameIsValid True name && not (T.null desc) && T.length desc <= 100 = Just $ CreateApplicationCommandChatInput name desc Nothing True   | otherwise = Nothing-  where-    l = T.length name  -- | Create the basics for a user command. Use record overwriting to enter the -- other values. The name needs to be between 1 and 32 characters. createApplicationCommandUser :: T.Text -> Maybe CreateApplicationCommand createApplicationCommandUser name-  | l >= 1 && l <= 32 = Just $ CreateApplicationCommand name "" Nothing Nothing (Just ApplicationCommandTypeUser)+  | nameIsValid False name = Just $ CreateApplicationCommandUser name True   | otherwise = Nothing-  where-    l = T.length name  -- | Create the basics for a message command. Use record overwriting to enter -- the other values. The name needs to be between 1 and 32 characters. createApplicationCommandMessage :: T.Text -> Maybe CreateApplicationCommand createApplicationCommandMessage name-  | l >= 1 && l <= 32 = Just $ CreateApplicationCommand name "" Nothing Nothing (Just ApplicationCommandTypeMessage)+  | nameIsValid False name = Just $ CreateApplicationCommandMessage name True   | otherwise = Nothing-  where-    l = T.length name  -- | Data type to be used when editing application commands. The specification -- is below. See `CreateApplicationCommand` for an explanation for the -- parameters. -- -- https://discord.com/developers/docs/interactions/application-commands#edit-global-application-command-data EditApplicationCommand = EditApplicationCommand-  { editApplicationCommandName :: Maybe T.Text,-    editApplicationCommandDescription :: Maybe T.Text,-    editApplicationCommandOptions :: Maybe [InternalApplicationCommandOption],-    editApplicationCommandDefaultPermission :: Maybe Bool,-    editApplicationCommandType :: Maybe ApplicationCommandType-  }+data EditApplicationCommand+  = EditApplicationCommandChatInput+      { editApplicationCommandName :: Maybe T.Text,+        editApplicationCommandDescription :: Maybe T.Text,+        editApplicationCommandOptions :: Maybe ApplicationCommandOptions,+        editApplicationCommandDefaultPermission :: Maybe Bool+      }+  | EditApplicationCommandUser+      { editApplicationCommandName :: Maybe T.Text,+        editApplicationCommandDefaultPermission :: Maybe Bool+      }+  | EditApplicationCommandMessage+      { editApplicationCommandName :: Maybe T.Text,+        editApplicationCommandDefaultPermission :: Maybe Bool+      } -instance Default EditApplicationCommand where-  def = EditApplicationCommand Nothing Nothing Nothing Nothing Nothing+defaultEditApplicationCommand :: Int -> EditApplicationCommand+defaultEditApplicationCommand 2 = EditApplicationCommandUser Nothing Nothing+defaultEditApplicationCommand 3 = EditApplicationCommandMessage Nothing Nothing+defaultEditApplicationCommand _ = EditApplicationCommandChatInput Nothing Nothing Nothing Nothing  instance ToJSON EditApplicationCommand where-  toJSON EditApplicationCommand {..} =+  toJSON EditApplicationCommandChatInput {..} =     object       [ (name, value)         | (name, Just value) <-@@ -352,181 +515,27 @@               ("description", toJSON <$> editApplicationCommandDescription),               ("options", toJSON <$> editApplicationCommandOptions),               ("default_permission", toJSON <$> editApplicationCommandDefaultPermission),-              ("type", toJSON <$> editApplicationCommandType)+              ("type", Just $ Number 1)             ]       ]---- | The full information about an application command, obtainable with the--- various get requests. In theory, you never need to construct one of these ---- so if you are, reconsider what you're doing.------ https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-structure-data InternalApplicationCommand = InternalApplicationCommand-  { -- | Unique id of the command.-    internalApplicationCommandId :: ApplicationCommandId,-    -- | The type of the command.-    internalApplicationCommandType :: Maybe ApplicationCommandType,-    -- | Unique id of the parent application (the bot).-    internalApplicationCommandApplicationId :: ApplicationId,-    -- | The guild id of the command if not global.-    internalApplicationCommandGuildId :: Maybe GuildId,-    -- | Must be 1-32 characters.-    internalApplicationCommandName :: T.Text,-    -- | Must be empty for USER and MESSAGE commands, otherwise 1-100 chars.-    internalApplicationCommandDescription :: T.Text,-    -- | CHAT_INPUT only, parameters to command-    internalApplicationCommandOptions :: Maybe [InternalApplicationCommandOption],-    -- | whether the command is enabled by default when the app is added to a-    -- guild. Defaults to true.-    internalApplicationCommandDefaultPermission :: Maybe Bool,-    internalApplicationCommandVersion :: Snowflake-  }-  deriving (Show, Eq, Read)--instance FromJSON InternalApplicationCommand where-  parseJSON =-    withObject-      "InternalApplicationCommand"-      ( \v ->-          InternalApplicationCommand-            <$> v .: "id"-            <*> v .:? "type"-            <*> v .: "application_id"-            <*> v .:? "guild_id"-            <*> v .: "name"-            <*> v .: "description"-            <*> v .:? "options"-            <*> v .:? "default_permission"-            <*> v .: "version"-      )---- | This is the structure that designates different options for slash commands.------ https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-option-structure-data InternalApplicationCommandOption = InternalApplicationCommandOption-  { -- | What the type of this option is.-    internalApplicationCommandOptionType :: ApplicationCommandOptionType,-    -- | The name of the option . 1-32 characters-    internalApplicationCommandOptionName :: T.Text,-    -- | 1-100 characters-    internalApplicationCommandOptionDescription :: T.Text,-    -- | Is the parameter required? default false-    internalApplicationCommandOptionRequired :: Maybe Bool,-    -- | If specified, these are the only valid options to choose from. Type-    -- depends on optionType, and can only be specified for STRING, INTEGER or-    -- NUMBER types.-    internalApplicationCommandOptionChoices :: Maybe [InternalApplicationCommandOptionChoice],-    -- | If the option type is a subcommand or subcommand group type, these are-    -- the parameters to the subcommand.-    internalApplicationCommandOptionOptions :: Maybe [InternalApplicationCommandOption],-    -- | If option is channel type, these are the only channel types allowed.-    internalApplicationCommandOptionChannelTypes :: Maybe [ApplicationCommandChannelType],-    -- | If option is number type, minimum value for the number-    internalApplicationCommandOptionMinVal :: Maybe Scientific,-    -- | if option is number type, maximum value for the number-    internalApplicationCommandOptionMaxVal :: Maybe Scientific,-    -- | Enable auto complete interactions. may not be set to true if choices is present.-    internalApplicationCommandOptionAutocomplete :: Maybe Bool-  }-  deriving (Show, Eq, Read)--instance ToJSON InternalApplicationCommandOption where-  toJSON InternalApplicationCommandOption {..} =+  toJSON EditApplicationCommandUser {..} =     object       [ (name, value)         | (name, Just value) <--            [ ("type", toMaybeJSON internalApplicationCommandOptionType),-              ("name", toMaybeJSON internalApplicationCommandOptionName),-              ("description", toMaybeJSON internalApplicationCommandOptionDescription),-              ("required", toJSON <$> internalApplicationCommandOptionRequired),-              ("choices", toJSON <$> internalApplicationCommandOptionChoices),-              ("options", toJSON <$> internalApplicationCommandOptionOptions),-              ("channel_types", toJSON <$> internalApplicationCommandOptionChannelTypes),-              ("min_val", toJSON <$> internalApplicationCommandOptionMinVal),-              ("max_val", toJSON <$> internalApplicationCommandOptionMaxVal),-              ("autocomplete", toJSON <$> internalApplicationCommandOptionAutocomplete)+            [ ("name", toJSON <$> editApplicationCommandName),+              ("default_permission", toJSON <$> editApplicationCommandDefaultPermission),+              ("type", Just $ Number 2)             ]       ]--instance FromJSON InternalApplicationCommandOption where-  parseJSON =-    withObject-      "InternalApplicationCommandOption"-      ( \v ->-          InternalApplicationCommandOption-            <$> v .: "type"-            <*> v .: "name"-            <*> v .: "description"-            <*> v .:? "required"-            <*> v .:? "choices"-            <*> v .:? "options"-            <*> v .:? "channel_types"-            <*> v .:? "min_val"-            <*> v .:? "max_val"-            <*> v .:? "autocomplete"-      )---- | What type of command option. Can represent a wide variety of types, so--- please check out the documentation below.------ https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-option-type-data ApplicationCommandOptionType-  = -- | A subcommand. It can take further options, excluding sub commands and-    -- sub command groups.-    ApplicationCommandOptionTypeSubcommand-  | -- | A subcommand group. It can take further options, excluding sub command-    -- groups.-    ApplicationCommandOptionTypeSubcommandGroup-  | -- | Can typically be provided with default values.-    ApplicationCommandOptionTypeString-  | -- | Can typically be provided with default values, and possibly with-    -- minimum and maximum values.-    ApplicationCommandOptionTypeInteger-  | ApplicationCommandOptionTypeBoolean-  | ApplicationCommandOptionTypeUser-  | -- | Can be limited in the types of the channel allowed.-    ApplicationCommandOptionTypeChannel-  | ApplicationCommandOptionTypeRole-  | -- | Users and roles.-    ApplicationCommandOptionTypeMentionable-  | -- | Can typically be provided with default values, and possibly with-    -- minimum and maximum values. Represents a double.-    ApplicationCommandOptionTypeNumber-  deriving (Show, Read, Data, Eq)--instance Enum ApplicationCommandOptionType where-  fromEnum ApplicationCommandOptionTypeSubcommand = 1-  fromEnum ApplicationCommandOptionTypeSubcommandGroup = 2-  fromEnum ApplicationCommandOptionTypeString = 3-  fromEnum ApplicationCommandOptionTypeInteger = 4-  fromEnum ApplicationCommandOptionTypeBoolean = 5-  fromEnum ApplicationCommandOptionTypeUser = 6-  fromEnum ApplicationCommandOptionTypeChannel = 7-  fromEnum ApplicationCommandOptionTypeRole = 8-  fromEnum ApplicationCommandOptionTypeMentionable = 9-  fromEnum ApplicationCommandOptionTypeNumber = 10-  toEnum a = fromJust $ lookup a table-    where-      table = makeTable ApplicationCommandOptionTypeSubcommand--instance ToJSON ApplicationCommandOptionType where-  toJSON = toJSON . fromEnum--instance FromJSON ApplicationCommandOptionType where-  parseJSON = withScientific "ApplicationCommandOptionType" (return . toEnum . round)---- | Utility data type to store strings or number types.-data StringNumberValue = StringNumberValueString T.Text | StringNumberValueNumber Scientific | StringNumberValueInteger Integer-  deriving (Show, Read, Eq)--instance ToJSON StringNumberValue where-  toJSON (StringNumberValueString s) = toJSON s-  toJSON (StringNumberValueNumber i) = toJSON i-  toJSON (StringNumberValueInteger i) = toJSON i--instance FromJSON StringNumberValue where-  parseJSON (String t) = return $ StringNumberValueString t-  parseJSON v = (StringNumberValueInteger <$> parseJSON v) <|> (StringNumberValueNumber <$> parseJSON v)+  toJSON EditApplicationCommandMessage {..} =+    object+      [ (name, value)+        | (name, Just value) <-+            [ ("name", toJSON <$> editApplicationCommandName),+              ("default_permission", toJSON <$> editApplicationCommandDefaultPermission),+              ("type", Just $ Number 3)+            ]+      ]  data Choice a = Choice {choiceName :: T.Text, choiceValue :: a}   deriving (Show, Read, Eq)@@ -534,14 +543,6 @@ instance Functor Choice where   fmap f (Choice s a) = Choice s (f a) -type InternalApplicationCommandOptionChoice = Choice StringNumberValue---- | The choices for a particular option.--- data InternalApplicationCommandOptionChoice = InternalApplicationCommandOptionChoice---   { internalApplicationCommandOptionChoiceName :: T.Text,---     internalApplicationCommandOptionChoiceValue :: StringNumberValue---   }---   deriving (Show, Read, Eq) instance (ToJSON a) => ToJSON (Choice a) where   toJSON Choice {..} = object [("name", toJSON choiceName), ("value", toJSON choiceValue)] @@ -555,6 +556,23 @@             <*> v .: "value"       ) +type AutocompleteOrChoice a = Either Bool [Choice a]++instance {-# OVERLAPPING #-} (FromJSON a) => FromJSON (AutocompleteOrChoice a) where+  parseJSON =+    withObject+      "AutocompleteOrChoice"+      ( \v -> do+          mcs <- v .:! "choices"+          case mcs of+            Nothing -> Left <$> v .:? "autocomplete" .!= False+            Just cs -> return $ Right cs+      )++choiceOrAutocompleteToJSON :: (ToJSON a) => AutocompleteOrChoice a -> Pair+choiceOrAutocompleteToJSON (Left b) = ("autocomplete", toJSON b)+choiceOrAutocompleteToJSON (Right cs) = ("choices", toJSON cs)+ -- | The different channel types. -- -- https://discord.com/developers/docs/resources/channel#channel-object-channel-types@@ -575,7 +593,7 @@     ApplicationCommandChannelTypeGuildStore   | -- | A temporary sub-channel within a guild_news channel.     ApplicationCommandChannelTypeGuildNewsThread-  | -- | A temporary sub-channel within a guild_text channel+  | -- | A temporary sub-channel within a guild_text channel.     ApplicationCommandChannelTypeGuildPublicThread   | -- | A temporary sub-channel within a GUILD_TEXT channel that is only     -- viewable by those invited and those with the MANAGE_THREADS permission@@ -584,36 +602,34 @@     ApplicationCommandChannelTypeGuildStageVoice   deriving (Show, Read, Data, Eq) -instance Enum ApplicationCommandChannelType where-  fromEnum ApplicationCommandChannelTypeGuildText = 0-  fromEnum ApplicationCommandChannelTypeDM = 1-  fromEnum ApplicationCommandChannelTypeGuildVoice = 2-  fromEnum ApplicationCommandChannelTypeGroupDM = 3-  fromEnum ApplicationCommandChannelTypeGuildCategory = 4-  fromEnum ApplicationCommandChannelTypeGuildNews = 5-  fromEnum ApplicationCommandChannelTypeGuildStore = 6-  fromEnum ApplicationCommandChannelTypeGuildNewsThread = 10-  fromEnum ApplicationCommandChannelTypeGuildPublicThread = 11-  fromEnum ApplicationCommandChannelTypeGuildPrivateThread = 12-  fromEnum ApplicationCommandChannelTypeGuildStageVoice = 13-  toEnum a = fromJust $ lookup a table-    where-      table = makeTable ApplicationCommandChannelTypeGuildText+instance InternalDiscordEnum ApplicationCommandChannelType where+  discordTypeStartValue = ApplicationCommandChannelTypeGuildText+  fromDiscordType ApplicationCommandChannelTypeGuildText = 0+  fromDiscordType ApplicationCommandChannelTypeDM = 1+  fromDiscordType ApplicationCommandChannelTypeGuildVoice = 2+  fromDiscordType ApplicationCommandChannelTypeGroupDM = 3+  fromDiscordType ApplicationCommandChannelTypeGuildCategory = 4+  fromDiscordType ApplicationCommandChannelTypeGuildNews = 5+  fromDiscordType ApplicationCommandChannelTypeGuildStore = 6+  fromDiscordType ApplicationCommandChannelTypeGuildNewsThread = 10+  fromDiscordType ApplicationCommandChannelTypeGuildPublicThread = 11+  fromDiscordType ApplicationCommandChannelTypeGuildPrivateThread = 12+  fromDiscordType ApplicationCommandChannelTypeGuildStageVoice = 13  instance ToJSON ApplicationCommandChannelType where-  toJSON = toJSON . fromEnum+  toJSON = toJSON . fromDiscordType  instance FromJSON ApplicationCommandChannelType where-  parseJSON = withScientific "ApplicationCommandChannelType" (return . toEnum . round)+  parseJSON = discordTypeParseJSON "ApplicationCommandChannelType"  data GuildApplicationCommandPermissions = GuildApplicationCommandPermissions-  { -- | The id of the command+  { -- | The id of the command.     guildApplicationCommandPermissionsId :: ApplicationCommandId,-    -- | The id of the application+    -- | The id of the application.     guildApplicationCommandPermissionsApplicationId :: ApplicationId,-    -- | The id of the guild+    -- | The id of the guild.     guildApplicationCommandPermissionsGuildId :: GuildId,-    -- | The permissions for the command in the guild+    -- | The permissions for the command in the guild.     guildApplicationCommandPermissionsPermissions :: [ApplicationCommandPermissions]   }   deriving (Show, Eq, Ord, Read)@@ -642,12 +658,14 @@             ]       ] +-- | Application command permissions allow you to enable or disable commands for+-- specific users or roles within a guild. data ApplicationCommandPermissions = ApplicationCommandPermissions-  { -- | The id of the role or user+  { -- | The id of the role or user.     applicationCommandPermissionsId :: Snowflake,-    -- | Choose either role or user-    applicationCommandPermissionsType :: ApplicationCommandPermissionType,-    -- | Whether to allow or not+    -- | Choose either role (1) or user (2).+    applicationCommandPermissionsType :: Integer,+    -- | Whether to allow or not.     applicationCommandPermissionsPermission :: Bool   }   deriving (Show, Eq, Ord, Read)@@ -673,21 +691,3 @@               ("permission", toMaybeJSON applicationCommandPermissionsPermission)             ]       ]--data ApplicationCommandPermissionType-  = ApplicationCommandPermissionTypeRole-  | ApplicationCommandPermissionTypeUser-  deriving (Show, Eq, Ord, Read, Data)--instance Enum ApplicationCommandPermissionType where-  fromEnum ApplicationCommandPermissionTypeRole = 1-  fromEnum ApplicationCommandPermissionTypeUser = 2-  toEnum a = fromJust $ lookup a table-    where-      table = makeTable ApplicationCommandPermissionTypeRole--instance ToJSON ApplicationCommandPermissionType where-  toJSON = toJSON . fromEnum--instance FromJSON ApplicationCommandPermissionType where-  parseJSON = withScientific "ApplicationCommandPermissionType" (return . toEnum . round)
src/Discord/Internal/Types/Channel.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeApplications #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE DeriveDataTypeable #-} @@ -17,9 +18,8 @@ import Discord.Internal.Types.User (User(..), GuildMember) import Discord.Internal.Types.Embed import Data.Data (Data)-import Data.Maybe (fromJust) import Data.Bits-import Discord.Internal.Types.Components (Component, Emoji)+import Discord.Internal.Types.Components (ComponentActionRow, Emoji)  -- | Guild channels represent an isolated set of users and messages in a Guild (Server) data Channel@@ -292,16 +292,15 @@   , messageWebhookId          :: Maybe WebhookId          -- ^ The webhook id of the webhook that made the message   , messageType               :: MessageType              -- ^ What type of message is this.   , messageActivity           :: Maybe MessageActivity    -- ^ sent with Rich Presence-related chat embeds-  -- , messageApplication  :: Maybe ??? -- ^ a partial application object   , messageApplicationId      :: Maybe ApplicationId      -- ^ if the message is a response to an Interaction, this is the id of the interaction's application   , messageReference          :: Maybe MessageReference   -- ^ Reference IDs of the original message   , messageFlags              :: Maybe MessageFlags       -- ^ Various message flags   , messageReferencedMessage  :: Maybe Message            -- ^ The full original message   , messageInteraction        :: Maybe MessageInteraction -- ^ sent if message is an interaction response   , messageThread             :: Maybe Channel            -- ^ the thread that was started from this message, includes thread member object-  , messageComponents         :: Maybe [Component]        -- ^ sent if the message contains components like buttons, action rows, or other interactive components-  , messageStickerItems       :: Maybe [StickerItem]      -- ^ sent if the message contains stickers -  } deriving (Show, Read, Eq, Ord)+  , messageComponents         :: Maybe [ComponentActionRow]        -- ^ sent if the message contains components like buttons, action rows, or other interactive components+  , messageStickerItems       :: Maybe [StickerItem]      -- ^ sent if the message contains stickers+  } deriving (Show, Eq, Ord, Read)  instance FromJSON Message where   parseJSON = withObject "Message" $ \o ->@@ -449,19 +448,17 @@   | StickerFormatTypeLOTTIE   deriving (Show, Read, Eq, Ord, Data) -instance Enum StickerFormatType where-  fromEnum StickerFormatTypePNG = 1-  fromEnum StickerFormatTypeAPNG = 2-  fromEnum StickerFormatTypeLOTTIE = 3-  toEnum a = fromJust $ lookup a table-    where-      table = makeTable StickerFormatTypePNG+instance InternalDiscordEnum StickerFormatType where+  discordTypeStartValue = StickerFormatTypePNG+  fromDiscordType StickerFormatTypePNG = 1+  fromDiscordType StickerFormatTypeAPNG = 2+  fromDiscordType StickerFormatTypeLOTTIE = 3  instance ToJSON StickerFormatType where-  toJSON = toJSON . fromEnum+  toJSON = toJSON . fromDiscordType  instance FromJSON StickerFormatType where-  parseJSON = withScientific "StickerFormatType" (return . toEnum . round)+  parseJSON = discordTypeParseJSON "StickerFormatType"  -- | Represents an attached to a message file. data Attachment = Attachment@@ -539,9 +536,9 @@   data MessageType-  = MessageTypeDefault -  | MessageTypeRecipientAdd -  | MessageTypeRecipientRemove +  = MessageTypeDefault+  | MessageTypeRecipientAdd+  | MessageTypeRecipientRemove   | MessageTypeCall   | MessageTypeChannelNameChange   | MessageTypeChannelIconChange@@ -564,39 +561,37 @@   | MessageTypeContextMenuCommand   deriving (Show, Read, Data, Eq, Ord) -instance Enum MessageType where-  fromEnum MessageTypeDefault = 0-  fromEnum MessageTypeRecipientAdd = 1-  fromEnum MessageTypeRecipientRemove = 2-  fromEnum MessageTypeCall = 3-  fromEnum MessageTypeChannelNameChange = 4-  fromEnum MessageTypeChannelIconChange = 5-  fromEnum MessageTypeChannelPinnedMessage = 6-  fromEnum MessageTypeGuildMemberJoin = 7-  fromEnum MessageTypeUserPremiumGuildSubscription = 8-  fromEnum MessageTypeUserPremiumGuildSubscriptionTier1 = 9-  fromEnum MessageTypeUserPremiumGuildSubscriptionTier2 = 10-  fromEnum MessageTypeUserPremiumGuildSubscriptionTier3 = 11-  fromEnum MessageTypeChannelFollowAdd = 12-  fromEnum MessageTypeGuildDiscoveryDisqualified = 14-  fromEnum MessageTypeGuildDiscoveryRequalified = 15-  fromEnum MessageTypeGuildDiscoveryGracePeriodInitialWarning = 16-  fromEnum MessageTypeGuildDiscoveryGracePeriodFinalWarning = 17-  fromEnum MessageTypeThreadCreated = 18-  fromEnum MessageTypeReply = 19-  fromEnum MessageTypeChatInputCommand = 20-  fromEnum MessageTypeThreadStarterMessage = 21-  fromEnum MessageTypeGuildInviteReminder = 22-  fromEnum MessageTypeContextMenuCommand = 23-  toEnum a = fromJust $ lookup a table-    where-      table = makeTable MessageTypeDefault+instance InternalDiscordEnum MessageType where+  discordTypeStartValue = MessageTypeDefault+  fromDiscordType MessageTypeDefault = 0+  fromDiscordType MessageTypeRecipientAdd = 1+  fromDiscordType MessageTypeRecipientRemove = 2+  fromDiscordType MessageTypeCall = 3+  fromDiscordType MessageTypeChannelNameChange = 4+  fromDiscordType MessageTypeChannelIconChange = 5+  fromDiscordType MessageTypeChannelPinnedMessage = 6+  fromDiscordType MessageTypeGuildMemberJoin = 7+  fromDiscordType MessageTypeUserPremiumGuildSubscription = 8+  fromDiscordType MessageTypeUserPremiumGuildSubscriptionTier1 = 9+  fromDiscordType MessageTypeUserPremiumGuildSubscriptionTier2 = 10+  fromDiscordType MessageTypeUserPremiumGuildSubscriptionTier3 = 11+  fromDiscordType MessageTypeChannelFollowAdd = 12+  fromDiscordType MessageTypeGuildDiscoveryDisqualified = 14+  fromDiscordType MessageTypeGuildDiscoveryRequalified = 15+  fromDiscordType MessageTypeGuildDiscoveryGracePeriodInitialWarning = 16+  fromDiscordType MessageTypeGuildDiscoveryGracePeriodFinalWarning = 17+  fromDiscordType MessageTypeThreadCreated = 18+  fromDiscordType MessageTypeReply = 19+  fromDiscordType MessageTypeChatInputCommand = 20+  fromDiscordType MessageTypeThreadStarterMessage = 21+  fromDiscordType MessageTypeGuildInviteReminder = 22+  fromDiscordType MessageTypeContextMenuCommand = 23  instance ToJSON MessageType where-  toJSON = toJSON . fromEnum+  toJSON = toJSON . fromDiscordType  instance FromJSON MessageType where-  parseJSON = withScientific "MessageType" (return . toEnum . round)+  parseJSON = discordTypeParseJSON "MessageType"  data MessageActivity = MessageActivity   { messageActivityType :: MessageActivityType@@ -622,23 +617,21 @@   | MessageActivityTypeJoinRequest -- ^ Request to join a Rich Presence event   deriving (Show, Read, Data, Eq, Ord) -instance Enum MessageActivityType where-  fromEnum MessageActivityTypeJoin = 1-  fromEnum MessageActivityTypeSpectate = 2-  fromEnum MessageActivityTypeListen = 3-  fromEnum MessageActivityTypeJoinRequest = 4-  toEnum a = fromJust $ lookup a table-    where-      table = makeTable MessageActivityTypeJoin+instance InternalDiscordEnum MessageActivityType where+  discordTypeStartValue = MessageActivityTypeJoin+  fromDiscordType MessageActivityTypeJoin = 1+  fromDiscordType MessageActivityTypeSpectate = 2+  fromDiscordType MessageActivityTypeListen = 3+  fromDiscordType MessageActivityTypeJoinRequest = 4  instance ToJSON MessageActivityType where-  toJSON = toJSON . fromEnum+  toJSON = toJSON . fromDiscordType  instance FromJSON MessageActivityType where-  parseJSON = withScientific "MessageActivityType" (return . toEnum . round)+  parseJSON = discordTypeParseJSON "MessageActivityType"  -- | Types of flags to attach to the message.-data MessageFlag = +data MessageFlag =     MessageFlagCrossposted   | MessageFlagIsCrosspost   | MessageFlagSupressEmbeds@@ -652,35 +645,36 @@ newtype MessageFlags = MessageFlags [MessageFlag]   deriving (Show, Read, Eq, Ord) -instance Enum MessageFlag where-  fromEnum MessageFlagCrossposted = 1 `shift` 0-  fromEnum MessageFlagIsCrosspost = 1 `shift` 1-  fromEnum MessageFlagSupressEmbeds = 1 `shift` 2-  fromEnum MessageFlagSourceMessageDeleted = 1 `shift` 3-  fromEnum MessageFlagUrgent = 1 `shift` 4-  fromEnum MessageFlagHasThread = 1 `shift` 5-  fromEnum MessageFlagEphemeral = 1 `shift` 6-  fromEnum MessageFlagLoading = 1 `shift` 7-  toEnum a = fromJust $ lookup a table-    where-      table = makeTable MessageFlagCrossposted+instance InternalDiscordEnum MessageFlag where+  discordTypeStartValue = MessageFlagCrossposted+  fromDiscordType MessageFlagCrossposted = 1 `shift` 0+  fromDiscordType MessageFlagIsCrosspost = 1 `shift` 1+  fromDiscordType MessageFlagSupressEmbeds = 1 `shift` 2+  fromDiscordType MessageFlagSourceMessageDeleted = 1 `shift` 3+  fromDiscordType MessageFlagUrgent = 1 `shift` 4+  fromDiscordType MessageFlagHasThread = 1 `shift` 5+  fromDiscordType MessageFlagEphemeral = 1 `shift` 6+  fromDiscordType MessageFlagLoading = 1 `shift` 7  instance ToJSON MessageFlags where-  toJSON (MessageFlags fs) = Number $ fromInteger $ fromIntegral $ foldr (.|.) 0 (fromEnum <$> fs)+  toJSON (MessageFlags fs) = Number $ fromInteger $ fromIntegral $ foldr (.|.) 0 (fromDiscordType <$> fs)  -- TODO: maybe make this a type class or something - the ability to handle flags automatically would be Very Good.  instance FromJSON MessageFlags where-  parseJSON = withScientific "MessageFlags" (\s -> let i = round s in if i /= (i .&. range) then fail "could not get message flags" else return $ MessageFlags (snd <$> filter (\(i',_) -> i .&. i' == i') table))-    where -      table = makeTable MessageFlagCrossposted-      range = sum $ fst <$> table+  parseJSON = withScientific "MessageFlags" $ \s ->+      let i = round s+          range = sum $ fst <$> (discordTypeTable @MessageFlag)+      in if i /= (i .&. range)+         then fail "could not get message flags"+         else return $ MessageFlags (snd <$> filter (\(i',_) -> i .&. i' == i') discordTypeTable) +-- | This is sent on the message object when the message is a response to an Interaction without an existing message (i.e., any non-component interaction). data MessageInteraction = MessageInteraction-  { messageInteractionId :: InteractionId-  , messageInteractionType :: InteractionType-  , messageInteractionName :: T.Text-  , messageInteractionUser :: User+  { messageInteractionId :: InteractionId -- ^ Id of the interaction+  , messageInteractionType :: Integer -- ^ Type of the interaction (liekly always application command)+  , messageInteractionName :: T.Text -- ^ Name of the interaction+  , messageInteractionUser :: User -- ^ User who invoked the interaction   } deriving (Show, Eq, Ord, Read)  instance ToJSON MessageInteraction where@@ -698,4 +692,3 @@                        <*> o .: "type"                        <*> o .: "name"                        <*> o .: "user"-
+ src/Discord/Internal/Types/Color.hs view
@@ -0,0 +1,164 @@+{-# LANGUAGE DeriveDataTypeable #-}++-- | Data structures pertaining to Discord Colors+module Discord.Internal.Types.Color where+++import Text.Read (readMaybe)+import Data.Maybe (fromMaybe)+import Data.Char (toLower)+import Data.Aeson+import Data.Data+import Control.Applicative (Alternative((<|>)))+import Data.Bits (Bits((.&.)))+++import Discord.Internal.Types.Prelude (InternalDiscordEnum(..))++-- | Color names+-- Color is a bit of a mess on discord embeds.+-- I've here stolen the pallet list from https://gist.github.com/thomasbnt/b6f455e2c7d743b796917fa3c205f812+--+-- All discord embed color stuff is credited to+-- https://github.com/WarwickTabletop/tablebot/pull/34+data DiscordColor+  = DiscordColorRGB Integer Integer Integer+  | DiscordColorDefault+  | DiscordColorAqua+  | DiscordColorDarkAqua+  | DiscordColorGreen+  | DiscordColorDarkGreen+  | DiscordColorBlue+  | DiscordColorDarkBlue+  | DiscordColorPurple+  | DiscordColorDarkPurple+  | DiscordColorLuminousVividPink+  | DiscordColorDarkVividPink+  | DiscordColorGold+  | DiscordColorDarkGold+  | DiscordColorOrange+  | DiscordColorDarkOrange+  | DiscordColorRed+  | DiscordColorDarkRed+  | DiscordColorGray+  | DiscordColorDarkGray+  | DiscordColorDarkerGray+  | DiscordColorLightGray+  | DiscordColorNavy+  | DiscordColorDarkNavy+  | DiscordColorYellow+  | DiscordColorDiscordWhite+  | DiscordColorDiscordBlurple+  | DiscordColorDiscordGrayple+  | DiscordColorDiscordDarkButNotBlack+  | DiscordColorDiscordNotQuiteBlack+  | DiscordColorDiscordGreen+  | DiscordColorDiscordYellow+  | DiscordColorDiscordFuschia+  | DiscordColorDiscordRed+  | DiscordColorDiscordBlack+  deriving (Show, Read, Eq, Ord, Data)++-- | @hexToRGB@ attempts to convert a potential hex string into its decimal RGB+-- components.+hexToRGB :: String -> Maybe (Integer, Integer, Integer)+hexToRGB hex = do+  let h = map toLower hex+  r <- take2 h >>= toDec+  g <- drop2 h >>= take2 >>= toDec+  b <- drop2 h >>= drop2 >>= toDec+  return (r, g, b)+  where+    take2 (a:b:_) = Just [a, b]+    take2 _ = Nothing+    drop2 (_ : _ : as) = Just as+    drop2 _ = Nothing+    toDec :: String -> Maybe Integer+    toDec [s, u] = do+      a <- charToDec s+      b <- charToDec u+      return $ a * 16 + b+    toDec _ = Nothing+    charToDec :: Char -> Maybe Integer+    charToDec 'a' = Just 10+    charToDec 'b' = Just 11+    charToDec 'c' = Just 12+    charToDec 'd' = Just 13+    charToDec 'e' = Just 14+    charToDec 'f' = Just 15+    charToDec c = readMaybe [c]++-- | @hexToDiscordColor@ converts a potential hex string into a DiscordColor,+-- evaluating to Default if it fails.+hexToDiscordColor :: String -> DiscordColor+hexToDiscordColor hex =+  let (r, g, b) = fromMaybe (0, 0, 0) $ hexToRGB hex+   in DiscordColorRGB r g b++colorToInternal :: DiscordColor -> Integer+-- colorToInternal (DiscordColor i) = i+colorToInternal (DiscordColorRGB r g b) = (r * 256 + g) * 256 + b+colorToInternal DiscordColorDefault = 0+colorToInternal DiscordColorAqua = 1752220+colorToInternal DiscordColorDarkAqua = 1146986+colorToInternal DiscordColorGreen = 3066993+colorToInternal DiscordColorDarkGreen = 2067276+colorToInternal DiscordColorBlue = 3447003+colorToInternal DiscordColorDarkBlue = 2123412+colorToInternal DiscordColorPurple = 10181046+colorToInternal DiscordColorDarkPurple = 7419530+colorToInternal DiscordColorLuminousVividPink = 15277667+colorToInternal DiscordColorDarkVividPink = 11342935+colorToInternal DiscordColorGold = 15844367+colorToInternal DiscordColorDarkGold = 12745742+colorToInternal DiscordColorOrange = 15105570+colorToInternal DiscordColorDarkOrange = 11027200+colorToInternal DiscordColorRed = 15158332+colorToInternal DiscordColorDarkRed = 10038562+colorToInternal DiscordColorGray = 9807270+colorToInternal DiscordColorDarkGray = 9936031+colorToInternal DiscordColorDarkerGray = 8359053+colorToInternal DiscordColorLightGray = 12370112+colorToInternal DiscordColorNavy = 3426654+colorToInternal DiscordColorDarkNavy = 2899536+colorToInternal DiscordColorYellow = 16776960+colorToInternal DiscordColorDiscordWhite = 16777215+colorToInternal DiscordColorDiscordBlurple = 5793266+colorToInternal DiscordColorDiscordGrayple = 10070709+colorToInternal DiscordColorDiscordDarkButNotBlack = 2895667+colorToInternal DiscordColorDiscordNotQuiteBlack = 2303786+colorToInternal DiscordColorDiscordGreen = 5763719+colorToInternal DiscordColorDiscordYellow = 16705372+colorToInternal DiscordColorDiscordFuschia = 15418782+colorToInternal DiscordColorDiscordRed = 15548997+colorToInternal DiscordColorDiscordBlack = 16777215++convertToRGB :: Integer -> DiscordColor+convertToRGB i = DiscordColorRGB (div i (256 * 256) .&. 255) (div i 256 .&. 255) (i .&. 255)++instance InternalDiscordEnum DiscordColor where+  discordTypeStartValue = DiscordColorDefault+  fromDiscordType = fromIntegral . colorToInternal+  discordTypeTable = map (\d -> (fromDiscordType d, d)) (makeTable discordTypeStartValue)+    where+      makeTable :: Data b => b -> [b]+      makeTable t = map (fromConstrB (fromConstr (toConstr (0 :: Int)))) (dataTypeConstrs $ dataTypeOf t)++instance ToJSON DiscordColor where+  toJSON = toJSON . fromDiscordType++instance FromJSON DiscordColor where+  parseJSON =+    withScientific+      "DiscordColor"+      ( \v ->+          discordTypeParseJSON "DiscordColor" (Number v)+            <|> ( case maybeInt v >>= Just . convertToRGB of+                    Nothing -> fail $ "could not parse discord color: " ++ show v+                    Just d -> return d+                )+      )+    where+      maybeInt i+        | fromIntegral (round i) == i = Just $ round i+        | otherwise = Nothing
src/Discord/Internal/Types/Components.hs view
@@ -1,219 +1,278 @@ {-# LANGUAGE DataKinds #-}-{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-}+{-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} -module Discord.Internal.Types.Components where+module Discord.Internal.Types.Components+  ( ComponentActionRow (..),+    ComponentButton (..),+    ButtonStyle (..),+    mkButton,+    ComponentSelectMenu (..),+    mkSelectMenu,+    SelectOption (..),+    mkSelectOption,+    Emoji (..),+    mkEmoji,+  )+where  import Data.Aeson-import Data.Data (Data)-import Data.Maybe (fromJust, fromMaybe)+import Data.Aeson.Types (Parser)+import Data.Foldable (Foldable (toList))+import Data.Scientific (Scientific) import qualified Data.Text as T-import Data.Tuple (swap)-import Discord.Internal.Types.Prelude (EmojiId, Internals (..), RoleId, makeTable, toMaybeJSON)+import Discord.Internal.Types.Prelude (EmojiId, RoleId, toMaybeJSON) import Discord.Internal.Types.User (User)-import qualified Network.HTTP.Req as R +data ComponentActionRow = ComponentActionRowButton [ComponentButton] | ComponentActionRowSelectMenu ComponentSelectMenu+  deriving (Show, Eq, Ord, Read)++instance FromJSON ComponentActionRow where+  parseJSON =+    withObject+      "ComponentActionRow"+      ( \cs -> do+          a <- cs .: "components" :: Parser Array+          let a' = toList a+          case a' of+            [] -> return $ ComponentActionRowButton []+            (c : _) ->+              withObject+                "ComponentActionRow item"+                ( \v -> do+                    t <- v .: "type" :: Parser Int+                    case t of+                      2 -> ComponentActionRowButton <$> mapM parseJSON a'+                      3 -> ComponentActionRowSelectMenu <$> parseJSON c+                      _ -> fail $ "unknown component type: " ++ show t+                )+                c+      )++instance ToJSON ComponentActionRow where+  toJSON (ComponentActionRowButton bs) = object [("type", Number 1), ("components", toJSON bs)]+  toJSON (ComponentActionRowSelectMenu bs) = object [("type", Number 1), ("components", toJSON [bs])]+ -- | Component type for a button, split into URL button and not URL button. -- -- Don't directly send button components - they need to be within an action row. data ComponentButton   = ComponentButton-      { componentButtonCustomId :: T.Text,+      { -- | Dev indentifier+        componentButtonCustomId :: T.Text,+        -- | Whether the button is disabled         componentButtonDisabled :: Bool,+        -- | What is the style of the button         componentButtonStyle :: ButtonStyle,+        -- | What is the user-facing label of the button         componentButtonLabel :: T.Text,+        -- | What emoji is displayed on the button         componentButtonEmoji :: Maybe Emoji       }   | ComponentButtonUrl-      { componentButtonUrl :: R.Url 'R.Https,+      { -- | The url for the button. If this is not a valid url, everything will+        -- break+        componentButtonUrl :: T.Text,+        -- | Whether the button is disabled         componentButtonDisabled :: Bool,+        -- | What is the user-facing label of the button         componentButtonLabel :: T.Text,+        -- | What emoji is displayed on the button         componentButtonEmoji :: Maybe Emoji       }-  deriving (Show, Eq)+  deriving (Show, Eq, Ord, Read) -data ButtonStyle = ButtonStylePrimary | ButtonStyleSecondary | ButtonStyleSuccess | ButtonStyleDanger-  deriving (Show, Eq, Read)+-- | Takes the label and the custom id of the button that is to be generated.+mkButton :: T.Text -> T.Text -> ComponentButton+mkButton label customId = ComponentButton customId False ButtonStyleSecondary label Nothing -buttonStyles :: [(ButtonStyle, InternalButtonStyle)]-buttonStyles =-  [ (ButtonStylePrimary, InternalButtonStylePrimary),-    (ButtonStyleSecondary, InternalButtonStyleSecondary),-    (ButtonStyleSuccess, InternalButtonStyleSuccess),-    (ButtonStyleDanger, InternalButtonStyleDanger)-  ]+instance FromJSON ComponentButton where+  parseJSON =+    withObject+      "ComponentButton"+      ( \v -> do+          t <- v .: "type" :: Parser Int+          case t of+            2 -> do+              disabled <- v .:? "disabled" .!= False+              label <- v .: "label"+              partialEmoji <- v .:? "emoji"+              style <- v .: "style" :: Parser Scientific+              case style of+                5 ->+                  ComponentButtonUrl+                    <$> v .: "url"+                    <*> return disabled+                    <*> return label+                    <*> return partialEmoji+                _ ->+                  ComponentButton+                    <$> v .: "custom_id"+                    <*> return disabled+                    <*> parseJSON (Number style)+                    <*> return label+                    <*> return partialEmoji+            _ -> fail "expected button type, got a different component"+      ) -instance Internals ButtonStyle InternalButtonStyle where-  toInternal a = fromJust (lookup a buttonStyles)-  fromInternal b = lookup b (swap <$> buttonStyles)+instance ToJSON ComponentButton where+  toJSON ComponentButtonUrl {..} =+    object+      [ (name, value)+        | (name, Just value) <-+            [ ("type", Just $ Number 2),+              ("style", Just $ Number 5),+              ("label", toMaybeJSON componentButtonLabel),+              ("disabled", toMaybeJSON componentButtonDisabled),+              ("url", toMaybeJSON componentButtonUrl),+              ("emoji", toJSON <$> componentButtonEmoji)+            ]+      ]+  toJSON ComponentButton {..} =+    object+      [ (name, value)+        | (name, Just value) <-+            [ ("type", Just $ Number 2),+              ("style", Just $ toJSON componentButtonStyle),+              ("label", toMaybeJSON componentButtonLabel),+              ("disabled", toMaybeJSON componentButtonDisabled),+              ("custom_id", toMaybeJSON componentButtonCustomId),+              ("emoji", toJSON <$> componentButtonEmoji)+            ]+      ] +-- | Buttton colors.+data ButtonStyle+  = -- | Blurple button+    ButtonStylePrimary+  | -- | Grey button+    ButtonStyleSecondary+  | -- | Green button+    ButtonStyleSuccess+  | -- | Red button+    ButtonStyleDanger+  deriving (Show, Eq, Ord, Read)++instance FromJSON ButtonStyle where+  parseJSON =+    withScientific+      "ButtonStyle"+      ( \case+          1 -> return ButtonStylePrimary+          2 -> return ButtonStyleSecondary+          3 -> return ButtonStyleSuccess+          4 -> return ButtonStyleDanger+          _ -> fail "unrecognised non-url button style"+      )++instance ToJSON ButtonStyle where+  toJSON ButtonStylePrimary = Number 1+  toJSON ButtonStyleSecondary = Number 2+  toJSON ButtonStyleSuccess = Number 3+  toJSON ButtonStyleDanger = Number 4+ -- | Component type for a select menus. -- -- Don't directly send select menus - they need to be within an action row. data ComponentSelectMenu = ComponentSelectMenu-  { componentSelectMenuCustomId :: T.Text,+  { -- | Dev identifier+    componentSelectMenuCustomId :: T.Text,+    -- | Whether the select menu is disabled     componentSelectMenuDisabled :: Bool,+    -- | What options are in this select menu (up to 25)     componentSelectMenuOptions :: [SelectOption],+    -- | Placeholder text if nothing is selected     componentSelectMenuPlaceholder :: Maybe T.Text,+    -- | Minimum number of values to select (def 1, min 0, max 25)     componentSelectMenuMinValues :: Maybe Integer,+    -- | Maximum number of values to select (def 1, max 25)     componentSelectMenuMaxValues :: Maybe Integer   }-  deriving (Show, Eq, Read)--data ComponentActionRow = ComponentActionRowButton [ComponentButton] | ComponentActionRowSelectMenu ComponentSelectMenu-  deriving (Show, Eq)+  deriving (Show, Eq, Ord, Read) -validPartialEmoji :: Emoji -> Maybe Emoji-validPartialEmoji Emoji {..} = do-  eid <- emojiId-  ean <- emojiAnimated-  return $ Emoji (Just eid) emojiName Nothing Nothing Nothing (Just ean)+-- | Takes the custom id and the options of the select menu that is to be+-- generated.+mkSelectMenu :: T.Text -> [SelectOption] -> ComponentSelectMenu+mkSelectMenu customId sos = ComponentSelectMenu customId False sos Nothing Nothing Nothing -instance Internals ComponentActionRow Component where-  toInternal (ComponentActionRowButton as) = Component ComponentTypeActionRow Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing (Just (toInternal' <$> as))-    where-      toInternal' ComponentButtonUrl {..} = Component ComponentTypeButton Nothing (Just componentButtonDisabled) (Just InternalButtonStyleLink) (Just componentButtonLabel) componentButtonEmoji (Just (R.renderUrl componentButtonUrl)) Nothing Nothing Nothing Nothing Nothing-      toInternal' ComponentButton {..} = Component ComponentTypeButton (Just componentButtonCustomId) (Just componentButtonDisabled) (Just (toInternal componentButtonStyle)) (Just componentButtonLabel) componentButtonEmoji Nothing Nothing Nothing Nothing Nothing Nothing-  toInternal (ComponentActionRowSelectMenu ComponentSelectMenu {..}) = Component ComponentTypeActionRow Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing (Just [Component ComponentTypeSelectMenu (Just componentSelectMenuCustomId) (Just componentSelectMenuDisabled) Nothing Nothing Nothing Nothing (Just componentSelectMenuOptions) componentSelectMenuPlaceholder componentSelectMenuMinValues componentSelectMenuMaxValues Nothing])+instance FromJSON ComponentSelectMenu where+  parseJSON =+    withObject+      "ComponentSelectMenu"+      ( \v ->+          do+            t <- v .: "type" :: Parser Int+            case t of+              3 ->+                ComponentSelectMenu+                  <$> v .: "custom_id"+                  <*> v .:? "disabled" .!= False+                  <*> v .: "options"+                  <*> v .:? "placeholder"+                  <*> v .:? "min_values"+                  <*> v .:? "max_values"+              _ -> fail "expected select menu type, got different component"+      ) -  fromInternal Component {componentType = ComponentTypeActionRow, componentComponents = (Just (Component {componentType = ComponentTypeSelectMenu, ..} : _))} = do-    cid <- componentCustomId-    cd <- componentDisabled-    co <- componentOptions-    return $ ComponentActionRowSelectMenu $ ComponentSelectMenu cid cd co componentPlaceholder componentMinValues componentMaxValues-  fromInternal Component {componentType = ComponentTypeActionRow, componentComponents = compComps} = compComps >>= mapM fromInternal' >>= Just . ComponentActionRowButton-    where-      fromInternal' Component {componentType = ComponentTypeButton, componentStyle = Just InternalButtonStyleLink, ..} = do-        url <- R.https <$> componentUrl-        label <- componentLabel-        return $ ComponentButtonUrl url (fromMaybe False componentDisabled) label componentEmoji-      fromInternal' Component {componentType = ComponentTypeButton, ..} = do-        customId <- componentCustomId-        label <- componentLabel-        style <- componentStyle >>= fromInternal-        return $ ComponentButton customId (fromMaybe False componentDisabled) style label componentEmoji-      fromInternal' _ = Nothing-  fromInternal _ = Nothing+instance ToJSON ComponentSelectMenu where+  toJSON ComponentSelectMenu {..} =+    object+      [ (name, value)+        | (name, Just value) <-+            [ ("type", Just $ Number 3),+              ("custom_id", toMaybeJSON componentSelectMenuCustomId),+              ("disabled", toMaybeJSON componentSelectMenuDisabled),+              ("options", toMaybeJSON componentSelectMenuOptions),+              ("placeholder", toJSON <$> componentSelectMenuPlaceholder),+              ("min_values", toJSON <$> componentSelectMenuMinValues),+              ("max_values", toJSON <$> componentSelectMenuMaxValues)+            ]+      ] -data Component = Component-  { componentType :: ComponentType,-    -- | Buttons and Select Menus only-    componentCustomId :: Maybe T.Text,-    -- | Buttons and Select Menus only-    componentDisabled :: Maybe Bool,-    -- | Button only-    componentStyle :: Maybe InternalButtonStyle,-    -- | Button only-    componentLabel :: Maybe T.Text,-    -- | Button only-    componentEmoji :: Maybe Emoji,-    -- | Button only, link buttons only-    componentUrl :: Maybe T.Text,-    -- | Select Menus only, max 25-    componentOptions :: Maybe [SelectOption],-    -- | Select Menus only, max 100 chars-    componentPlaceholder :: Maybe T.Text,-    -- | Select Menus only, min values to choose, default 1-    componentMinValues :: Maybe Integer,-    -- | Select Menus only, max values to choose, default 1-    componentMaxValues :: Maybe Integer,-    -- | Action Rows only-    componentComponents :: Maybe [Component]+-- | A single option in a select menu.+data SelectOption = SelectOption+  { -- | User facing option name+    selectOptionLabel :: T.Text,+    -- | Dev facing option value+    selectOptionValue :: T.Text,+    -- | additional description+    selectOptionDescription :: Maybe T.Text,+    -- | A partial emoji to show with the object (id, name, animated)+    selectOptionEmoji :: Maybe Emoji,+    -- | Use this value by default+    selectOptionDefault :: Maybe Bool   }   deriving (Show, Eq, Ord, Read) -instance FromJSON Component where-  parseJSON = withObject "Component" $ \o ->-    Component <$> o .: "type"-      <*> o .:? "custom_id"-      <*> o .:? "disabled"-      <*> o .:? "style"-      <*> o .:? "label"+-- | Make a select option from the given label and value.+mkSelectOption :: T.Text -> T.Text -> SelectOption+mkSelectOption label value = SelectOption label value Nothing Nothing Nothing++instance FromJSON SelectOption where+  parseJSON = withObject "SelectOption" $ \o ->+    SelectOption <$> o .: "label"+      <*> o .: "value"+      <*> o .:? "description"       <*> o .:? "emoji"-      <*> o .:? "url"-      <*> o .:? "options"-      <*> o .:? "placeholder"-      <*> o .:? "min_values"-      <*> o .:? "max_values"-      <*> o .:? "components"+      <*> o .:? "default" -instance ToJSON Component where-  toJSON Component {..} =+instance ToJSON SelectOption where+  toJSON SelectOption {..} =     object       [ (name, value)         | (name, Just value) <--            [ ("type", toMaybeJSON componentType),-              ("custom_id", toJSON <$> componentCustomId),-              ("disabled", toJSON <$> componentDisabled),-              ("style", toJSON <$> componentStyle),-              ("label", toJSON <$> componentLabel),-              ("emoji", toJSON <$> componentEmoji),-              ("url", toJSON <$> componentUrl),-              ("options", toJSON <$> componentOptions),-              ("placeholder", toJSON <$> componentPlaceholder),-              ("min_values", toJSON <$> componentMinValues),-              ("max_values", toJSON <$> componentMaxValues),-              ("components", toJSON <$> componentComponents)+            [ ("label", toMaybeJSON selectOptionLabel),+              ("value", toMaybeJSON selectOptionValue),+              ("description", toJSON <$> selectOptionDescription),+              ("emoji", toJSON <$> selectOptionEmoji),+              ("default", toJSON <$> selectOptionDefault)             ]       ] --- | The different types of components-data ComponentType-  = -- | A container for other components-    ComponentTypeActionRow-  | -- | A button-    ComponentTypeButton-  | -- | A select menu for picking from choices-    ComponentTypeSelectMenu-  deriving (Show, Read, Eq, Ord, Data)--instance Enum ComponentType where-  fromEnum ComponentTypeActionRow = 1-  fromEnum ComponentTypeButton = 2-  fromEnum ComponentTypeSelectMenu = 3-  toEnum a = fromJust $ lookup a table-    where-      table = makeTable ComponentTypeActionRow--instance ToJSON ComponentType where-  toJSON = toJSON . fromEnum--instance FromJSON ComponentType where-  parseJSON = withScientific "StickerFormatType" (return . toEnum . round)--data InternalButtonStyle-  = -- | Blurple button-    InternalButtonStylePrimary-  | -- | Grey button-    InternalButtonStyleSecondary-  | -- | Green button-    InternalButtonStyleSuccess-  | -- | Red button-    InternalButtonStyleDanger-  | -- | Grey button, navigates to URL-    InternalButtonStyleLink-  deriving (Show, Read, Eq, Ord, Data)--instance Enum InternalButtonStyle where-  fromEnum InternalButtonStylePrimary = 1-  fromEnum InternalButtonStyleSecondary = 2-  fromEnum InternalButtonStyleSuccess = 3-  fromEnum InternalButtonStyleDanger = 4-  fromEnum InternalButtonStyleLink = 5-  toEnum a = fromJust $ lookup a table-    where-      table = makeTable InternalButtonStylePrimary--instance ToJSON InternalButtonStyle where-  toJSON = toJSON . fromEnum--instance FromJSON InternalButtonStyle where-  parseJSON = withScientific "InternalButtonStyle" (return . toEnum . round)- -- | Represents an emoticon (emoji) data Emoji = Emoji   { -- | The emoji id@@ -231,6 +290,10 @@   }   deriving (Show, Read, Eq, Ord) +-- | Make an emoji with only a name+mkEmoji :: T.Text -> Emoji+mkEmoji t = Emoji Nothing t Nothing Nothing Nothing Nothing+ instance FromJSON Emoji where   parseJSON = withObject "Emoji" $ \o ->     Emoji <$> o .:? "id"@@ -253,44 +316,3 @@               ("animated", toJSON <$> emojiAnimated)             ]       ]--data SelectOption = SelectOption-  { -- | User facing option name-    selectOptionLabel :: T.Text,-    -- | Dev facing option value-    selectOptionValue :: T.Text,-    -- | additional description-    selectOptionDescription :: Maybe T.Text,-    -- | A partial emoji to show with the object (id, name, animated)-    selectOptionEmoji :: Maybe Emoji,-    -- | Use this value by default-    selectOptionDefault :: Maybe Bool-  }-  deriving (Show, Eq, Ord, Read)--instance FromJSON SelectOption where-  parseJSON = withObject "SelectOption" $ \o ->-    SelectOption <$> o .: "label"-      <*> o .: "value"-      <*> o .:? "description"-      <*> o .:? "emoji"-      <*> o .:? "default"--instance ToJSON SelectOption where-  toJSON SelectOption {..} =-    object-      [ (name, value)-        | (name, Just value) <--            [ ("label", toMaybeJSON selectOptionLabel),-              ("value", toMaybeJSON selectOptionValue),-              ("description", toJSON <$> selectOptionDescription),-              ("emoji", toJSON <$> selectOptionEmoji),-              ("default", toJSON <$> selectOptionDefault)-            ]-      ]--filterOutIncorrectEmoji :: Component -> Component-filterOutIncorrectEmoji c@Component {componentType = ComponentTypeActionRow, componentComponents = (Just cs)} = c {componentComponents = Just (filterOutIncorrectEmoji <$> cs)}-filterOutIncorrectEmoji c@Component {componentType = ComponentTypeSelectMenu, componentOptions = (Just os)} = c {componentOptions = Just ((\so -> so {selectOptionEmoji = selectOptionEmoji so >>= validPartialEmoji}) <$> os)}-filterOutIncorrectEmoji c@Component {componentType = ComponentTypeButton, componentEmoji = (Just e)} = c {componentEmoji = validPartialEmoji e}-filterOutIncorrectEmoji c = c
src/Discord/Internal/Types/Embed.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE RecordWildCards #-}  -- | Data structures pertaining to Discord Embed@@ -9,9 +10,13 @@ import Data.Default (Default, def) import qualified Data.Text as T import qualified Data.ByteString as B+import Data.Functor ((<&>)) -import Discord.Internal.Types.Prelude+import Network.HTTP.Client.MultipartFormData (PartM, partFileRequestBody)+import Network.HTTP.Client (RequestBody(RequestBodyBS)) +import Discord.Internal.Types.Color (DiscordColor)+ createEmbed :: CreateEmbed -> Embed createEmbed CreateEmbed{..} =   let@@ -21,16 +26,16 @@     embedImageToUrl :: T.Text -> CreateEmbedImage -> T.Text     embedImageToUrl place cei = case cei of                             CreateEmbedImageUrl t -> t-                            CreateEmbedImageUpload _ -> "attachment://" <> place <> ".png"+                            CreateEmbedImageUpload _ -> T.filter (/=' ') $ "attachment://" <> createEmbedTitle <> place <> ".png" -    embedAuthor = EmbedAuthor (emptyMaybe createEmbedAuthorName)+    embedAuthor = EmbedAuthor createEmbedAuthorName                               (emptyMaybe createEmbedAuthorUrl)                               (embedImageToUrl "author" <$> createEmbedAuthorIcon)                               Nothing-    embedImage = EmbedImage   (embedImageToUrl "image" <$> createEmbedImage)-                              Nothing Nothing Nothing-    embedThumbnail = EmbedThumbnail (embedImageToUrl "thumbnail" <$> createEmbedThumbnail)-                              Nothing Nothing Nothing+    embedImage = (embedImageToUrl "image" <$> createEmbedImage) <&>+                  \image -> EmbedImage image Nothing Nothing Nothing+    embedThumbnail = (embedImageToUrl "thumbnail" <$> createEmbedThumbnail) <&>+                      \thumbnail -> EmbedThumbnail thumbnail Nothing Nothing Nothing     embedFooter = EmbedFooter createEmbedFooterText                               (embedImageToUrl "footer" <$> createEmbedFooterIcon)                               Nothing@@ -38,16 +43,15 @@   in Embed { embedAuthor      = Just embedAuthor            , embedTitle       = emptyMaybe createEmbedTitle            , embedUrl         = emptyMaybe createEmbedUrl-           , embedThumbnail   = Just embedThumbnail+           , embedThumbnail   = embedThumbnail            , embedDescription = emptyMaybe createEmbedDescription            , embedFields      = createEmbedFields-           , embedImage       = Just embedImage+           , embedImage       = embedImage            , embedFooter      = Just embedFooter            , embedColor       = createEmbedColor-           , embedTimestamp   = Nothing+           , embedTimestamp   = createEmbedTimestamp             -- can't set these-           , embedType        = Nothing            , embedVideo       = Nothing            , embedProvider    = Nothing            }@@ -64,8 +68,8 @@   , createEmbedImage       :: Maybe CreateEmbedImage   , createEmbedFooterText  :: T.Text   , createEmbedFooterIcon  :: Maybe CreateEmbedImage-  , createEmbedColor       :: Maybe ColorInteger---, createEmbedTimestamp   :: Maybe UTCTime+  , createEmbedColor       :: Maybe DiscordColor+  , createEmbedTimestamp   :: Maybe UTCTime   } deriving (Show, Read, Eq, Ord)  data CreateEmbedImage = CreateEmbedImageUrl T.Text@@ -73,7 +77,7 @@   deriving (Show, Read, Eq, Ord)  instance Default CreateEmbed where- def = CreateEmbed "" "" Nothing "" "" Nothing "" [] Nothing "" Nothing Nothing  -- Nothing+ def = CreateEmbed "" "" Nothing "" "" Nothing "" [] Nothing "" Nothing Nothing Nothing  -- | An embed attached to a message. data Embed = Embed@@ -85,9 +89,8 @@   , embedFields      :: [EmbedField]     -- ^ Fields of the embed   , embedImage       :: Maybe EmbedImage   , embedFooter      :: Maybe EmbedFooter-  , embedColor       :: Maybe ColorInteger    -- ^ The embed color+  , embedColor       :: Maybe DiscordColor    -- ^ The embed color   , embedTimestamp   :: Maybe UTCTime    -- ^ The time of the embed content-  , embedType        :: Maybe T.Text     -- ^ Type of embed (Always "rich" for users)   , embedVideo       :: Maybe EmbedVideo -- ^ Only present for "video" types   , embedProvider    :: Maybe EmbedProvider -- ^ Only present for "video" types   } deriving (Show, Read, Eq, Ord)@@ -105,7 +108,6 @@    , "footer"      .= embedFooter    , "color"       .= embedColor    , "timestamp"   .= embedTimestamp-   , "type"        .= embedType    , "video"       .= embedVideo    , "provider"    .= embedProvider     ]@@ -122,13 +124,12 @@           <*> o .:? "footer"           <*> o .:? "color"           <*> o .:? "timestamp"-          <*> o .:? "type"           <*> o .:? "video"           <*> o .:? "provider"   data EmbedThumbnail = EmbedThumbnail-  { embedThumbnailUrl :: Maybe T.Text+  { embedThumbnailUrl :: T.Text   , embedThumbnailProxyUrl :: Maybe T.Text   , embedThumbnailHeight :: Maybe Integer   , embedThumbnailWidth :: Maybe Integer@@ -144,32 +145,35 @@  instance FromJSON EmbedThumbnail where   parseJSON = withObject "thumbnail" $ \o ->-    EmbedThumbnail <$> o .:? "url"+    EmbedThumbnail <$> o .: "url"                    <*> o .:? "proxy_url"                    <*> o .:? "height"                    <*> o .:? "width"  data EmbedVideo = EmbedVideo   { embedVideoUrl :: Maybe T.Text+  , embedProxyUrl :: Maybe T.Text   , embedVideoHeight :: Maybe Integer   , embedVideoWidth :: Maybe Integer   } deriving (Show, Read, Eq, Ord)  instance ToJSON EmbedVideo where-  toJSON (EmbedVideo a b c) = object+  toJSON (EmbedVideo a a' b c) = object     [ "url" .= a     , "height" .= b     , "width" .= c+    , "proxy_url" .= a'     ]  instance FromJSON EmbedVideo where   parseJSON = withObject "video" $ \o ->     EmbedVideo <$> o .:? "url"+               <*> o .:? "proxy_url"                <*> o .:? "height"                <*> o .:? "width"  data EmbedImage = EmbedImage-  { embedImageUrl :: Maybe T.Text+  { embedImageUrl :: T.Text   , embedImageProxyUrl :: Maybe T.Text   , embedImageHeight :: Maybe Integer   , embedImageWidth :: Maybe Integer@@ -185,7 +189,7 @@  instance FromJSON EmbedImage where   parseJSON = withObject "image" $ \o ->-    EmbedImage <$> o .:? "url"+    EmbedImage <$> o .:  "url"                <*> o .:? "proxy_url"                <*> o .:? "height"                <*> o .:? "width"@@ -207,7 +211,7 @@                   <*> o .:? "url"  data EmbedAuthor = EmbedAuthor-  { embedAuthorName :: Maybe T.Text+  { embedAuthorName :: T.Text   , embedAuthorUrl :: Maybe T.Text   , embedAuthorIconUrl :: Maybe T.Text   , embedAuthorProxyIconUrl :: Maybe T.Text@@ -223,7 +227,7 @@  instance FromJSON EmbedAuthor where   parseJSON = withObject "author" $ \o ->-    EmbedAuthor <$> o .:? "name"+    EmbedAuthor <$> o .:  "name"                 <*> o .:? "url"                 <*> o .:? "icon_url"                 <*> o .:? "proxy_icon_url"@@ -265,3 +269,14 @@     EmbedField <$> o .:  "name"                <*> o .:  "value"                <*> o .:? "inline"+++maybeEmbed :: Maybe CreateEmbed -> [PartM IO]+maybeEmbed =+      let mkPart (name,content) = partFileRequestBody name (T.unpack name) (RequestBodyBS content)+          uploads CreateEmbed{..} = [(T.filter (/=' ') $ createEmbedTitle<>n,c) | (n, Just (CreateEmbedImageUpload c)) <-+                                          [ ("author.png", createEmbedAuthorIcon)+                                          , ("thumbnail.png", createEmbedThumbnail)+                                          , ("image.png", createEmbedImage)+                                          , ("footer.png", createEmbedFooterIcon) ]]+      in maybe [] (map mkPart . uploads)
src/Discord/Internal/Types/Events.hs view
@@ -15,9 +15,9 @@  import Discord.Internal.Types.Prelude import Discord.Internal.Types.Channel-import Discord.Internal.Types.Guild     ( Role, GuildInfo, GuildUnavailable, Guild )+import Discord.Internal.Types.Guild (Role, GuildInfo, GuildUnavailable, Guild) import Discord.Internal.Types.User (User, GuildMember)-import Discord.Internal.Types.Interactions (InternalInteraction, Interaction)+import Discord.Internal.Types.Interactions (Interaction) import Discord.Internal.Types.Components (Emoji)  @@ -58,7 +58,7 @@   -- | VoiceStateUpdate   -- | VoiceServerUpdate   | UnknownEvent     T.Text Object-  deriving (Show, Read, Eq)+  deriving (Show, Eq)  data EventInternalParse =     InternalReady                   Int User [Channel] [GuildUnavailable] T.Text (Maybe Shard) PartialApplication@@ -92,11 +92,11 @@   | InternalPresenceUpdate          PresenceInfo   | InternalTypingStart             TypingInfo   | InternalUserUpdate              User-  | InternalInteractionCreate       InternalInteraction-  -- | InternalVoiceStateUpdate-  -- | InternalVoiceServerUpdate+  | InternalInteractionCreate       Interaction+  -- -- | InternalVoiceStateUpdate+  -- -- | InternalVoiceServerUpdate   | InternalUnknownEvent     T.Text Object-  deriving (Show, Read, Eq)+  deriving (Show, Eq, Read)  data PartialApplication = PartialApplication   { partialApplicationID :: ApplicationId
src/Discord/Internal/Types/Gateway.hs view
@@ -30,7 +30,7 @@   | Hello Integer   | HeartbeatAck   | ParseError T.Text-  deriving (Show, Read, Eq)+  deriving (Show, Eq, Read)  -- | Sent to gateway by our library data GatewaySendableInternal@@ -80,7 +80,7 @@ compileGatewayIntent :: GatewayIntent -> Int compileGatewayIntent GatewayIntent{..} =  sum $ [ if on then flag else 0-       | (flag, on) <- [ (2 ^  0, gatewayIntentGuilds)+       | (flag, on) <- [ (     1, gatewayIntentGuilds)                        , (2 ^  1, gatewayIntentMembers)                        , (2 ^  2, gatewayIntentBans)                        , (2 ^  3, gatewayIntentEmojis)@@ -169,7 +169,7 @@                ejson <- o .: "d"                case ejson of                  Object hm -> Dispatch <$> eventParse etype hm <*> o .: "s"-                 _other -> Dispatch (InternalUnknownEvent ("Dispatch payload wasn't an object") o)+                 _other -> Dispatch (InternalUnknownEvent "Dispatch payload wasn't an object" o)                                   <$> o .: "s"       1  -> HeartbeatRequest . fromMaybe 0 . readMaybe <$> o .: "d"       7  -> pure Reconnect
src/Discord/Internal/Types/Guild.hs view
@@ -10,6 +10,7 @@ import qualified Data.Text as T  import Discord.Internal.Types.Prelude+import Discord.Internal.Types.Color (DiscordColor) import Discord.Internal.Types.Channel (Channel) import Discord.Internal.Types.User (User, GuildMember) import Discord.Internal.Types.Components (Emoji)@@ -116,10 +117,10 @@     Role {         roleId      :: RoleId -- ^ The role id       , roleName    :: T.Text                    -- ^ The role name-      , roleColor   :: ColorInteger              -- ^ Integer representation of color code+      , roleColor   :: DiscordColor              -- ^ Integer representation of color code       , roleHoist   :: Bool                      -- ^ If the role is pinned in the user listing       , rolePos     :: Integer                   -- ^ Position of this role-      , rolePerms   :: T.Text                   -- ^ Permission bit set+      , rolePerms   :: T.Text                    -- ^ Permission bit set       , roleManaged :: Bool                      -- ^ Whether this role is managed by an integration       , roleMention :: Bool                      -- ^ Whether this role is mentionable     } deriving (Show, Read, Eq, Ord)
src/Discord/Internal/Types/Interactions.hs view
@@ -1,9 +1,10 @@ {-# LANGUAGE DataKinds #-}-{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes #-} {-# LANGUAGE RecordWildCards #-}  module Discord.Internal.Types.Interactions@@ -14,22 +15,16 @@     InteractionDataApplicationCommandOptionSubcommandOrGroup (..),     InteractionDataApplicationCommandOptionSubcommand (..),     InteractionDataApplicationCommandOptionValue (..),-    ApplicationCommandInteractionDataValue (..),-    InternalInteraction (..),     InteractionToken,-    InteractionType,-    InternalInteractionData (..),     ResolvedData (..),-    InternalInteractionDataApplicationCommandOption (..),+    MemberOrUser (..),     InteractionResponse (..),     interactionResponseBasic,-    InteractionCallbackType (..),-    InteractionCallbackData (..),-    InteractionCallbackAutocomplete,-    InteractionCallbackMessages (..),-    interactionCallbackMessagesBasic,-    InteractionCallbackDataFlags (..),-    InteractionCallbackDataFlag (..),+    InteractionResponseAutocomplete (..),+    InteractionResponseMessage (..),+    interactionResponseMessageBasic,+    InteractionResponseMessageFlags (..),+    InteractionResponseMessageFlag (..),   ) where @@ -37,344 +32,393 @@ import Data.Aeson import Data.Aeson.Types (Parser) import Data.Bits (Bits (shift, (.|.)))-import Data.Data (Data)-import Data.Maybe (fromJust, fromMaybe)+import Data.Foldable (Foldable (toList)) import Data.Scientific (Scientific) import qualified Data.Text as T-import Discord.Internal.Types.ApplicationCommands-  (-    InternalApplicationCommandOptionChoice,-    ApplicationCommandOptionType (..),-    ApplicationCommandType (..),-  )+import Discord.Internal.Types.ApplicationCommands (Choice) import Discord.Internal.Types.Channel (AllowedMentions, Attachment, Message)-import Discord.Internal.Types.Components (Component, ComponentType (..))-import Discord.Internal.Types.Embed (Embed)-import Discord.Internal.Types.Prelude (ApplicationId, ApplicationCommandId, ChannelId, GuildId, InteractionId, InteractionToken, InteractionType (..), Internals (..), MessageId, Snowflake, UserId, makeTable, toMaybeJSON)+import Discord.Internal.Types.Components (ComponentActionRow)+import Discord.Internal.Types.Embed (CreateEmbed, createEmbed)+import Discord.Internal.Types.Prelude (ApplicationCommandId, ApplicationId, ChannelId, GuildId, InteractionId, InteractionToken, MessageId, RoleId, Snowflake, UserId) import Discord.Internal.Types.User (GuildMember, User) -import Debug.Trace-+-- | An interaction received from discord. data Interaction   = InteractionComponent-      { interactionId :: InteractionId,+      { -- | The id of this interaction.+        interactionId :: InteractionId,+        -- | The id of the application that this interaction belongs to.         interactionApplicationId :: ApplicationId,-        interactionDataComponent :: Maybe InteractionDataComponent, -- referenced as Data in API+        -- | The data for this interaction.+        interactionDataComponent :: InteractionDataComponent,+        -- | What guild this interaction comes from.         interactionGuildId :: Maybe GuildId,+        -- | What channel this interaction comes from.         interactionChannelId :: Maybe ChannelId,-        interactionMember :: Maybe GuildMember,-        interactionUser :: Maybe User,+        -- | What user/member this interaction comes from.+        interactionUser :: MemberOrUser,+        -- | The unique token that represents this interaction.         interactionToken :: InteractionToken,+        -- | What version of interaction is this (always 1).         interactionVersion :: Int,-        interactionMessage :: Message+        -- | What message is associated with this interaction.+        interactionMessage :: Message,+        -- | The invoking user's preferred locale.+        interactionLocale :: T.Text,+        -- | The invoking guild's preferred locale.+        interactionGuildLocale :: Maybe T.Text       }   | InteractionPing-      { interactionId :: InteractionId,+      { -- | The id of this interaction.+        interactionId :: InteractionId,+        -- | The id of the application that this interaction belongs to.         interactionApplicationId :: ApplicationId,+        -- | The unique token that represents this interaction.         interactionToken :: InteractionToken,+        -- | What version of interaction is this (always 1).         interactionVersion :: Int       }   | InteractionApplicationCommand-      { interactionId :: InteractionId,+      { -- | The id of this interaction.+        interactionId :: InteractionId,+        -- | The id of the application that this interaction belongs to.         interactionApplicationId :: ApplicationId,-        interactionDataApplicationCommand :: Maybe InteractionDataApplicationCommand, -- referenced as Data in API+        -- | The data for this interaction.+        interactionDataApplicationCommand :: InteractionDataApplicationCommand,+        -- | What guild this interaction comes from.         interactionGuildId :: Maybe GuildId,+        -- | What channel this interaction comes from.         interactionChannelId :: Maybe ChannelId,-        interactionMember :: Maybe GuildMember,-        interactionUser :: Maybe User,+        -- | What user/member this interaction comes from.+        interactionUser :: MemberOrUser,+        -- | The unique token that represents this interaction.         interactionToken :: InteractionToken,-        interactionVersion :: Int+        -- | What version of interaction is this (always 1).+        interactionVersion :: Int,+        -- | The invoking user's preferred locale.+        interactionLocale :: T.Text,+        -- | The invoking guild's preferred locale.+        interactionGuildLocale :: Maybe T.Text       }   | InteractionApplicationCommandAutocomplete-      { interactionId :: InteractionId,+      { -- | The id of this interaction.+        interactionId :: InteractionId,+        -- | The id of the application that this interaction belongs to.         interactionApplicationId :: ApplicationId,-        interactionDataApplicationCommand :: Maybe InteractionDataApplicationCommand, -- referenced as Data in API+        -- | The data for this interaction.+        interactionDataApplicationCommand :: InteractionDataApplicationCommand,+        -- | What guild this interaction comes from.         interactionGuildId :: Maybe GuildId,+        -- | What channel this interaction comes from.         interactionChannelId :: Maybe ChannelId,-        interactionMember :: Maybe GuildMember,-        interactionUser :: Maybe User,+        -- | What user/member this interaction comes from.+        interactionUser :: MemberOrUser,+        -- | The unique token that represents this interaction.         interactionToken :: InteractionToken,-        interactionVersion :: Int+        -- | What version of interaction is this (always 1).+        interactionVersion :: Int,+        -- | The invoking user's preferred locale.+        interactionLocale :: T.Text,+        -- | The invoking guild's preferred locale.+        interactionGuildLocale :: Maybe T.Text       }-  | InteractionUnknown InternalInteraction-  deriving (Show, Read, Eq)+  deriving (Show, Eq, Read) +instance FromJSON Interaction where+  parseJSON =+    withObject+      "Interaction"+      ( \v -> do+          iid <- v .: "id"+          aid <- v .: "application_id"+          gid <- v .:? "guild_id"+          cid <- v .:? "channel_id"+          tok <- v .: "token"+          version <- v .: "version"+          glocale <- v .:? "guild_locale"+          t <- v .: "type" :: Parser Int+          case t of+            1 -> return $ InteractionPing iid aid tok version+            2 ->+              InteractionApplicationCommand iid aid+                <$> v .: "data"+                <*> return gid+                <*> return cid+                <*> parseJSON (Object v)+                <*> return tok+                <*> return version+                <*> v .: "locale"+                <*> return glocale+            3 ->+              InteractionComponent iid aid+                <$> v .: "data"+                <*> return gid+                <*> return cid+                <*> parseJSON (Object v)+                <*> return tok+                <*> return version+                <*> v .: "message"+                <*> v .: "locale"+                <*> return glocale+            4 ->+              InteractionApplicationCommandAutocomplete iid aid+                <$> v .: "data"+                <*> return gid+                <*> return cid+                <*> parseJSON (Object v)+                <*> return tok+                <*> return version+                <*> v .: "locale"+                <*> return glocale+            _ -> fail "unknown interaction type"+      )++newtype MemberOrUser = MemberOrUser (Either GuildMember User) deriving (Show, Eq, Read)++instance {-# OVERLAPPING #-} FromJSON MemberOrUser where+  parseJSON =+    withObject+      "MemberOrUser"+      ( \v -> MemberOrUser <$> ((Left <$> v .: "member") <|> (Right <$> v .: "user"))+      )+ data InteractionDataComponent   = InteractionDataComponentButton-      { -- | Component only, the unique id+      { -- | The unique id of the component (up to 100 characters).         interactionDataComponentCustomId :: T.Text       }   | InteractionDataComponentSelectMenu-      { interactionDataComponentCustomId :: T.Text,+      { -- | The unique id of the component (up to 100 characters).+        interactionDataComponentCustomId :: T.Text,+        -- | Values for the select menu.         interactionDataComponentValues :: [T.Text]       }   deriving (Show, Read, Eq) +instance FromJSON InteractionDataComponent where+  parseJSON =+    withObject+      "InteractionDataComponent"+      ( \v -> do+          cid <- v .: "custom_id"+          t <- v .: "component_type" :: Parser Int+          case t of+            2 -> return $ InteractionDataComponentButton cid+            3 ->+              InteractionDataComponentSelectMenu cid+                <$> v .: "values"+            _ -> fail "unknown interaction data component type"+      )+ data InteractionDataApplicationCommand   = InteractionDataApplicationCommandUser-      { -- | id of the invoked command+      { -- | Id of the invoked command.         interactionDataApplicationCommandId :: ApplicationCommandId,-        -- | name of the invoked command+        -- | Name of the invoked command.         interactionDataApplicationCommandName :: T.Text,-        -- | the resolved data in the command+        -- | The resolved data in the command.         interactionDataApplicationCommandResolvedData :: Maybe ResolvedData,-        -- | the target of the command+        -- | The id of the user that is the target.         interactionDataApplicationCommandTargetId :: UserId       }   | InteractionDataApplicationCommandMessage-      { -- | Application command only, id of the invoked command+      { -- | Id of the invoked command.         interactionDataApplicationCommandId :: ApplicationCommandId,-        -- | Application command only, name of the invoked command+        -- | Name of the invoked command.         interactionDataApplicationCommandName :: T.Text,+        -- | The resolved data in the command.         interactionDataApplicationCommandResolvedData :: Maybe ResolvedData,+        -- | The id of the message that is the target.         interactionDataApplicationCommandTargetId :: MessageId       }   | InteractionDataApplicationCommandChatInput-      { -- | Application command only, id of the invoked command+      { -- | Id of the invoked command.         interactionDataApplicationCommandId :: ApplicationCommandId,-        -- | Application command only, name of the invoked command+        -- | Name of the invoked command.         interactionDataApplicationCommandName :: T.Text,+        -- | The resolved data in the command.         interactionDataApplicationCommandResolvedData :: Maybe ResolvedData,+        -- | The options of the application command.         interactionDataApplicationCommandOptions :: Maybe InteractionDataApplicationCommandOptions       }   deriving (Show, Read, Eq) +instance FromJSON InteractionDataApplicationCommand where+  parseJSON =+    withObject+      "InteractionDataApplicationCommand"+      ( \v -> do+          aci <- v .: "id"+          name <- v .: "name"+          rd <- v .:? "resolved_data"+          t <- v .: "type" :: Parser Int+          case t of+            1 ->+              InteractionDataApplicationCommandChatInput aci name rd+                <$> v .:? "options"+            2 ->+              InteractionDataApplicationCommandUser aci name rd+                <$> v .: "target_id"+            3 ->+              InteractionDataApplicationCommandMessage aci name rd+                <$> v .: "target_id"+            _ -> fail "unknown interaction data component type"+      )++-- | Either subcommands and groups, or values. data InteractionDataApplicationCommandOptions   = InteractionDataApplicationCommandOptionsSubcommands [InteractionDataApplicationCommandOptionSubcommandOrGroup]   | InteractionDataApplicationCommandOptionsValues [InteractionDataApplicationCommandOptionValue]   deriving (Show, Read, Eq) +instance FromJSON InteractionDataApplicationCommandOptions where+  parseJSON =+    withArray+      "InteractionDataApplicationCommandOptions"+      ( \a -> do+          let a' = toList a+          case a' of+            [] -> return $ InteractionDataApplicationCommandOptionsValues []+            (v' : _) ->+              withObject+                "InteractionDataApplicationCommandOptions item"+                ( \v -> do+                    t <- v .: "type" :: Parser Int+                    if t == 1 || t == 2+                      then InteractionDataApplicationCommandOptionsSubcommands <$> mapM parseJSON a'+                      else InteractionDataApplicationCommandOptionsValues <$> mapM parseJSON a'+                )+                v'+      )++-- | Either a subcommand group or a subcommand. data InteractionDataApplicationCommandOptionSubcommandOrGroup   = InteractionDataApplicationCommandOptionSubcommandGroup       { interactionDataApplicationCommandOptionSubcommandGroupName :: T.Text,         interactionDataApplicationCommandOptionSubcommandGroupOptions :: [InteractionDataApplicationCommandOptionSubcommand],-        interactionDataApplicationCommandOptionSubcommandGroupFocused :: Maybe Bool+        interactionDataApplicationCommandOptionSubcommandGroupFocused :: Bool       }   | InteractionDataApplicationCommandOptionSubcommandOrGroupSubcommand InteractionDataApplicationCommandOptionSubcommand   deriving (Show, Read, Eq) +instance FromJSON InteractionDataApplicationCommandOptionSubcommandOrGroup where+  parseJSON =+    withObject+      "InteractionDataApplicationCommandOptionSubcommandOrGroup"+      ( \v -> do+          t <- v .: "type" :: Parser Int+          case t of+            2 ->+              InteractionDataApplicationCommandOptionSubcommandGroup+                <$> v .: "name"+                <*> v .: "options"+                <*> v .:? "focused" .!= False+            1 -> InteractionDataApplicationCommandOptionSubcommandOrGroupSubcommand <$> parseJSON (Object v)+            _ -> fail "unexpected subcommand group type"+      )++-- | Data for a single subcommand. data InteractionDataApplicationCommandOptionSubcommand = InteractionDataApplicationCommandOptionSubcommand   { interactionDataApplicationCommandOptionSubcommandName :: T.Text,     interactionDataApplicationCommandOptionSubcommandOptions :: [InteractionDataApplicationCommandOptionValue],-    interactionDataApplicationCommandOptionSubcommandFocused :: Maybe Bool-  }-  deriving (Show, Read, Eq)--data InteractionDataApplicationCommandOptionValue = InteractionDataApplicationCommandOptionValue-  { interactionDataApplicationCommandOptionValueName :: T.Text,-    interactionDataApplicationCommandOptionValueValue :: ApplicationCommandInteractionDataValue,-    interactionDataApplicationCommandOptionValueFocused :: Maybe Bool-  }-  deriving (Show, Read, Eq)--instance Internals InteractionDataApplicationCommandOptionValue InternalInteractionDataApplicationCommandOption where-  toInternal InteractionDataApplicationCommandOptionValue {..} = InternalInteractionDataApplicationCommandOption interactionDataApplicationCommandOptionValueName (getTypeFromACIDV interactionDataApplicationCommandOptionValueValue) (Just interactionDataApplicationCommandOptionValueValue) Nothing interactionDataApplicationCommandOptionValueFocused--  fromInternal InternalInteractionDataApplicationCommandOption {..}-    | internalInteractionDataApplicationCommandOptionType `elem` [ApplicationCommandOptionTypeSubcommand, ApplicationCommandOptionTypeSubcommandGroup] = Nothing-    | otherwise = do-      v <- trace ("this" ++ show internalInteractionDataApplicationCommandOptionValue) internalInteractionDataApplicationCommandOptionValue-      return $ InteractionDataApplicationCommandOptionValue internalInteractionDataApplicationCommandOptionName v internalInteractionDataApplicationCommandOptionFocused--instance Internals InteractionDataApplicationCommandOptionSubcommand InternalInteractionDataApplicationCommandOption where-  toInternal InteractionDataApplicationCommandOptionSubcommand {..} =-    InternalInteractionDataApplicationCommandOption interactionDataApplicationCommandOptionSubcommandName ApplicationCommandOptionTypeSubcommand Nothing (Just $ toInternal <$> interactionDataApplicationCommandOptionSubcommandOptions) interactionDataApplicationCommandOptionSubcommandFocused--  fromInternal InternalInteractionDataApplicationCommandOption {internalInteractionDataApplicationCommandOptionType = ApplicationCommandOptionTypeSubcommand, ..} = do-    o <- internalInteractionDataApplicationCommandOptionOptions-    o' <- mapM fromInternal o-    return $ InteractionDataApplicationCommandOptionSubcommand internalInteractionDataApplicationCommandOptionName o' internalInteractionDataApplicationCommandOptionFocused-  fromInternal _ = Nothing--instance Internals InteractionDataApplicationCommandOptionSubcommandOrGroup InternalInteractionDataApplicationCommandOption where-  toInternal InteractionDataApplicationCommandOptionSubcommandGroup {..} =-    InternalInteractionDataApplicationCommandOption interactionDataApplicationCommandOptionSubcommandGroupName ApplicationCommandOptionTypeSubcommand Nothing (Just $ toInternal <$> interactionDataApplicationCommandOptionSubcommandGroupOptions) interactionDataApplicationCommandOptionSubcommandGroupFocused-  toInternal (InteractionDataApplicationCommandOptionSubcommandOrGroupSubcommand s) = toInternal s--  fromInternal InternalInteractionDataApplicationCommandOption {internalInteractionDataApplicationCommandOptionType = ApplicationCommandOptionTypeSubcommandGroup, ..} = do-    o <- internalInteractionDataApplicationCommandOptionOptions-    o' <- mapM fromInternal o-    return $ InteractionDataApplicationCommandOptionSubcommandGroup internalInteractionDataApplicationCommandOptionName o' internalInteractionDataApplicationCommandOptionFocused-  fromInternal i@InternalInteractionDataApplicationCommandOption {internalInteractionDataApplicationCommandOptionType = ApplicationCommandOptionTypeSubcommand, ..} = InteractionDataApplicationCommandOptionSubcommandOrGroupSubcommand <$> fromInternal i-  fromInternal _ = Nothing--instance Internals InteractionDataApplicationCommandOptions [InternalInteractionDataApplicationCommandOption] where-  toInternal (InteractionDataApplicationCommandOptionsSubcommands lst) = toInternal <$> lst-  toInternal (InteractionDataApplicationCommandOptionsValues lst) = toInternal <$> lst--  fromInternal is = (InteractionDataApplicationCommandOptionsSubcommands <$> mapM fromInternal is) <|> (InteractionDataApplicationCommandOptionsValues <$> mapM fromInternal is)--instance Internals InteractionDataApplicationCommand InternalInteractionData where-  toInternal InteractionDataApplicationCommandUser {..} = InternalInteractionData (Just interactionDataApplicationCommandId) (Just interactionDataApplicationCommandName) (Just ApplicationCommandTypeUser) interactionDataApplicationCommandResolvedData Nothing Nothing Nothing Nothing Nothing-  toInternal InteractionDataApplicationCommandMessage {..} = InternalInteractionData (Just interactionDataApplicationCommandId) (Just interactionDataApplicationCommandName) (Just ApplicationCommandTypeMessage) interactionDataApplicationCommandResolvedData Nothing Nothing Nothing Nothing Nothing-  toInternal InteractionDataApplicationCommandChatInput {..} = InternalInteractionData (Just interactionDataApplicationCommandId) (Just interactionDataApplicationCommandName) (Just ApplicationCommandTypeMessage) interactionDataApplicationCommandResolvedData (toInternal <$> interactionDataApplicationCommandOptions) Nothing Nothing Nothing Nothing--  fromInternal InternalInteractionData {internalInteractionDataApplicationCommandType = Just ApplicationCommandTypeUser, ..} = do-    aid <- internalInteractionDataApplicationCommandId-    name <- internalInteractionDataApplicationCommandName-    tid <- internalInteractionDataTargetId-    return $ InteractionDataApplicationCommandUser aid name internalInteractionDataResolved tid-  fromInternal InternalInteractionData {internalInteractionDataApplicationCommandType = Just ApplicationCommandTypeMessage, ..} = do-    aid <- internalInteractionDataApplicationCommandId-    name <- internalInteractionDataApplicationCommandName-    tid <- internalInteractionDataTargetId-    return $ InteractionDataApplicationCommandMessage aid name internalInteractionDataResolved tid-  fromInternal InternalInteractionData {internalInteractionDataApplicationCommandType = Just ApplicationCommandTypeChatInput, ..} = do-    aid <- internalInteractionDataApplicationCommandId-    name <- internalInteractionDataApplicationCommandName-    return $ InteractionDataApplicationCommandChatInput aid name internalInteractionDataResolved (internalInteractionDataOptions >>= fromInternal)-  fromInternal _ = Nothing--instance Internals InteractionDataComponent InternalInteractionData where-  toInternal InteractionDataComponentButton {..} = InternalInteractionData Nothing Nothing Nothing Nothing Nothing (Just interactionDataComponentCustomId) (Just ComponentTypeButton) Nothing Nothing-  toInternal InteractionDataComponentSelectMenu {..} = InternalInteractionData Nothing Nothing Nothing Nothing Nothing (Just interactionDataComponentCustomId) (Just ComponentTypeSelectMenu) (Just interactionDataComponentValues) Nothing--  fromInternal InternalInteractionData {internalInteractionDataComponentType = Just ComponentTypeButton, ..} = InteractionDataComponentButton <$> internalInteractionDataCustomId-  fromInternal InternalInteractionData {internalInteractionDataComponentType = Just ComponentTypeSelectMenu, ..} = InteractionDataComponentSelectMenu <$> internalInteractionDataCustomId <*> internalInteractionDataValues-  fromInternal _ = Nothing--instance Internals Interaction InternalInteraction where-  toInternal InteractionPing {..} = InternalInteraction interactionId interactionApplicationId InteractionTypePing Nothing Nothing Nothing Nothing Nothing interactionToken interactionVersion Nothing-  toInternal InteractionComponent {..} = InternalInteraction interactionId interactionApplicationId InteractionTypeMessageComponent (toInternal <$> interactionDataComponent) interactionGuildId interactionChannelId interactionMember interactionUser interactionToken interactionVersion (Just interactionMessage)-  toInternal InteractionApplicationCommand {..} = InternalInteraction interactionId interactionApplicationId InteractionTypeApplicationCommand (toInternal <$> interactionDataApplicationCommand) interactionGuildId interactionChannelId interactionMember interactionUser interactionToken interactionVersion Nothing-  toInternal InteractionApplicationCommandAutocomplete {..} = InternalInteraction interactionId interactionApplicationId InteractionTypeApplicationCommandAutocomplete (toInternal <$> interactionDataApplicationCommand) interactionGuildId interactionChannelId interactionMember interactionUser interactionToken interactionVersion Nothing-  toInternal (InteractionUnknown i) = i--  fromInternal InternalInteraction {internalInteractionType = InteractionTypePing, ..} = Just $ InteractionPing internalInteractionId internalInteractionApplicationId internalInteractionToken internalInteractionVersion-  fromInternal i@InternalInteraction {internalInteractionType = InteractionTypeMessageComponent, ..} = Just $ fromMaybe (InteractionUnknown i) $ internalInteractionMessage >>= Just . InteractionComponent internalInteractionId internalInteractionApplicationId (internalInteractionData >>= fromInternal) internalInteractionGuildId internalInteractionChannelId internalInteractionMember internalInteractionUser internalInteractionToken internalInteractionVersion-  fromInternal i@InternalInteraction {internalInteractionType=InteractionTypeApplicationCommandAutocomplete,..} = Just $ fromMaybe (InteractionUnknown i) $ process internalInteractionData-    where process Nothing = Just $ InteractionApplicationCommandAutocomplete internalInteractionId internalInteractionApplicationId Nothing internalInteractionGuildId internalInteractionChannelId internalInteractionMember internalInteractionUser internalInteractionToken internalInteractionVersion-          process (Just d) = fromInternal d >>= \d' -> Just $ InteractionApplicationCommandAutocomplete internalInteractionId internalInteractionApplicationId (Just d') internalInteractionGuildId internalInteractionChannelId internalInteractionMember internalInteractionUser internalInteractionToken internalInteractionVersion-  fromInternal i@InternalInteraction {internalInteractionType=InteractionTypeApplicationCommand,..} = Just $ fromMaybe (InteractionUnknown i) $ process internalInteractionData-    where process Nothing = Just $ InteractionApplicationCommand internalInteractionId internalInteractionApplicationId Nothing internalInteractionGuildId internalInteractionChannelId internalInteractionMember internalInteractionUser internalInteractionToken internalInteractionVersion-          process (Just d) = fromInternal d >>= \d' -> Just $ InteractionApplicationCommand internalInteractionId internalInteractionApplicationId (Just d') internalInteractionGuildId internalInteractionChannelId internalInteractionMember internalInteractionUser internalInteractionToken internalInteractionVersion-    -- Just $ InteractionApplicationCommand internalInteractionId internalInteractionApplicationId (internalInteractionType == InteractionTypeApplicationCommandAutocomplete) (internalInteractionData >>= fromInternal) internalInteractionGuildId internalInteractionChannelId internalInteractionMember internalInteractionUser internalInteractionToken internalInteractionVersion---- instance Internals Interaction InternalInteraction where---- application command id--- application command name--- application command type -- this should be defined in the constructor!--- resolved data -- this should be formalised and integrated, instead of being---  left as values--- options -- only present if type is subcommand or subcommand group---- | This is the data that is recieved when an interaction occurs.------ https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-interaction-structure-data InternalInteraction = InternalInteraction-  { internalInteractionId :: InteractionId,-    internalInteractionApplicationId :: ApplicationId,-    internalInteractionType :: InteractionType, -- referenced as Type in API-    internalInteractionData :: Maybe InternalInteractionData, -- referenced as Data in API-    internalInteractionGuildId :: Maybe GuildId,-    internalInteractionChannelId :: Maybe ChannelId,-    internalInteractionMember :: Maybe GuildMember,-    internalInteractionUser :: Maybe User,-    internalInteractionToken :: InteractionToken,-    internalInteractionVersion :: Int,-    internalInteractionMessage :: Maybe Message+    interactionDataApplicationCommandOptionSubcommandFocused :: Bool   }   deriving (Show, Read, Eq) -instance ToJSON InternalInteraction where-  toJSON InternalInteraction {..} =-    object-      [ (name, value)-        | (name, Just value) <--            [ ("id", toMaybeJSON internalInteractionId),-              ("application_id", toMaybeJSON internalInteractionApplicationId),-              ("type", toMaybeJSON internalInteractionType),-              ("data", toJSON <$> internalInteractionData),-              ("guild_id", toJSON <$> internalInteractionGuildId),-              ("channel_id", toJSON <$> internalInteractionChannelId),-              ("member", toJSON <$> internalInteractionMember),-              ("user", toJSON <$> internalInteractionUser),-              ("token", toMaybeJSON internalInteractionToken),-              ("version", toMaybeJSON internalInteractionVersion),-              ("message", toJSON <$> internalInteractionMessage)-            ]-      ]--instance FromJSON InternalInteraction where+instance FromJSON InteractionDataApplicationCommandOptionSubcommand where   parseJSON =     withObject-      "InternalInteraction"-      ( \v ->-          InternalInteraction-            <$> v .: "id"-            <*> v .: "application_id"-            <*> v .: "type"-            <*> v .:? "data"-            <*> v .:? "guild_id"-            <*> v .:? "channel_id"-            <*> v .:? "member"-            <*> v .:? "user"-            <*> v .: "token"-            <*> v .: "version"-            <*> v .:? "message"+      "InteractionDataApplicationCommandOptionSubcommand"+      ( \v -> do+          t <- v .: "type" :: Parser Int+          case t of+            1 ->+              InteractionDataApplicationCommandOptionSubcommand+                <$> v .: "name"+                <*> v .:? "options" .!= []+                <*> v .:? "focused" .!= False+            _ -> fail "unexpected subcommand type"       ) --- | This is received if the interaction was a component or application command.------ https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-interaction-data-structure-data InternalInteractionData = InternalInteractionData-  { -- | Application command only, id of the invoked command-    internalInteractionDataApplicationCommandId :: Maybe ApplicationCommandId,-    -- | Application command only, name of the invoked command-    internalInteractionDataApplicationCommandName :: Maybe T.Text,-    -- | Application command only, the type of the invoked command-    internalInteractionDataApplicationCommandType :: Maybe ApplicationCommandType,-    -- | Application command only, converted users, roles, channels-    internalInteractionDataResolved :: Maybe ResolvedData,-    -- | Application command only, params and values-    internalInteractionDataOptions :: Maybe [InternalInteractionDataApplicationCommandOption],-    -- | Component only, the unique id-    internalInteractionDataCustomId :: Maybe T.Text,-    -- | Component only, the type of the component-    internalInteractionDataComponentType :: Maybe ComponentType,-    -- | Component only, the selected options if component is the select type-    internalInteractionDataValues :: Maybe [T.Text],-    -- | This is the id of the user or message being targetted by a user command-    -- or a message command-    internalInteractionDataTargetId :: Maybe Snowflake-  }+-- | Data for a single value.+data InteractionDataApplicationCommandOptionValue+  = InteractionDataApplicationCommandOptionValueString+      { interactionDataApplicationCommandOptionValueName :: T.Text,+        interactionDataApplicationCommandOptionValueStringValue :: Either T.Text T.Text+      }+  | InteractionDataApplicationCommandOptionValueInteger+      { interactionDataApplicationCommandOptionValueName :: T.Text,+        interactionDataApplicationCommandOptionValueIntegerValue :: Either T.Text Integer+      }+  | InteractionDataApplicationCommandOptionValueBoolean+      { interactionDataApplicationCommandOptionValueName :: T.Text,+        interactionDataApplicationCommandOptionValueBooleanValue :: Bool+      }+  | InteractionDataApplicationCommandOptionValueUser+      { interactionDataApplicationCommandOptionValueName :: T.Text,+        interactionDataApplicationCommandOptionValueUserValue :: UserId+      }+  | InteractionDataApplicationCommandOptionValueChannel+      { interactionDataApplicationCommandOptionValueName :: T.Text,+        interactionDataApplicationCommandOptionValueChannelValue :: ChannelId+      }+  | InteractionDataApplicationCommandOptionValueRole+      { interactionDataApplicationCommandOptionValueName :: T.Text,+        interactionDataApplicationCommandOptionValueRoleValue :: RoleId+      }+  | InteractionDataApplicationCommandOptionValueMentionable+      { interactionDataApplicationCommandOptionValueName :: T.Text,+        interactionDataApplicationCommandOptionValueMentionableValue :: Snowflake+      }+  | InteractionDataApplicationCommandOptionValueNumber+      { interactionDataApplicationCommandOptionValueName :: T.Text,+        interactionDataApplicationCommandOptionValueNumberValue :: Either T.Text Scientific+      }   deriving (Show, Read, Eq) -instance ToJSON InternalInteractionData where-  toJSON InternalInteractionData {..} =-    object-      [ (name, value)-        | (name, Just value) <--            [ ("id", toJSON <$> internalInteractionDataApplicationCommandId),-              ("name", toJSON <$> internalInteractionDataApplicationCommandName),-              ("type", toJSON <$> internalInteractionDataApplicationCommandType),-              ("resolved", toJSON <$> internalInteractionDataResolved),-              ("options", toJSON <$> internalInteractionDataOptions),-              ("custom_id", toJSON <$> internalInteractionDataCustomId),-              ("component_type", toJSON <$> internalInteractionDataComponentType),-              ("values", toJSON <$> internalInteractionDataValues),-              ("target_id", toJSON <$> internalInteractionDataTargetId)-            ]-      ]--instance FromJSON InternalInteractionData where+instance FromJSON InteractionDataApplicationCommandOptionValue where   parseJSON =     withObject-      "InternalInteractionData"-      ( \v ->-          InternalInteractionData-            <$> v .:? "id"-            <*> v .:? "name"-            <*> v .:? "type"-            <*> v .:? "resolved"-            <*> v .:? "options"-            <*> v .:? "custom_id"-            <*> v .:? "component_type"-            <*> v .:? "values"-            <*> v .:? "target_id"+      "InteractionDataApplicationCommandOptionValue"+      ( \v -> do+          name <- v .: "name"+          focused <- v .:? "focused" .!= False+          t <- v .: "type" :: Parser Int+          case t of+            3 ->+              InteractionDataApplicationCommandOptionValueString name+                <$> parseValue v focused+            4 ->+              InteractionDataApplicationCommandOptionValueInteger name+                <$> parseValue v focused+            10 ->+              InteractionDataApplicationCommandOptionValueNumber name+                <$> parseValue v focused+            5 ->+              InteractionDataApplicationCommandOptionValueBoolean name+                <$> v .: "value"+            6 ->+              InteractionDataApplicationCommandOptionValueUser name+                <$> v .: "value"+            7 ->+              InteractionDataApplicationCommandOptionValueChannel name+                <$> v .: "value"+            8 ->+              InteractionDataApplicationCommandOptionValueRole name+                <$> v .: "value"+            9 ->+              InteractionDataApplicationCommandOptionValueMentionable name+                <$> v .: "value"+            _ -> fail $ "unexpected interaction data application command option value type: " ++ show t       ) +parseValue :: (FromJSON a) => Object -> Bool -> Parser (Either T.Text a)+parseValue o True = Left <$> o .: "value"+parseValue o False = Right <$> o .: "value"++-- resolved data -- this should be formalised and integrated, instead of being+--  left as values+ -- | I'm not sure what this stuff is, so you're on your own. -- -- It's not worth the time working out how to create this stuff.@@ -413,141 +457,72 @@             <*> v .:? "channels"       ) --- | The application command payload for an interaction.-data InternalInteractionDataApplicationCommandOption = InternalInteractionDataApplicationCommandOption-  { internalInteractionDataApplicationCommandOptionName :: T.Text,-    internalInteractionDataApplicationCommandOptionType :: ApplicationCommandOptionType,-    -- | The value itself. Mutually exclusive with options. Docs are wrong that it's only numbers and strings.-    internalInteractionDataApplicationCommandOptionValue :: Maybe ApplicationCommandInteractionDataValue,-    -- | Only present in group subcommands and subcommands. Mutually exclusive with value.-    internalInteractionDataApplicationCommandOptionOptions :: Maybe [InternalInteractionDataApplicationCommandOption],-    -- | Whether this is the field that the user is currently typing in.-    internalInteractionDataApplicationCommandOptionFocused :: Maybe Bool-  }-  deriving (Show, Read, Eq)--instance ToJSON InternalInteractionDataApplicationCommandOption where-  toJSON InternalInteractionDataApplicationCommandOption {..} =-    object-      [ (name, value)-        | (name, Just value) <--            [ ("name", toMaybeJSON internalInteractionDataApplicationCommandOptionName),-              ("type", toMaybeJSON internalInteractionDataApplicationCommandOptionType),-              ("value", toJSON <$> internalInteractionDataApplicationCommandOptionValue),-              ("options", toJSON <$> internalInteractionDataApplicationCommandOptionOptions),-              ("focused", toJSON <$> internalInteractionDataApplicationCommandOptionFocused)-            ]-      ]--instance FromJSON InternalInteractionDataApplicationCommandOption where-  parseJSON =-    withObject-      "InternalInteractionDataApplicationCommandOption"-      ( \v ->-          InternalInteractionDataApplicationCommandOption-            <$> v .: "name"-            <*> typeParser v-            <*> (typeParser v >>= \t -> v .:? "value" >>= valueParser t)-            <*> v .:? "options"-            <*> v .:? "focused"-      )-    where-      typeParser v = v .: "type"-      valueParser t (Just v) = parseJSONACIDV t v-      valueParser _ Nothing = return Nothing- -- | The data to respond to an interaction with. Unless specified otherwise, you -- only have three seconds to reply to an interaction before a failure state is -- given.-data InteractionResponse = InteractionResponse-  { interactionResponseType :: InteractionCallbackType,-    interactionResponseData :: Maybe InteractionCallbackData-  }-  deriving (Show, Read, Eq)+data InteractionResponse+  = -- | ACK a Ping+    InteractionResponsePong+  | -- | Respond to an interaction with a message+    InteractionResponseChannelMessage InteractionResponseMessage+  | -- | ACK an interaction and edit a response later (use `CreateFollowupInteractionMessage` and `InteractionResponseMessage` to do so). User sees loading state.+    InteractionResponseDeferChannelMessage+  | -- | for components, ACK an interaction and edit the original message later; the user does not see a loading state.+    InteractionResponseDeferUpdateMessage+  | -- | for components, edit the message the component was attached to+    InteractionResponseUpdateMessage InteractionResponseMessage+  | -- | respond to an autocomplete interaction with suggested choices+    InteractionResponseAutocompleteResult InteractionResponseAutocomplete +-- | A basic interaction response, sending back the given text. interactionResponseBasic :: T.Text -> InteractionResponse-interactionResponseBasic t = InteractionResponse InteractionCallbackTypeChannelMessageWithSource (Just . InteractionCallbackDataMessages $ interactionCallbackMessagesBasic t)+interactionResponseBasic t = InteractionResponseChannelMessage (interactionResponseMessageBasic t)  instance ToJSON InteractionResponse where-  toJSON InteractionResponse {..} =-    object-      [ (name, value)-        | (name, Just value) <--            [ ("type", toMaybeJSON interactionResponseType),-              ("data", toJSON <$> interactionResponseData)-            ]-      ]---- | What's the type of the response?-data InteractionCallbackType-  = -- | Responds to a PING.-    InteractionCallbackTypePong-  | -- | Respond with a message to the interaction-    InteractionCallbackTypeChannelMessageWithSource-  | -- | Respond with a message to the interaction, after a delay. Sending this-    -- back means the interaction token lasts for 15 minutes.-    InteractionCallbackTypeDeferredChannelMessageWithSource-  | -- | For components, edit the original message later.-    InteractionCallbackTypeDeferredUpdateMessage-  | -- | For components, edit the original message.-    InteractionCallbackTypeUpdateMessage-  | -- | Respond to an autocomplete interaction with suggested choices.-    InteractionCallbackTypeApplicationCommandAutocompleteResult-  deriving (Show, Read, Eq, Data)--instance Enum InteractionCallbackType where-  fromEnum InteractionCallbackTypePong = 1-  fromEnum InteractionCallbackTypeChannelMessageWithSource = 4-  fromEnum InteractionCallbackTypeDeferredChannelMessageWithSource = 5-  fromEnum InteractionCallbackTypeDeferredUpdateMessage = 6-  fromEnum InteractionCallbackTypeUpdateMessage = 7-  fromEnum InteractionCallbackTypeApplicationCommandAutocompleteResult = 8-  toEnum a = fromJust $ lookup a table-    where-      table = makeTable InteractionCallbackTypePong--instance ToJSON InteractionCallbackType where-  toJSON = toJSON . fromEnum---- | Convenience wrapper for two separate types of callback.-data InteractionCallbackData-  = InteractionCallbackDataMessages InteractionCallbackMessages-  | InteractionCallbackDataAutocomplete InteractionCallbackAutocomplete-  deriving (Show, Read, Eq)+  toJSON InteractionResponsePong = object [("type", Number 1)]+  toJSON InteractionResponseDeferChannelMessage = object [("type", Number 5)]+  toJSON InteractionResponseDeferUpdateMessage = object [("type", Number 6)]+  toJSON (InteractionResponseChannelMessage ms) = object [("type", Number 4), ("data", toJSON ms)]+  toJSON (InteractionResponseUpdateMessage ms) = object [("type", Number 7), ("data", toJSON ms)]+  toJSON (InteractionResponseAutocompleteResult ms) = object [("type", Number 8), ("data", toJSON ms)] -instance ToJSON InteractionCallbackData where-  toJSON (InteractionCallbackDataMessages icdm) = toJSON icdm-  toJSON (InteractionCallbackDataAutocomplete icda) = toJSON icda+data InteractionResponseAutocomplete = InteractionResponseAutocompleteString [Choice T.Text] | InteractionResponseAutocompleteInteger [Choice Integer] | InteractionResponseAutocompleteNumber [Choice Scientific]+  deriving (Show, Eq) -type InteractionCallbackAutocomplete = [InternalApplicationCommandOptionChoice]+instance ToJSON InteractionResponseAutocomplete where+  toJSON (InteractionResponseAutocompleteString cs) = object [("choices", toJSON cs)]+  toJSON (InteractionResponseAutocompleteInteger cs) = object [("choices", toJSON cs)]+  toJSON (InteractionResponseAutocompleteNumber cs) = object [("choices", toJSON cs)]  -- | A cut down message structure.-data InteractionCallbackMessages = InteractionCallbackMessages-  { interactionCallbackMessagesTTS :: Maybe Bool,-    interactionCallbackMessagesContent :: Maybe T.Text,-    interactionCallbackMessagesEmbeds :: Maybe [Embed],-    interactionCallbackMessagesAllowedMentions :: Maybe AllowedMentions,-    interactionCallbackMessagesFlags :: Maybe InteractionCallbackDataFlags,-    interactionCallbackMessagesComponents :: Maybe [Component],-    interactionCallbackMessagesAttachments :: Maybe [Attachment]+data InteractionResponseMessage = InteractionResponseMessage+  { interactionResponseMessageTTS :: Maybe Bool,+    interactionResponseMessageContent :: Maybe T.Text,+    interactionResponseMessageEmbeds :: Maybe [CreateEmbed],+    interactionResponseMessageAllowedMentions :: Maybe AllowedMentions,+    interactionResponseMessageFlags :: Maybe InteractionResponseMessageFlags,+    interactionResponseMessageComponents :: Maybe [ComponentActionRow],+    interactionResponseMessageAttachments :: Maybe [Attachment]   }-  deriving (Show, Read, Eq)+  deriving (Show, Eq) -interactionCallbackMessagesBasic :: T.Text -> InteractionCallbackMessages-interactionCallbackMessagesBasic t = InteractionCallbackMessages Nothing (Just t) Nothing Nothing Nothing Nothing Nothing+-- | A basic interaction response, sending back the given text. This is+-- effectively a helper function.+interactionResponseMessageBasic :: T.Text -> InteractionResponseMessage+interactionResponseMessageBasic t = InteractionResponseMessage Nothing (Just t) Nothing Nothing Nothing Nothing Nothing -instance ToJSON InteractionCallbackMessages where-  toJSON InteractionCallbackMessages {..} =+instance ToJSON InteractionResponseMessage where+  toJSON InteractionResponseMessage {..} =     object       [ (name, value)         | (name, Just value) <--            [ ("tts", toJSON <$> interactionCallbackMessagesTTS),-              ("content", toJSON <$> interactionCallbackMessagesContent),-              ("embeds", toJSON <$> interactionCallbackMessagesEmbeds),-              ("allowed_mentions", toJSON <$> interactionCallbackMessagesAllowedMentions),-              ("flags", toJSON <$> interactionCallbackMessagesFlags),-              ("components", toJSON <$> interactionCallbackMessagesComponents),-              ("attachments", toJSON <$> interactionCallbackMessagesAttachments)+            [ ("tts", toJSON <$> interactionResponseMessageTTS),+              ("content", toJSON <$> interactionResponseMessageContent),+              ("embeds", toJSON . (createEmbed <$>) <$> interactionResponseMessageEmbeds),+              ("allowed_mentions", toJSON <$> interactionResponseMessageAllowedMentions),+              ("flags", toJSON <$> interactionResponseMessageFlags),+              ("components", toJSON <$> interactionResponseMessageComponents),+              ("attachments", toJSON <$> interactionResponseMessageAttachments)             ]       ] @@ -555,60 +530,17 @@ -- -- Currently the only flag is EPHERMERAL, which means only the user can see the -- message.-data InteractionCallbackDataFlag = InteractionCallbackDataFlagEphermeral+data InteractionResponseMessageFlag = InteractionResponseMessageFlagEphermeral   deriving (Show, Read, Eq) -newtype InteractionCallbackDataFlags = InteractionCallbackDataFlags [InteractionCallbackDataFlag]+newtype InteractionResponseMessageFlags = InteractionResponseMessageFlags [InteractionResponseMessageFlag]   deriving (Show, Read, Eq) -instance Enum InteractionCallbackDataFlag where-  fromEnum InteractionCallbackDataFlagEphermeral = 1 `shift` 6+instance Enum InteractionResponseMessageFlag where+  fromEnum InteractionResponseMessageFlagEphermeral = 1 `shift` 6   toEnum i-    | i == 1 `shift` 6 = InteractionCallbackDataFlagEphermeral+    | i == 1 `shift` 6 = InteractionResponseMessageFlagEphermeral     | otherwise = error $ "could not find InteractionCallbackDataFlag `" ++ show i ++ "`" -instance ToJSON InteractionCallbackDataFlags where-  toJSON (InteractionCallbackDataFlags fs) = Number $ fromInteger $ fromIntegral $ foldr (.|.) 0 (fromEnum <$> fs)--data ApplicationCommandInteractionDataValue-  = ApplicationCommandInteractionDataValueString T.Text-  | ApplicationCommandInteractionDataValueInteger Integer-  | ApplicationCommandInteractionDataValueBoolean Bool-  | ApplicationCommandInteractionDataValueUser Snowflake-  | ApplicationCommandInteractionDataValueChannel Snowflake-  | ApplicationCommandInteractionDataValueRole Snowflake-  | ApplicationCommandInteractionDataValueMentionable Snowflake-  | ApplicationCommandInteractionDataValueNumber Scientific-  deriving (Show, Eq, Ord, Read)--getTypeFromACIDV :: ApplicationCommandInteractionDataValue -> ApplicationCommandOptionType-getTypeFromACIDV acidv = case acidv of-  ApplicationCommandInteractionDataValueString _ -> ApplicationCommandOptionTypeString-  ApplicationCommandInteractionDataValueInteger _ -> ApplicationCommandOptionTypeInteger-  ApplicationCommandInteractionDataValueBoolean _ -> ApplicationCommandOptionTypeBoolean-  ApplicationCommandInteractionDataValueUser _ -> ApplicationCommandOptionTypeUser-  ApplicationCommandInteractionDataValueChannel _ -> ApplicationCommandOptionTypeChannel-  ApplicationCommandInteractionDataValueRole _ -> ApplicationCommandOptionTypeRole-  ApplicationCommandInteractionDataValueMentionable _ -> ApplicationCommandOptionTypeMentionable-  ApplicationCommandInteractionDataValueNumber _ -> ApplicationCommandOptionTypeNumber--instance ToJSON ApplicationCommandInteractionDataValue where-  toJSON (ApplicationCommandInteractionDataValueString t) = String t-  toJSON (ApplicationCommandInteractionDataValueNumber t) = Number t-  toJSON (ApplicationCommandInteractionDataValueInteger t) = Number $ fromInteger t-  toJSON (ApplicationCommandInteractionDataValueBoolean t) = Bool t-  toJSON (ApplicationCommandInteractionDataValueUser t) = toJSON t-  toJSON (ApplicationCommandInteractionDataValueChannel t) = toJSON t-  toJSON (ApplicationCommandInteractionDataValueRole t) = toJSON t-  toJSON (ApplicationCommandInteractionDataValueMentionable t) = toJSON t--parseJSONACIDV :: ApplicationCommandOptionType -> Value -> Parser (Maybe ApplicationCommandInteractionDataValue)-parseJSONACIDV ApplicationCommandOptionTypeString (String t) = return $ return (ApplicationCommandInteractionDataValueString t)-parseJSONACIDV ApplicationCommandOptionTypeInteger n = Just . ApplicationCommandInteractionDataValueInteger <$> parseJSON n-parseJSONACIDV ApplicationCommandOptionTypeNumber (Number t) = return $ return (ApplicationCommandInteractionDataValueNumber t)-parseJSONACIDV ApplicationCommandOptionTypeBoolean (Bool t) = return $ return (ApplicationCommandInteractionDataValueBoolean t)-parseJSONACIDV ApplicationCommandOptionTypeUser t = Just . ApplicationCommandInteractionDataValueUser <$> parseJSON t-parseJSONACIDV ApplicationCommandOptionTypeChannel t = Just . ApplicationCommandInteractionDataValueChannel <$> parseJSON t-parseJSONACIDV ApplicationCommandOptionTypeRole t = Just . ApplicationCommandInteractionDataValueRole <$> parseJSON t-parseJSONACIDV ApplicationCommandOptionTypeMentionable t = Just . ApplicationCommandInteractionDataValueMentionable <$> parseJSON t-parseJSONACIDV t v = fail $ "could not parse type " ++ show t ++ " from " ++ show v+instance ToJSON InteractionResponseMessageFlags where+  toJSON (InteractionResponseMessageFlags fs) = Number $ fromInteger $ fromIntegral $ foldr (.|.) 0 (fromEnum <$> fs)
src/Discord/Internal/Types/Prelude.hs view
@@ -1,8 +1,8 @@-{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE MultiParamTypeClasses  #-} {-# LANGUAGE FlexibleInstances  #-}+{-# LANGUAGE RankNTypes  #-}  -- | Provides base types and utility functions needed for modules in Discord.Internal.Types module Discord.Internal.Types.Prelude where@@ -14,16 +14,14 @@ import Data.Time.Clock import qualified Data.Text as T import Data.Time.Clock.POSIX-import Control.Monad (mzero)  import Data.Functor.Compose (Compose(Compose, getCompose)) import Data.Bifunctor (first) import Text.Read (readMaybe) import Data.Data (Data (dataTypeOf), dataTypeConstrs, fromConstr)-import Data.Maybe (fromJust)  -- | Authorization token for the Discord API-data Auth = Auth T.Text+newtype Auth = Auth T.Text   deriving (Show, Read, Eq, Ord)  @@ -47,10 +45,14 @@   toJSON (Snowflake snowflake) = String . T.pack $ show snowflake  instance FromJSON Snowflake where-  parseJSON (String snowflake) = case readMaybe (T.unpack snowflake) of-    Nothing -> fail "null snowflake"-    (Just i) -> pure i-  parseJSON _ = mzero+  parseJSON =+    withText+      "Snowflake"+      ( \snowflake ->+          case readMaybe (T.unpack snowflake) of+            Nothing -> fail "null snowflake"+            (Just i) -> pure i+      )  type ChannelId = Snowflake type StageId = Snowflake@@ -65,7 +67,7 @@ type IntegrationId = Snowflake type WebhookId = Snowflake type ParentId = Snowflake-type ApplicationId = Snowflake +type ApplicationId = Snowflake type ApplicationCommandId = Snowflake type InteractionId = Snowflake type InteractionToken = T.Text@@ -80,42 +82,42 @@ epochTime :: UTCTime epochTime = posixSecondsToUTCTime 0 -type ColorInteger = Integer--makeTable :: (Data t, Enum t) => t -> [(Int, t)]-makeTable t = map (\cData -> let c = fromConstr cData in (fromEnum c, c)) (dataTypeConstrs $ dataTypeOf t)+{- -toMaybeJSON :: (ToJSON a) => a -> Maybe Value-toMaybeJSON = return . toJSON+InternalDiscordEnum is a hack-y typeclass, but it's the best solution overall.+The best we can do is prevent the end-user from seeing this. --- | What type of interaction has a user requested? Each requires its own type--- of response.-data InteractionType-  = InteractionTypePing-  | InteractionTypeApplicationCommand-  | InteractionTypeMessageComponent-  | InteractionTypeApplicationCommandAutocomplete-  deriving (Show, Read, Data, Eq, Ord)+typeclass Bounded (minBound + maxBound) could replace discordTypeStartValue, but+it can't derive instances for types like DiscordColor, which have simple sum types involved. -instance Enum InteractionType where-  fromEnum InteractionTypePing = 1-  fromEnum InteractionTypeApplicationCommand = 2-  fromEnum InteractionTypeMessageComponent = 3-  fromEnum InteractionTypeApplicationCommandAutocomplete = 4-  toEnum a = fromJust $ lookup a table-    where-      table = makeTable InteractionTypePing+typeclass Enum (toEnum + fromEnum) requires defining both A->Int and Int->A.+If we handle both at once (with an inline map), it's no longer typesafe. -instance ToJSON InteractionType where-  toJSON = toJSON . fromEnum+External packages exist, but bloat our dependencies -instance FromJSON InteractionType where-  parseJSON = withScientific "InteractionType" (return . toEnum . round)+-}+class Data a => InternalDiscordEnum a where+  discordTypeStartValue :: a+  fromDiscordType :: a -> Int+  discordTypeTable :: [(Int, a)]+  discordTypeTable =  map (\d -> (fromDiscordType d, d)) (makeTable discordTypeStartValue)+    where+      makeTable :: Data b => b -> [b]+      makeTable t = map fromConstr (dataTypeConstrs $ dataTypeOf t) -class Internals a b where-  toInternal :: a -> b-  fromInternal :: b -> Maybe a+  discordTypeParseJSON :: String -> Value -> Parser a+  discordTypeParseJSON name =+    withScientific+      name+      ( \i -> do+          case maybeInt i >>= (`lookup` discordTypeTable) of+            Nothing -> fail $ "could not parse type: " ++ show i+            Just d -> return d+      )+    where+      maybeInt i+        | fromIntegral (round i) == i = Just $ round i+        | otherwise = Nothing -instance Internals a a where-  toInternal = id-  fromInternal = Just+toMaybeJSON :: (ToJSON a) => a -> Maybe Value+toMaybeJSON = return . toJSON
src/Discord/Types.hs view
@@ -1,3 +1,4 @@+-- | Re-export user-visible types module Discord.Types   ( module Discord.Internal.Types   ) where@@ -6,4 +7,9 @@     ( GatewaySendableInternal(..)     , GatewayReceivable(..)     , EventInternalParse(..)+    , InternalDiscordEnum(..)++    , colorToInternal+    , convertToRGB+    , hexToRGB     )