discord-haskell 1.10.0 → 1.11.0
raw patch · 24 files changed
+2507/−272 lines, 24 filesdep +scientificPVP ok
version bump matches the API change (PVP)
Dependencies added: scientific
API changes (from Hackage documentation)
- Discord.Internal.Rest.Channel: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Rest.Channel.AllowedMentions
- Discord.Internal.Rest.Channel: instance Data.Default.Class.Default Discord.Internal.Rest.Channel.AllowedMentions
- Discord.Internal.Rest.Channel: instance GHC.Classes.Eq Discord.Internal.Rest.Channel.AllowedMentions
- Discord.Internal.Rest.Channel: instance GHC.Classes.Ord Discord.Internal.Rest.Channel.AllowedMentions
- Discord.Internal.Rest.Channel: instance GHC.Read.Read Discord.Internal.Rest.Channel.AllowedMentions
- Discord.Internal.Rest.Channel: instance GHC.Show.Show Discord.Internal.Rest.Channel.AllowedMentions
- Discord.Internal.Rest.Guild: [GetGuildEmbed] :: GuildId -> GuildRequest GuildEmbed
- Discord.Internal.Rest.Guild: [ModifyGuildEmbed] :: GuildId -> GuildEmbed -> GuildRequest GuildEmbed
- Discord.Internal.Types.Channel: Emoji :: Maybe EmojiId -> Text -> Maybe [RoleId] -> Maybe User -> Maybe Bool -> Maybe Bool -> Emoji
- Discord.Internal.Types.Channel: [emojiAnimated] :: Emoji -> Maybe Bool
- Discord.Internal.Types.Channel: [emojiId] :: Emoji -> Maybe EmojiId
- Discord.Internal.Types.Channel: [emojiManaged] :: Emoji -> Maybe Bool
- Discord.Internal.Types.Channel: [emojiName] :: Emoji -> Text
- Discord.Internal.Types.Channel: [emojiRoles] :: Emoji -> Maybe [RoleId]
- Discord.Internal.Types.Channel: [emojiUser] :: Emoji -> Maybe User
- Discord.Internal.Types.Channel: [messageChannel] :: Message -> ChannelId
- Discord.Internal.Types.Channel: [messageGuild] :: Message -> Maybe GuildId
- Discord.Internal.Types.Channel: [messageText] :: Message -> Text
- Discord.Internal.Types.Channel: [referencedMessage] :: Message -> Maybe Message
- Discord.Internal.Types.Channel: data Emoji
- Discord.Internal.Types.Channel: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Channel.Emoji
- Discord.Internal.Types.Channel: instance GHC.Classes.Eq Discord.Internal.Types.Channel.Emoji
- Discord.Internal.Types.Channel: instance GHC.Classes.Ord Discord.Internal.Types.Channel.Emoji
- Discord.Internal.Types.Channel: instance GHC.Read.Read Discord.Internal.Types.Channel.Emoji
- Discord.Internal.Types.Channel: instance GHC.Show.Show Discord.Internal.Types.Channel.Emoji
- Discord.Internal.Types.Guild: GuildEmbed :: Bool -> ChannelId -> GuildEmbed
- Discord.Internal.Types.Guild: GuildMember :: User -> Maybe Text -> [Snowflake] -> UTCTime -> Bool -> Bool -> GuildMember
- Discord.Internal.Types.Guild: [embedChannel] :: GuildEmbed -> ChannelId
- Discord.Internal.Types.Guild: [embedEnabled] :: GuildEmbed -> Bool
- Discord.Internal.Types.Guild: [guildEmbedChannel] :: Guild -> Maybe ChannelId
- Discord.Internal.Types.Guild: [guildEmbedEnabled] :: Guild -> Maybe Bool
- Discord.Internal.Types.Guild: [memberDeaf] :: GuildMember -> Bool
- Discord.Internal.Types.Guild: [memberJoinedAt] :: GuildMember -> UTCTime
- Discord.Internal.Types.Guild: [memberMute] :: GuildMember -> Bool
- Discord.Internal.Types.Guild: [memberNick] :: GuildMember -> Maybe Text
- Discord.Internal.Types.Guild: [memberRoles] :: GuildMember -> [Snowflake]
- Discord.Internal.Types.Guild: [memberUser] :: GuildMember -> User
- Discord.Internal.Types.Guild: data GuildEmbed
- Discord.Internal.Types.Guild: data GuildMember
- Discord.Internal.Types.Guild: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Guild.GuildEmbed
- Discord.Internal.Types.Guild: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Guild.GuildMember
- Discord.Internal.Types.Guild: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Guild.GuildEmbed
- Discord.Internal.Types.Guild: instance GHC.Classes.Eq Discord.Internal.Types.Guild.GuildEmbed
- Discord.Internal.Types.Guild: instance GHC.Classes.Eq Discord.Internal.Types.Guild.GuildMember
- Discord.Internal.Types.Guild: instance GHC.Classes.Ord Discord.Internal.Types.Guild.GuildEmbed
- Discord.Internal.Types.Guild: instance GHC.Classes.Ord Discord.Internal.Types.Guild.GuildMember
- Discord.Internal.Types.Guild: instance GHC.Read.Read Discord.Internal.Types.Guild.GuildEmbed
- Discord.Internal.Types.Guild: instance GHC.Read.Read Discord.Internal.Types.Guild.GuildMember
- Discord.Internal.Types.Guild: instance GHC.Show.Show Discord.Internal.Types.Guild.GuildEmbed
- Discord.Internal.Types.Guild: instance GHC.Show.Show Discord.Internal.Types.Guild.GuildMember
- Discord.Types: GuildEmbed :: Bool -> ChannelId -> GuildEmbed
- Discord.Types: [embedChannel] :: GuildEmbed -> ChannelId
- Discord.Types: [embedEnabled] :: GuildEmbed -> Bool
- Discord.Types: [guildEmbedChannel] :: Guild -> Maybe ChannelId
- Discord.Types: [guildEmbedEnabled] :: Guild -> Maybe Bool
- Discord.Types: [messageChannel] :: Message -> ChannelId
- Discord.Types: [messageGuild] :: Message -> Maybe GuildId
- Discord.Types: [messageText] :: Message -> Text
- Discord.Types: [referencedMessage] :: Message -> Maybe Message
- Discord.Types: data GuildEmbed
+ Discord: [cacheApplication] :: Cache -> PartialApplication
+ Discord.Internal.Gateway: [cacheApplication] :: Cache -> PartialApplication
+ Discord.Internal.Gateway.Cache: [cacheApplication] :: Cache -> PartialApplication
+ Discord.Internal.Rest.ApplicationCommands: [BatchEditApplicationCommandPermissions] :: ApplicationId -> GuildId -> [GuildApplicationCommandPermissions] -> ApplicationCommandRequest [GuildApplicationCommandPermissions]
+ Discord.Internal.Rest.ApplicationCommands: [BulkOverWriteGlobalApplicationCommand] :: ApplicationId -> [CreateApplicationCommand] -> ApplicationCommandRequest ()
+ Discord.Internal.Rest.ApplicationCommands: [BulkOverWriteGuildApplicationCommand] :: ApplicationId -> GuildId -> [CreateApplicationCommand] -> ApplicationCommandRequest ()
+ Discord.Internal.Rest.ApplicationCommands: [CreateGlobalApplicationCommand] :: ApplicationId -> CreateApplicationCommand -> ApplicationCommandRequest InternalApplicationCommand
+ Discord.Internal.Rest.ApplicationCommands: [CreateGuildApplicationCommand] :: ApplicationId -> GuildId -> CreateApplicationCommand -> ApplicationCommandRequest InternalApplicationCommand
+ Discord.Internal.Rest.ApplicationCommands: [DeleteGlobalApplicationCommand] :: ApplicationId -> ApplicationCommandId -> ApplicationCommandRequest ()
+ Discord.Internal.Rest.ApplicationCommands: [DeleteGuildApplicationCommand] :: ApplicationId -> GuildId -> ApplicationCommandId -> ApplicationCommandRequest ()
+ Discord.Internal.Rest.ApplicationCommands: [EditApplicationCommandPermissions] :: ApplicationId -> GuildId -> ApplicationCommandId -> [ApplicationCommandPermissions] -> ApplicationCommandRequest GuildApplicationCommandPermissions
+ Discord.Internal.Rest.ApplicationCommands: [EditGlobalApplicationCommand] :: ApplicationId -> ApplicationCommandId -> EditApplicationCommand -> ApplicationCommandRequest InternalApplicationCommand
+ Discord.Internal.Rest.ApplicationCommands: [EditGuildApplicationCommand] :: ApplicationId -> GuildId -> ApplicationCommandId -> CreateApplicationCommand -> ApplicationCommandRequest InternalApplicationCommand
+ Discord.Internal.Rest.ApplicationCommands: [GetApplicationCommandPermissions] :: ApplicationId -> GuildId -> ApplicationCommandId -> ApplicationCommandRequest GuildApplicationCommandPermissions
+ Discord.Internal.Rest.ApplicationCommands: [GetGlobalApplicationCommand] :: ApplicationId -> ApplicationCommandId -> ApplicationCommandRequest InternalApplicationCommand
+ Discord.Internal.Rest.ApplicationCommands: [GetGlobalApplicationCommands] :: ApplicationId -> ApplicationCommandRequest [InternalApplicationCommand]
+ Discord.Internal.Rest.ApplicationCommands: [GetGuildApplicationCommandPermissions] :: ApplicationId -> GuildId -> ApplicationCommandRequest GuildApplicationCommandPermissions
+ Discord.Internal.Rest.ApplicationCommands: [GetGuildApplicationCommand] :: ApplicationId -> GuildId -> ApplicationCommandId -> ApplicationCommandRequest InternalApplicationCommand
+ Discord.Internal.Rest.ApplicationCommands: [GetGuildApplicationCommands] :: ApplicationId -> GuildId -> ApplicationCommandRequest [InternalApplicationCommand]
+ Discord.Internal.Rest.ApplicationCommands: applicationCommandJsonRequest :: ApplicationCommandRequest a -> JsonRequest
+ Discord.Internal.Rest.ApplicationCommands: applicationCommandMajorRoute :: ApplicationCommandRequest a -> String
+ Discord.Internal.Rest.ApplicationCommands: applications :: ApplicationId -> Url 'Https
+ Discord.Internal.Rest.ApplicationCommands: data ApplicationCommandRequest a
+ Discord.Internal.Rest.ApplicationCommands: instance Discord.Internal.Rest.Prelude.Request (Discord.Internal.Rest.ApplicationCommands.ApplicationCommandRequest a)
+ Discord.Internal.Rest.Channel: [messageDetailedComponents] :: MessageDetailedOpts -> Maybe [Component]
+ Discord.Internal.Rest.Channel: [messageDetailedStickerIds] :: MessageDetailedOpts -> Maybe [StickerId]
+ Discord.Internal.Rest.Guild: [GetGuildWidget] :: GuildId -> GuildRequest GuildWidget
+ Discord.Internal.Rest.Guild: [ModifyGuildWidget] :: GuildId -> GuildWidget -> GuildRequest GuildWidget
+ Discord.Internal.Rest.Interactions: [CreateFollowupInteractionMessage] :: ApplicationId -> InteractionToken -> InteractionCallbackMessages -> InteractionResponseRequest Message
+ Discord.Internal.Rest.Interactions: [CreateInteractionResponse] :: InteractionId -> InteractionToken -> InteractionResponse -> InteractionResponseRequest ()
+ Discord.Internal.Rest.Interactions: [DeleteFollowupInteractionMessage] :: ApplicationId -> InteractionToken -> MessageId -> InteractionResponseRequest ()
+ Discord.Internal.Rest.Interactions: [DeleteOriginalInteractionResponse] :: ApplicationId -> InteractionToken -> InteractionResponseRequest ()
+ Discord.Internal.Rest.Interactions: [EditFollowupInteractionMessage] :: ApplicationId -> InteractionToken -> MessageId -> InteractionResponse -> InteractionResponseRequest Message
+ Discord.Internal.Rest.Interactions: [EditOriginalInteractionResponse] :: ApplicationId -> InteractionToken -> InteractionCallbackMessages -> InteractionResponseRequest Message
+ Discord.Internal.Rest.Interactions: [GetFollowupInteractionMessage] :: ApplicationId -> InteractionToken -> MessageId -> InteractionResponseRequest Message
+ Discord.Internal.Rest.Interactions: [GetOriginalInteractionResponse] :: ApplicationId -> InteractionToken -> InteractionResponseRequest Message
+ Discord.Internal.Rest.Interactions: data InteractionResponseRequest a
+ Discord.Internal.Rest.Interactions: instance Discord.Internal.Rest.Prelude.Request (Discord.Internal.Rest.Interactions.InteractionResponseRequest a)
+ Discord.Internal.Rest.Interactions: interaction :: ApplicationId -> InteractionToken -> Url 'Https
+ Discord.Internal.Rest.Interactions: interactionResponseJsonRequest :: InteractionResponseRequest a -> JsonRequest
+ Discord.Internal.Rest.Interactions: interactionResponseMajorRoute :: InteractionResponseRequest a -> String
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandChannelTypeDM :: ApplicationCommandChannelType
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandChannelTypeGroupDM :: ApplicationCommandChannelType
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandChannelTypeGuildCategory :: ApplicationCommandChannelType
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandChannelTypeGuildNews :: ApplicationCommandChannelType
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandChannelTypeGuildNewsThread :: ApplicationCommandChannelType
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandChannelTypeGuildPrivateThread :: ApplicationCommandChannelType
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandChannelTypeGuildPublicThread :: ApplicationCommandChannelType
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandChannelTypeGuildStageVoice :: ApplicationCommandChannelType
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandChannelTypeGuildStore :: ApplicationCommandChannelType
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandChannelTypeGuildText :: ApplicationCommandChannelType
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandChannelTypeGuildVoice :: ApplicationCommandChannelType
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandChatInput :: ApplicationCommandId -> ApplicationId -> Maybe GuildId -> Text -> Text -> Maybe ApplicationCommandOptions -> Maybe Bool -> Snowflake -> ApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandMessage :: ApplicationCommandId -> ApplicationId -> Maybe GuildId -> Text -> Maybe Bool -> Snowflake -> ApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionSubcommand :: Text -> Text -> [ApplicationCommandOptionValue] -> ApplicationCommandOptionSubcommand
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionSubcommandGroup :: Text -> Text -> [ApplicationCommandOptionSubcommand] -> ApplicationCommandOptionSubcommandOrGroup
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionSubcommandOrGroupSubcommand :: ApplicationCommandOptionSubcommand -> ApplicationCommandOptionSubcommandOrGroup
+ 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: ApplicationCommandOptionValueBoolean :: Text -> Text -> Maybe Bool -> ApplicationCommandOptionValue
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionValueChannel :: Text -> Text -> Maybe 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: ApplicationCommandOptionValueMentionable :: Text -> Text -> Maybe 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: ApplicationCommandOptionValueRole :: Text -> Text -> Maybe Bool -> ApplicationCommandOptionValue
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionValueString :: Text -> Text -> Maybe Bool -> Maybe [Choice Text] -> Maybe Bool -> ApplicationCommandOptionValue
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandOptionValueUser :: Text -> Text -> Maybe Bool -> ApplicationCommandOptionValue
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandPermissionTypeRole :: ApplicationCommandPermissionType
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandPermissionTypeUser :: ApplicationCommandPermissionType
+ Discord.Internal.Types.ApplicationCommands: ApplicationCommandPermissions :: Snowflake -> ApplicationCommandPermissionType -> Bool -> ApplicationCommandPermissions
+ 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: ApplicationCommandUser :: ApplicationCommandId -> ApplicationId -> Maybe GuildId -> Text -> Maybe Bool -> Snowflake -> ApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: Choice :: Text -> a -> Choice a
+ 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: GuildApplicationCommandPermissions :: ApplicationCommandId -> ApplicationId -> GuildId -> [ApplicationCommandPermissions] -> GuildApplicationCommandPermissions
+ 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: [applicationCommandApplicationId] :: ApplicationCommand -> ApplicationId
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandDefaultPermission] :: ApplicationCommand -> Maybe Bool
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandDescription] :: ApplicationCommand -> Text
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandGuildId] :: ApplicationCommand -> Maybe GuildId
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandId] :: ApplicationCommand -> ApplicationCommandId
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandName] :: ApplicationCommand -> Text
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionSubcommandDescription] :: ApplicationCommandOptionSubcommand -> Text
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionSubcommandGroupDescription] :: ApplicationCommandOptionSubcommandOrGroup -> Text
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionSubcommandGroupName] :: ApplicationCommandOptionSubcommandOrGroup -> Text
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionSubcommandGroupOptions] :: ApplicationCommandOptionSubcommandOrGroup -> [ApplicationCommandOptionSubcommand]
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionSubcommandName] :: ApplicationCommandOptionSubcommand -> Text
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionSubcommandOptions] :: ApplicationCommandOptionSubcommand -> [ApplicationCommandOptionValue]
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionValueAutocomplete] :: ApplicationCommandOptionValue -> Maybe Bool
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionValueChannelTypes] :: ApplicationCommandOptionValue -> Maybe [ApplicationCommandChannelType]
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionValueDescription] :: ApplicationCommandOptionValue -> Text
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionValueIntegerChoices] :: ApplicationCommandOptionValue -> Maybe [Choice Integer]
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionValueIntegerMaxVal] :: ApplicationCommandOptionValue -> Maybe Integer
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionValueIntegerMinVal] :: ApplicationCommandOptionValue -> Maybe Integer
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionValueName] :: ApplicationCommandOptionValue -> Text
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionValueNumberChoices] :: ApplicationCommandOptionValue -> Maybe [Choice Scientific]
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionValueNumberMaxVal] :: ApplicationCommandOptionValue -> Maybe Scientific
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionValueNumberMinVal] :: ApplicationCommandOptionValue -> Maybe Scientific
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionValueRequired] :: ApplicationCommandOptionValue -> Maybe Bool
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandOptionValueStringChoices] :: ApplicationCommandOptionValue -> Maybe [Choice Text]
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandOptions] :: ApplicationCommand -> Maybe ApplicationCommandOptions
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandPermissionsId] :: ApplicationCommandPermissions -> Snowflake
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandPermissionsPermission] :: ApplicationCommandPermissions -> Bool
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandPermissionsType] :: ApplicationCommandPermissions -> ApplicationCommandPermissionType
+ Discord.Internal.Types.ApplicationCommands: [applicationCommandVersion] :: ApplicationCommand -> Snowflake
+ Discord.Internal.Types.ApplicationCommands: [choiceName] :: Choice a -> Text
+ Discord.Internal.Types.ApplicationCommands: [choiceValue] :: Choice a -> a
+ Discord.Internal.Types.ApplicationCommands: [createApplicationCommandDefaultPermission] :: CreateApplicationCommand -> Maybe Bool
+ Discord.Internal.Types.ApplicationCommands: [createApplicationCommandDescription] :: CreateApplicationCommand -> Text
+ Discord.Internal.Types.ApplicationCommands: [createApplicationCommandName] :: CreateApplicationCommand -> Text
+ Discord.Internal.Types.ApplicationCommands: [createApplicationCommandOptions] :: CreateApplicationCommand -> Maybe [InternalApplicationCommandOption]
+ Discord.Internal.Types.ApplicationCommands: [createApplicationCommandType] :: CreateApplicationCommand -> Maybe ApplicationCommandType
+ Discord.Internal.Types.ApplicationCommands: [editApplicationCommandDefaultPermission] :: EditApplicationCommand -> Maybe Bool
+ Discord.Internal.Types.ApplicationCommands: [editApplicationCommandDescription] :: EditApplicationCommand -> Maybe Text
+ Discord.Internal.Types.ApplicationCommands: [editApplicationCommandName] :: EditApplicationCommand -> Maybe Text
+ Discord.Internal.Types.ApplicationCommands: [editApplicationCommandOptions] :: EditApplicationCommand -> Maybe [InternalApplicationCommandOption]
+ Discord.Internal.Types.ApplicationCommands: [editApplicationCommandType] :: EditApplicationCommand -> Maybe ApplicationCommandType
+ Discord.Internal.Types.ApplicationCommands: [guildApplicationCommandPermissionsApplicationId] :: GuildApplicationCommandPermissions -> ApplicationId
+ Discord.Internal.Types.ApplicationCommands: [guildApplicationCommandPermissionsGuildId] :: GuildApplicationCommandPermissions -> GuildId
+ Discord.Internal.Types.ApplicationCommands: [guildApplicationCommandPermissionsId] :: GuildApplicationCommandPermissions -> ApplicationCommandId
+ Discord.Internal.Types.ApplicationCommands: [guildApplicationCommandPermissionsPermissions] :: GuildApplicationCommandPermissions -> [ApplicationCommandPermissions]
+ 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: createApplicationCommandChatInput :: Text -> Text -> Maybe CreateApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: createApplicationCommandMessage :: Text -> Maybe CreateApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: createApplicationCommandUser :: Text -> Maybe CreateApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: data ApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: data ApplicationCommandChannelType
+ Discord.Internal.Types.ApplicationCommands: data ApplicationCommandOptionSubcommand
+ Discord.Internal.Types.ApplicationCommands: data ApplicationCommandOptionSubcommandOrGroup
+ Discord.Internal.Types.ApplicationCommands: data ApplicationCommandOptionType
+ Discord.Internal.Types.ApplicationCommands: data ApplicationCommandOptionValue
+ Discord.Internal.Types.ApplicationCommands: data ApplicationCommandPermissionType
+ Discord.Internal.Types.ApplicationCommands: data ApplicationCommandPermissions
+ Discord.Internal.Types.ApplicationCommands: data ApplicationCommandType
+ Discord.Internal.Types.ApplicationCommands: data Choice a
+ Discord.Internal.Types.ApplicationCommands: data CreateApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: data EditApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: data GuildApplicationCommandPermissions
+ 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.ApplicationCommandChannelType
+ 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.ApplicationCommandPermissions
+ 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.GuildApplicationCommandPermissions
+ 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.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Discord.Internal.Types.ApplicationCommands.Choice a)
+ Discord.Internal.Types.ApplicationCommands: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.ApplicationCommands.ApplicationCommandChannelType
+ 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.ApplicationCommandPermissions
+ 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.CreateApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.ApplicationCommands.EditApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.ApplicationCommands.GuildApplicationCommandPermissions
+ 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.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Discord.Internal.Types.ApplicationCommands.Choice a)
+ Discord.Internal.Types.ApplicationCommands: instance Data.Data.Data Discord.Internal.Types.ApplicationCommands.ApplicationCommandChannelType
+ 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.Base.Functor Discord.Internal.Types.ApplicationCommands.Choice
+ Discord.Internal.Types.ApplicationCommands: instance GHC.Classes.Eq Discord.Internal.Types.ApplicationCommands.ApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: instance GHC.Classes.Eq Discord.Internal.Types.ApplicationCommands.ApplicationCommandChannelType
+ Discord.Internal.Types.ApplicationCommands: instance GHC.Classes.Eq Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptionSubcommand
+ Discord.Internal.Types.ApplicationCommands: instance GHC.Classes.Eq Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptionSubcommandOrGroup
+ 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.ApplicationCommandOptionValue
+ Discord.Internal.Types.ApplicationCommands: instance GHC.Classes.Eq Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptions
+ 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.ApplicationCommandPermissions
+ 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.CreateApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: instance GHC.Classes.Eq Discord.Internal.Types.ApplicationCommands.GuildApplicationCommandPermissions
+ 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.Eq a => GHC.Classes.Eq (Discord.Internal.Types.ApplicationCommands.Choice a)
+ Discord.Internal.Types.ApplicationCommands: instance GHC.Classes.Ord Discord.Internal.Types.ApplicationCommands.ApplicationCommandPermissionType
+ Discord.Internal.Types.ApplicationCommands: instance GHC.Classes.Ord Discord.Internal.Types.ApplicationCommands.ApplicationCommandPermissions
+ Discord.Internal.Types.ApplicationCommands: instance GHC.Classes.Ord Discord.Internal.Types.ApplicationCommands.GuildApplicationCommandPermissions
+ 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.ApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: instance GHC.Read.Read Discord.Internal.Types.ApplicationCommands.ApplicationCommandChannelType
+ Discord.Internal.Types.ApplicationCommands: instance GHC.Read.Read Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptionSubcommand
+ Discord.Internal.Types.ApplicationCommands: instance GHC.Read.Read Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptionSubcommandOrGroup
+ 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.ApplicationCommandOptionValue
+ Discord.Internal.Types.ApplicationCommands: instance GHC.Read.Read Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptions
+ 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.ApplicationCommandPermissions
+ 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.CreateApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: instance GHC.Read.Read Discord.Internal.Types.ApplicationCommands.GuildApplicationCommandPermissions
+ 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.Read.Read a => GHC.Read.Read (Discord.Internal.Types.ApplicationCommands.Choice a)
+ Discord.Internal.Types.ApplicationCommands: instance GHC.Show.Show Discord.Internal.Types.ApplicationCommands.ApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: instance GHC.Show.Show Discord.Internal.Types.ApplicationCommands.ApplicationCommandChannelType
+ Discord.Internal.Types.ApplicationCommands: instance GHC.Show.Show Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptionSubcommand
+ Discord.Internal.Types.ApplicationCommands: instance GHC.Show.Show Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptionSubcommandOrGroup
+ 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.ApplicationCommandOptionValue
+ Discord.Internal.Types.ApplicationCommands: instance GHC.Show.Show Discord.Internal.Types.ApplicationCommands.ApplicationCommandOptions
+ 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.ApplicationCommandPermissions
+ 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.CreateApplicationCommand
+ Discord.Internal.Types.ApplicationCommands: instance GHC.Show.Show Discord.Internal.Types.ApplicationCommands.GuildApplicationCommandPermissions
+ 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: instance GHC.Show.Show a => GHC.Show.Show (Discord.Internal.Types.ApplicationCommands.Choice a)
+ Discord.Internal.Types.ApplicationCommands: type InternalApplicationCommandOptionChoice = Choice StringNumberValue
+ Discord.Internal.Types.Channel: AllowedMentions :: Bool -> Bool -> Bool -> [UserId] -> [RoleId] -> Bool -> AllowedMentions
+ Discord.Internal.Types.Channel: MessageActivity :: MessageActivityType -> Maybe Text -> MessageActivity
+ Discord.Internal.Types.Channel: MessageActivityTypeJoin :: MessageActivityType
+ Discord.Internal.Types.Channel: MessageActivityTypeJoinRequest :: MessageActivityType
+ Discord.Internal.Types.Channel: MessageActivityTypeListen :: MessageActivityType
+ Discord.Internal.Types.Channel: MessageActivityTypeSpectate :: MessageActivityType
+ Discord.Internal.Types.Channel: MessageFlagCrossposted :: MessageFlag
+ Discord.Internal.Types.Channel: MessageFlagEphemeral :: MessageFlag
+ Discord.Internal.Types.Channel: MessageFlagHasThread :: MessageFlag
+ Discord.Internal.Types.Channel: MessageFlagIsCrosspost :: MessageFlag
+ Discord.Internal.Types.Channel: MessageFlagLoading :: MessageFlag
+ Discord.Internal.Types.Channel: MessageFlagSourceMessageDeleted :: MessageFlag
+ Discord.Internal.Types.Channel: MessageFlagSupressEmbeds :: MessageFlag
+ Discord.Internal.Types.Channel: MessageFlagUrgent :: MessageFlag
+ Discord.Internal.Types.Channel: MessageFlags :: [MessageFlag] -> MessageFlags
+ Discord.Internal.Types.Channel: MessageInteraction :: InteractionId -> InteractionType -> Text -> User -> MessageInteraction
+ Discord.Internal.Types.Channel: MessageTypeCall :: MessageType
+ Discord.Internal.Types.Channel: MessageTypeChannelFollowAdd :: MessageType
+ Discord.Internal.Types.Channel: MessageTypeChannelIconChange :: MessageType
+ Discord.Internal.Types.Channel: MessageTypeChannelNameChange :: MessageType
+ Discord.Internal.Types.Channel: MessageTypeChannelPinnedMessage :: MessageType
+ Discord.Internal.Types.Channel: MessageTypeChatInputCommand :: MessageType
+ Discord.Internal.Types.Channel: MessageTypeContextMenuCommand :: MessageType
+ Discord.Internal.Types.Channel: MessageTypeDefault :: MessageType
+ Discord.Internal.Types.Channel: MessageTypeGuildDiscoveryDisqualified :: MessageType
+ Discord.Internal.Types.Channel: MessageTypeGuildDiscoveryGracePeriodFinalWarning :: MessageType
+ Discord.Internal.Types.Channel: MessageTypeGuildDiscoveryGracePeriodInitialWarning :: MessageType
+ Discord.Internal.Types.Channel: MessageTypeGuildDiscoveryRequalified :: MessageType
+ Discord.Internal.Types.Channel: MessageTypeGuildInviteReminder :: MessageType
+ Discord.Internal.Types.Channel: MessageTypeGuildMemberJoin :: MessageType
+ Discord.Internal.Types.Channel: MessageTypeRecipientAdd :: MessageType
+ Discord.Internal.Types.Channel: MessageTypeRecipientRemove :: MessageType
+ Discord.Internal.Types.Channel: MessageTypeReply :: MessageType
+ Discord.Internal.Types.Channel: MessageTypeThreadCreated :: MessageType
+ Discord.Internal.Types.Channel: MessageTypeThreadStarterMessage :: MessageType
+ Discord.Internal.Types.Channel: MessageTypeUserPremiumGuildSubscription :: MessageType
+ Discord.Internal.Types.Channel: MessageTypeUserPremiumGuildSubscriptionTier1 :: MessageType
+ Discord.Internal.Types.Channel: MessageTypeUserPremiumGuildSubscriptionTier2 :: MessageType
+ Discord.Internal.Types.Channel: MessageTypeUserPremiumGuildSubscriptionTier3 :: MessageType
+ Discord.Internal.Types.Channel: StickerFormatTypeAPNG :: StickerFormatType
+ Discord.Internal.Types.Channel: StickerFormatTypeLOTTIE :: StickerFormatType
+ Discord.Internal.Types.Channel: StickerFormatTypePNG :: StickerFormatType
+ Discord.Internal.Types.Channel: StickerItem :: StickerId -> Text -> StickerFormatType -> StickerItem
+ Discord.Internal.Types.Channel: [mentionEveryone] :: AllowedMentions -> Bool
+ Discord.Internal.Types.Channel: [mentionRepliedUser] :: AllowedMentions -> Bool
+ Discord.Internal.Types.Channel: [mentionRoleIds] :: AllowedMentions -> [RoleId]
+ Discord.Internal.Types.Channel: [mentionRoles] :: AllowedMentions -> Bool
+ Discord.Internal.Types.Channel: [mentionUserIds] :: AllowedMentions -> [UserId]
+ Discord.Internal.Types.Channel: [mentionUsers] :: AllowedMentions -> Bool
+ Discord.Internal.Types.Channel: [messageActivityPartyId] :: MessageActivity -> Maybe Text
+ Discord.Internal.Types.Channel: [messageActivityType] :: MessageActivity -> MessageActivityType
+ Discord.Internal.Types.Channel: [messageActivity] :: Message -> Maybe MessageActivity
+ Discord.Internal.Types.Channel: [messageApplicationId] :: Message -> Maybe ApplicationId
+ Discord.Internal.Types.Channel: [messageChannelId] :: Message -> ChannelId
+ Discord.Internal.Types.Channel: [messageComponents] :: Message -> Maybe [Component]
+ Discord.Internal.Types.Channel: [messageContent] :: Message -> Text
+ Discord.Internal.Types.Channel: [messageFlags] :: Message -> Maybe MessageFlags
+ Discord.Internal.Types.Channel: [messageGuildId] :: Message -> Maybe GuildId
+ Discord.Internal.Types.Channel: [messageInteractionId] :: MessageInteraction -> InteractionId
+ Discord.Internal.Types.Channel: [messageInteractionName] :: MessageInteraction -> Text
+ Discord.Internal.Types.Channel: [messageInteractionType] :: MessageInteraction -> InteractionType
+ Discord.Internal.Types.Channel: [messageInteractionUser] :: MessageInteraction -> User
+ Discord.Internal.Types.Channel: [messageInteraction] :: Message -> Maybe MessageInteraction
+ Discord.Internal.Types.Channel: [messageMember] :: Message -> Maybe GuildMember
+ Discord.Internal.Types.Channel: [messageReferencedMessage] :: Message -> Maybe Message
+ Discord.Internal.Types.Channel: [messageStickerItems] :: Message -> Maybe [StickerItem]
+ Discord.Internal.Types.Channel: [messageThread] :: Message -> Maybe Channel
+ Discord.Internal.Types.Channel: [messageType] :: Message -> MessageType
+ Discord.Internal.Types.Channel: [messageWebhookId] :: Message -> Maybe WebhookId
+ Discord.Internal.Types.Channel: [stickerItemFormatType] :: StickerItem -> StickerFormatType
+ Discord.Internal.Types.Channel: [stickerItemId] :: StickerItem -> StickerId
+ Discord.Internal.Types.Channel: [stickerItemName] :: StickerItem -> Text
+ Discord.Internal.Types.Channel: data AllowedMentions
+ Discord.Internal.Types.Channel: data MessageActivity
+ Discord.Internal.Types.Channel: data MessageActivityType
+ Discord.Internal.Types.Channel: data MessageFlag
+ Discord.Internal.Types.Channel: data MessageInteraction
+ Discord.Internal.Types.Channel: data MessageType
+ Discord.Internal.Types.Channel: data StickerFormatType
+ Discord.Internal.Types.Channel: data StickerItem
+ Discord.Internal.Types.Channel: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Channel.MessageActivity
+ Discord.Internal.Types.Channel: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Channel.MessageActivityType
+ Discord.Internal.Types.Channel: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Channel.MessageFlags
+ Discord.Internal.Types.Channel: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Channel.MessageInteraction
+ Discord.Internal.Types.Channel: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Channel.MessageType
+ Discord.Internal.Types.Channel: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Channel.StickerFormatType
+ Discord.Internal.Types.Channel: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Channel.StickerItem
+ Discord.Internal.Types.Channel: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Channel.AllowedMentions
+ Discord.Internal.Types.Channel: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Channel.Attachment
+ Discord.Internal.Types.Channel: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Channel.Channel
+ Discord.Internal.Types.Channel: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Channel.Message
+ Discord.Internal.Types.Channel: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Channel.MessageActivity
+ Discord.Internal.Types.Channel: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Channel.MessageActivityType
+ Discord.Internal.Types.Channel: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Channel.MessageFlags
+ Discord.Internal.Types.Channel: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Channel.MessageInteraction
+ Discord.Internal.Types.Channel: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Channel.MessageReaction
+ Discord.Internal.Types.Channel: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Channel.MessageType
+ Discord.Internal.Types.Channel: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Channel.Nonce
+ Discord.Internal.Types.Channel: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Channel.StickerFormatType
+ Discord.Internal.Types.Channel: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Channel.StickerItem
+ Discord.Internal.Types.Channel: instance Data.Data.Data Discord.Internal.Types.Channel.MessageActivity
+ Discord.Internal.Types.Channel: instance Data.Data.Data Discord.Internal.Types.Channel.MessageActivityType
+ Discord.Internal.Types.Channel: instance Data.Data.Data Discord.Internal.Types.Channel.MessageFlag
+ Discord.Internal.Types.Channel: instance Data.Data.Data Discord.Internal.Types.Channel.MessageType
+ Discord.Internal.Types.Channel: instance Data.Data.Data Discord.Internal.Types.Channel.StickerFormatType
+ Discord.Internal.Types.Channel: instance Data.Default.Class.Default Discord.Internal.Types.Channel.AllowedMentions
+ Discord.Internal.Types.Channel: instance GHC.Classes.Eq Discord.Internal.Types.Channel.AllowedMentions
+ Discord.Internal.Types.Channel: instance GHC.Classes.Eq Discord.Internal.Types.Channel.MessageActivity
+ Discord.Internal.Types.Channel: instance GHC.Classes.Eq Discord.Internal.Types.Channel.MessageActivityType
+ Discord.Internal.Types.Channel: instance GHC.Classes.Eq Discord.Internal.Types.Channel.MessageFlag
+ Discord.Internal.Types.Channel: instance GHC.Classes.Eq Discord.Internal.Types.Channel.MessageFlags
+ Discord.Internal.Types.Channel: instance GHC.Classes.Eq Discord.Internal.Types.Channel.MessageInteraction
+ Discord.Internal.Types.Channel: instance GHC.Classes.Eq Discord.Internal.Types.Channel.MessageType
+ Discord.Internal.Types.Channel: instance GHC.Classes.Eq Discord.Internal.Types.Channel.StickerFormatType
+ Discord.Internal.Types.Channel: instance GHC.Classes.Eq Discord.Internal.Types.Channel.StickerItem
+ Discord.Internal.Types.Channel: instance GHC.Classes.Ord Discord.Internal.Types.Channel.AllowedMentions
+ Discord.Internal.Types.Channel: instance GHC.Classes.Ord Discord.Internal.Types.Channel.MessageActivity
+ Discord.Internal.Types.Channel: instance GHC.Classes.Ord Discord.Internal.Types.Channel.MessageActivityType
+ Discord.Internal.Types.Channel: instance GHC.Classes.Ord Discord.Internal.Types.Channel.MessageFlag
+ Discord.Internal.Types.Channel: instance GHC.Classes.Ord Discord.Internal.Types.Channel.MessageFlags
+ Discord.Internal.Types.Channel: instance GHC.Classes.Ord Discord.Internal.Types.Channel.MessageInteraction
+ Discord.Internal.Types.Channel: instance GHC.Classes.Ord Discord.Internal.Types.Channel.MessageType
+ Discord.Internal.Types.Channel: instance GHC.Classes.Ord Discord.Internal.Types.Channel.StickerFormatType
+ Discord.Internal.Types.Channel: instance GHC.Classes.Ord Discord.Internal.Types.Channel.StickerItem
+ 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.Channel: instance GHC.Read.Read Discord.Internal.Types.Channel.AllowedMentions
+ Discord.Internal.Types.Channel: instance GHC.Read.Read Discord.Internal.Types.Channel.MessageActivity
+ Discord.Internal.Types.Channel: instance GHC.Read.Read Discord.Internal.Types.Channel.MessageActivityType
+ Discord.Internal.Types.Channel: instance GHC.Read.Read Discord.Internal.Types.Channel.MessageFlag
+ Discord.Internal.Types.Channel: instance GHC.Read.Read Discord.Internal.Types.Channel.MessageFlags
+ Discord.Internal.Types.Channel: instance GHC.Read.Read Discord.Internal.Types.Channel.MessageInteraction
+ Discord.Internal.Types.Channel: instance GHC.Read.Read Discord.Internal.Types.Channel.MessageType
+ Discord.Internal.Types.Channel: instance GHC.Read.Read Discord.Internal.Types.Channel.StickerFormatType
+ Discord.Internal.Types.Channel: instance GHC.Read.Read Discord.Internal.Types.Channel.StickerItem
+ Discord.Internal.Types.Channel: instance GHC.Show.Show Discord.Internal.Types.Channel.AllowedMentions
+ Discord.Internal.Types.Channel: instance GHC.Show.Show Discord.Internal.Types.Channel.MessageActivity
+ Discord.Internal.Types.Channel: instance GHC.Show.Show Discord.Internal.Types.Channel.MessageActivityType
+ Discord.Internal.Types.Channel: instance GHC.Show.Show Discord.Internal.Types.Channel.MessageFlag
+ Discord.Internal.Types.Channel: instance GHC.Show.Show Discord.Internal.Types.Channel.MessageFlags
+ Discord.Internal.Types.Channel: instance GHC.Show.Show Discord.Internal.Types.Channel.MessageInteraction
+ Discord.Internal.Types.Channel: instance GHC.Show.Show Discord.Internal.Types.Channel.MessageType
+ Discord.Internal.Types.Channel: instance GHC.Show.Show Discord.Internal.Types.Channel.StickerFormatType
+ Discord.Internal.Types.Channel: instance GHC.Show.Show Discord.Internal.Types.Channel.StickerItem
+ Discord.Internal.Types.Channel: newtype MessageFlags
+ Discord.Internal.Types.Components: ButtonStyleDanger :: ButtonStyle
+ Discord.Internal.Types.Components: ButtonStylePrimary :: ButtonStyle
+ Discord.Internal.Types.Components: ButtonStyleSecondary :: ButtonStyle
+ Discord.Internal.Types.Components: ButtonStyleSuccess :: ButtonStyle
+ 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: ComponentActionRowButton :: [ComponentButton] -> ComponentActionRow
+ Discord.Internal.Types.Components: ComponentActionRowSelectMenu :: ComponentSelectMenu -> ComponentActionRow
+ Discord.Internal.Types.Components: ComponentButton :: Text -> Bool -> ButtonStyle -> Text -> Maybe Emoji -> ComponentButton
+ Discord.Internal.Types.Components: ComponentButtonUrl :: Url 'Https -> Bool -> Text -> Maybe Emoji -> ComponentButton
+ Discord.Internal.Types.Components: ComponentSelectMenu :: Text -> Bool -> [SelectOption] -> Maybe Text -> Maybe Integer -> Maybe Integer -> ComponentSelectMenu
+ Discord.Internal.Types.Components: ComponentTypeActionRow :: ComponentType
+ Discord.Internal.Types.Components: ComponentTypeButton :: ComponentType
+ Discord.Internal.Types.Components: ComponentTypeSelectMenu :: ComponentType
+ Discord.Internal.Types.Components: Emoji :: Maybe EmojiId -> Text -> Maybe [RoleId] -> Maybe User -> Maybe Bool -> Maybe Bool -> Emoji
+ 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: SelectOption :: Text -> Text -> Maybe Text -> Maybe Emoji -> Maybe Bool -> SelectOption
+ Discord.Internal.Types.Components: [componentButtonCustomId] :: ComponentButton -> Text
+ Discord.Internal.Types.Components: [componentButtonDisabled] :: ComponentButton -> Bool
+ Discord.Internal.Types.Components: [componentButtonEmoji] :: ComponentButton -> Maybe Emoji
+ Discord.Internal.Types.Components: [componentButtonLabel] :: ComponentButton -> Text
+ Discord.Internal.Types.Components: [componentButtonStyle] :: ComponentButton -> ButtonStyle
+ Discord.Internal.Types.Components: [componentButtonUrl] :: ComponentButton -> Url 'Https
+ 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: [componentSelectMenuCustomId] :: ComponentSelectMenu -> Text
+ Discord.Internal.Types.Components: [componentSelectMenuDisabled] :: ComponentSelectMenu -> Bool
+ Discord.Internal.Types.Components: [componentSelectMenuMaxValues] :: ComponentSelectMenu -> Maybe Integer
+ Discord.Internal.Types.Components: [componentSelectMenuMinValues] :: ComponentSelectMenu -> Maybe Integer
+ Discord.Internal.Types.Components: [componentSelectMenuOptions] :: ComponentSelectMenu -> [SelectOption]
+ Discord.Internal.Types.Components: [componentSelectMenuPlaceholder] :: ComponentSelectMenu -> 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: [emojiAnimated] :: Emoji -> Maybe Bool
+ Discord.Internal.Types.Components: [emojiId] :: Emoji -> Maybe EmojiId
+ Discord.Internal.Types.Components: [emojiManaged] :: Emoji -> Maybe Bool
+ Discord.Internal.Types.Components: [emojiName] :: Emoji -> Text
+ Discord.Internal.Types.Components: [emojiRoles] :: Emoji -> Maybe [RoleId]
+ Discord.Internal.Types.Components: [emojiUser] :: Emoji -> Maybe User
+ Discord.Internal.Types.Components: [selectOptionDefault] :: SelectOption -> Maybe Bool
+ Discord.Internal.Types.Components: [selectOptionDescription] :: SelectOption -> Maybe Text
+ Discord.Internal.Types.Components: [selectOptionEmoji] :: SelectOption -> Maybe Emoji
+ Discord.Internal.Types.Components: [selectOptionLabel] :: SelectOption -> Text
+ Discord.Internal.Types.Components: [selectOptionValue] :: SelectOption -> Text
+ Discord.Internal.Types.Components: buttonStyles :: [(ButtonStyle, InternalButtonStyle)]
+ Discord.Internal.Types.Components: data ButtonStyle
+ Discord.Internal.Types.Components: data Component
+ Discord.Internal.Types.Components: data ComponentActionRow
+ Discord.Internal.Types.Components: data ComponentButton
+ Discord.Internal.Types.Components: data ComponentSelectMenu
+ Discord.Internal.Types.Components: data ComponentType
+ Discord.Internal.Types.Components: data Emoji
+ Discord.Internal.Types.Components: data InternalButtonStyle
+ Discord.Internal.Types.Components: data SelectOption
+ 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.Emoji
+ Discord.Internal.Types.Components: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Components.InternalButtonStyle
+ Discord.Internal.Types.Components: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Components.SelectOption
+ 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.Emoji
+ Discord.Internal.Types.Components: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Components.InternalButtonStyle
+ Discord.Internal.Types.Components: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Components.SelectOption
+ 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.ButtonStyle
+ 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.ComponentActionRow
+ Discord.Internal.Types.Components: instance GHC.Classes.Eq Discord.Internal.Types.Components.ComponentButton
+ Discord.Internal.Types.Components: instance GHC.Classes.Eq Discord.Internal.Types.Components.ComponentSelectMenu
+ 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.Emoji
+ Discord.Internal.Types.Components: instance GHC.Classes.Eq Discord.Internal.Types.Components.InternalButtonStyle
+ Discord.Internal.Types.Components: instance GHC.Classes.Eq Discord.Internal.Types.Components.SelectOption
+ 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.Emoji
+ Discord.Internal.Types.Components: instance GHC.Classes.Ord Discord.Internal.Types.Components.InternalButtonStyle
+ Discord.Internal.Types.Components: instance GHC.Classes.Ord Discord.Internal.Types.Components.SelectOption
+ 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.ButtonStyle
+ 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.ComponentSelectMenu
+ 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.Emoji
+ Discord.Internal.Types.Components: instance GHC.Read.Read Discord.Internal.Types.Components.InternalButtonStyle
+ Discord.Internal.Types.Components: instance GHC.Read.Read Discord.Internal.Types.Components.SelectOption
+ Discord.Internal.Types.Components: instance GHC.Show.Show Discord.Internal.Types.Components.ButtonStyle
+ 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.ComponentActionRow
+ Discord.Internal.Types.Components: instance GHC.Show.Show Discord.Internal.Types.Components.ComponentButton
+ Discord.Internal.Types.Components: instance GHC.Show.Show Discord.Internal.Types.Components.ComponentSelectMenu
+ 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.Emoji
+ Discord.Internal.Types.Components: instance GHC.Show.Show Discord.Internal.Types.Components.InternalButtonStyle
+ Discord.Internal.Types.Components: instance GHC.Show.Show Discord.Internal.Types.Components.SelectOption
+ Discord.Internal.Types.Components: validPartialEmoji :: Emoji -> Maybe Emoji
+ Discord.Internal.Types.Events: InteractionCreate :: Interaction -> Event
+ Discord.Internal.Types.Events: InternalInteractionCreate :: InternalInteraction -> EventInternalParse
+ Discord.Internal.Types.Events: PartialApplication :: ApplicationId -> Int -> PartialApplication
+ Discord.Internal.Types.Events: [partialApplicationFlags] :: PartialApplication -> Int
+ Discord.Internal.Types.Events: [partialApplicationID] :: PartialApplication -> ApplicationId
+ Discord.Internal.Types.Events: data PartialApplication
+ Discord.Internal.Types.Events: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Events.PartialApplication
+ Discord.Internal.Types.Events: instance GHC.Classes.Eq Discord.Internal.Types.Events.PartialApplication
+ Discord.Internal.Types.Events: instance GHC.Read.Read Discord.Internal.Types.Events.PartialApplication
+ Discord.Internal.Types.Events: instance GHC.Show.Show Discord.Internal.Types.Events.PartialApplication
+ Discord.Internal.Types.Guild: GuildWidget :: Bool -> ChannelId -> GuildWidget
+ Discord.Internal.Types.Guild: [guildWidgetChannelId] :: Guild -> Maybe ChannelId
+ Discord.Internal.Types.Guild: [guildWidgetEnabled] :: Guild -> Maybe Bool
+ Discord.Internal.Types.Guild: [widgetChannelId] :: GuildWidget -> ChannelId
+ Discord.Internal.Types.Guild: [widgetEnabled] :: GuildWidget -> Bool
+ Discord.Internal.Types.Guild: data GuildWidget
+ Discord.Internal.Types.Guild: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.Guild.GuildWidget
+ Discord.Internal.Types.Guild: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Guild.GuildWidget
+ Discord.Internal.Types.Guild: instance GHC.Classes.Eq Discord.Internal.Types.Guild.GuildWidget
+ Discord.Internal.Types.Guild: instance GHC.Classes.Ord Discord.Internal.Types.Guild.GuildWidget
+ Discord.Internal.Types.Guild: instance GHC.Read.Read Discord.Internal.Types.Guild.GuildWidget
+ Discord.Internal.Types.Guild: instance GHC.Show.Show Discord.Internal.Types.Guild.GuildWidget
+ 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: InteractionApplicationCommand :: InteractionId -> ApplicationId -> Maybe InteractionDataApplicationCommand -> Maybe GuildId -> Maybe ChannelId -> Maybe GuildMember -> Maybe User -> InteractionToken -> Int -> 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: 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: InteractionComponent :: InteractionId -> ApplicationId -> Maybe InteractionDataComponent -> Maybe GuildId -> Maybe ChannelId -> Maybe GuildMember -> Maybe User -> InteractionToken -> Int -> Message -> Interaction
+ Discord.Internal.Types.Interactions: InteractionDataApplicationCommandChatInput :: ApplicationCommandId -> Text -> Maybe ResolvedData -> Maybe InteractionDataApplicationCommandOptions -> InteractionDataApplicationCommand
+ Discord.Internal.Types.Interactions: InteractionDataApplicationCommandMessage :: ApplicationCommandId -> Text -> Maybe ResolvedData -> MessageId -> InteractionDataApplicationCommand
+ Discord.Internal.Types.Interactions: InteractionDataApplicationCommandOptionSubcommand :: Text -> [InteractionDataApplicationCommandOptionValue] -> Maybe Bool -> InteractionDataApplicationCommandOptionSubcommand
+ Discord.Internal.Types.Interactions: InteractionDataApplicationCommandOptionSubcommandGroup :: Text -> [InteractionDataApplicationCommandOptionSubcommand] -> Maybe Bool -> InteractionDataApplicationCommandOptionSubcommandOrGroup
+ Discord.Internal.Types.Interactions: InteractionDataApplicationCommandOptionSubcommandOrGroupSubcommand :: InteractionDataApplicationCommandOptionSubcommand -> InteractionDataApplicationCommandOptionSubcommandOrGroup
+ Discord.Internal.Types.Interactions: InteractionDataApplicationCommandOptionValue :: Text -> ApplicationCommandInteractionDataValue -> Maybe Bool -> InteractionDataApplicationCommandOptionValue
+ Discord.Internal.Types.Interactions: InteractionDataApplicationCommandOptionsSubcommands :: [InteractionDataApplicationCommandOptionSubcommandOrGroup] -> InteractionDataApplicationCommandOptions
+ Discord.Internal.Types.Interactions: InteractionDataApplicationCommandOptionsValues :: [InteractionDataApplicationCommandOptionValue] -> InteractionDataApplicationCommandOptions
+ Discord.Internal.Types.Interactions: InteractionDataApplicationCommandUser :: ApplicationCommandId -> Text -> Maybe ResolvedData -> UserId -> InteractionDataApplicationCommand
+ Discord.Internal.Types.Interactions: InteractionDataComponentButton :: Text -> InteractionDataComponent
+ Discord.Internal.Types.Interactions: InteractionDataComponentSelectMenu :: Text -> [Text] -> InteractionDataComponent
+ Discord.Internal.Types.Interactions: InteractionPing :: InteractionId -> ApplicationId -> InteractionToken -> Int -> Interaction
+ 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: ResolvedData :: Maybe Value -> Maybe Value -> Maybe Value -> Maybe Value -> ResolvedData
+ Discord.Internal.Types.Interactions: [interactionApplicationId] :: Interaction -> ApplicationId
+ 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: [interactionChannelId] :: Interaction -> Maybe ChannelId
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommandId] :: InteractionDataApplicationCommand -> ApplicationCommandId
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommandName] :: InteractionDataApplicationCommand -> Text
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommandOptionSubcommandFocused] :: InteractionDataApplicationCommandOptionSubcommand -> Maybe Bool
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommandOptionSubcommandGroupFocused] :: InteractionDataApplicationCommandOptionSubcommandOrGroup -> Maybe Bool
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommandOptionSubcommandGroupName] :: InteractionDataApplicationCommandOptionSubcommandOrGroup -> Text
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommandOptionSubcommandGroupOptions] :: InteractionDataApplicationCommandOptionSubcommandOrGroup -> [InteractionDataApplicationCommandOptionSubcommand]
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommandOptionSubcommandName] :: InteractionDataApplicationCommandOptionSubcommand -> Text
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommandOptionSubcommandOptions] :: InteractionDataApplicationCommandOptionSubcommand -> [InteractionDataApplicationCommandOptionValue]
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommandOptionValueFocused] :: InteractionDataApplicationCommandOptionValue -> Maybe Bool
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommandOptionValueName] :: InteractionDataApplicationCommandOptionValue -> Text
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommandOptionValueValue] :: InteractionDataApplicationCommandOptionValue -> ApplicationCommandInteractionDataValue
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommandOptions] :: InteractionDataApplicationCommand -> Maybe InteractionDataApplicationCommandOptions
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommandResolvedData] :: InteractionDataApplicationCommand -> Maybe ResolvedData
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommandTargetId] :: InteractionDataApplicationCommand -> MessageId
+ Discord.Internal.Types.Interactions: [interactionDataApplicationCommand] :: Interaction -> Maybe InteractionDataApplicationCommand
+ Discord.Internal.Types.Interactions: [interactionDataComponentCustomId] :: InteractionDataComponent -> Text
+ Discord.Internal.Types.Interactions: [interactionDataComponentValues] :: InteractionDataComponent -> [Text]
+ Discord.Internal.Types.Interactions: [interactionDataComponent] :: Interaction -> Maybe InteractionDataComponent
+ Discord.Internal.Types.Interactions: [interactionGuildId] :: Interaction -> Maybe GuildId
+ Discord.Internal.Types.Interactions: [interactionId] :: Interaction -> InteractionId
+ Discord.Internal.Types.Interactions: [interactionMember] :: Interaction -> Maybe GuildMember
+ Discord.Internal.Types.Interactions: [interactionMessage] :: Interaction -> Message
+ Discord.Internal.Types.Interactions: [interactionResponseData] :: InteractionResponse -> Maybe InteractionCallbackData
+ Discord.Internal.Types.Interactions: [interactionResponseType] :: InteractionResponse -> InteractionCallbackType
+ Discord.Internal.Types.Interactions: [interactionToken] :: Interaction -> InteractionToken
+ Discord.Internal.Types.Interactions: [interactionUser] :: Interaction -> Maybe User
+ Discord.Internal.Types.Interactions: [interactionVersion] :: Interaction -> Int
+ 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: [resolvedDataChannels] :: ResolvedData -> Maybe Value
+ Discord.Internal.Types.Interactions: [resolvedDataMembers] :: ResolvedData -> Maybe Value
+ Discord.Internal.Types.Interactions: [resolvedDataRoles] :: ResolvedData -> Maybe Value
+ Discord.Internal.Types.Interactions: [resolvedDataUsers] :: ResolvedData -> Maybe Value
+ Discord.Internal.Types.Interactions: data ApplicationCommandInteractionDataValue
+ Discord.Internal.Types.Interactions: data Interaction
+ 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 InteractionDataApplicationCommand
+ Discord.Internal.Types.Interactions: data InteractionDataApplicationCommandOptionSubcommand
+ Discord.Internal.Types.Interactions: data InteractionDataApplicationCommandOptionSubcommandOrGroup
+ Discord.Internal.Types.Interactions: data InteractionDataApplicationCommandOptionValue
+ Discord.Internal.Types.Interactions: data InteractionDataApplicationCommandOptions
+ Discord.Internal.Types.Interactions: data InteractionDataComponent
+ Discord.Internal.Types.Interactions: data InteractionResponse
+ 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: data ResolvedData
+ 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.FromJSON.FromJSON Discord.Internal.Types.Interactions.ResolvedData
+ 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.InteractionResponse
+ 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.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Interactions.ResolvedData
+ 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.Interaction
+ 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.InteractionDataApplicationCommand
+ Discord.Internal.Types.Interactions: instance GHC.Classes.Eq Discord.Internal.Types.Interactions.InteractionDataApplicationCommandOptionSubcommand
+ Discord.Internal.Types.Interactions: instance GHC.Classes.Eq Discord.Internal.Types.Interactions.InteractionDataApplicationCommandOptionSubcommandOrGroup
+ Discord.Internal.Types.Interactions: instance GHC.Classes.Eq Discord.Internal.Types.Interactions.InteractionDataApplicationCommandOptionValue
+ Discord.Internal.Types.Interactions: instance GHC.Classes.Eq Discord.Internal.Types.Interactions.InteractionDataApplicationCommandOptions
+ Discord.Internal.Types.Interactions: instance GHC.Classes.Eq Discord.Internal.Types.Interactions.InteractionDataComponent
+ 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.Eq Discord.Internal.Types.Interactions.ResolvedData
+ 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.Interaction
+ 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.InteractionDataApplicationCommand
+ Discord.Internal.Types.Interactions: instance GHC.Read.Read Discord.Internal.Types.Interactions.InteractionDataApplicationCommandOptionSubcommand
+ Discord.Internal.Types.Interactions: instance GHC.Read.Read Discord.Internal.Types.Interactions.InteractionDataApplicationCommandOptionSubcommandOrGroup
+ Discord.Internal.Types.Interactions: instance GHC.Read.Read Discord.Internal.Types.Interactions.InteractionDataApplicationCommandOptionValue
+ Discord.Internal.Types.Interactions: instance GHC.Read.Read Discord.Internal.Types.Interactions.InteractionDataApplicationCommandOptions
+ Discord.Internal.Types.Interactions: instance GHC.Read.Read Discord.Internal.Types.Interactions.InteractionDataComponent
+ 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.Read.Read Discord.Internal.Types.Interactions.ResolvedData
+ 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.Interaction
+ 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.InteractionDataApplicationCommand
+ Discord.Internal.Types.Interactions: instance GHC.Show.Show Discord.Internal.Types.Interactions.InteractionDataApplicationCommandOptionSubcommand
+ Discord.Internal.Types.Interactions: instance GHC.Show.Show Discord.Internal.Types.Interactions.InteractionDataApplicationCommandOptionSubcommandOrGroup
+ Discord.Internal.Types.Interactions: instance GHC.Show.Show Discord.Internal.Types.Interactions.InteractionDataApplicationCommandOptionValue
+ Discord.Internal.Types.Interactions: instance GHC.Show.Show Discord.Internal.Types.Interactions.InteractionDataApplicationCommandOptions
+ Discord.Internal.Types.Interactions: instance GHC.Show.Show Discord.Internal.Types.Interactions.InteractionDataComponent
+ 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: instance GHC.Show.Show Discord.Internal.Types.Interactions.ResolvedData
+ Discord.Internal.Types.Interactions: interactionCallbackMessagesBasic :: Text -> InteractionCallbackMessages
+ Discord.Internal.Types.Interactions: interactionResponseBasic :: Text -> InteractionResponse
+ Discord.Internal.Types.Interactions: newtype InteractionCallbackDataFlags
+ Discord.Internal.Types.Interactions: type InteractionCallbackAutocomplete = [InternalApplicationCommandOptionChoice]
+ Discord.Internal.Types.Interactions: type InteractionToken = Text
+ 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 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: toMaybeJSON :: ToJSON a => a -> Maybe Value
+ Discord.Internal.Types.Prelude: type ApplicationCommandId = Snowflake
+ Discord.Internal.Types.Prelude: type ApplicationId = Snowflake
+ Discord.Internal.Types.Prelude: type AttachmentId = Snowflake
+ Discord.Internal.Types.Prelude: type InteractionId = Snowflake
+ Discord.Internal.Types.Prelude: type InteractionToken = Text
+ Discord.Internal.Types.Prelude: type Shard = (Int, Int)
+ Discord.Internal.Types.Prelude: type StickerId = Snowflake
+ Discord.Internal.Types.User: GuildMember :: Maybe User -> Maybe Text -> Maybe Text -> [RoleId] -> UTCTime -> Maybe UTCTime -> Bool -> Bool -> Bool -> Maybe Text -> GuildMember
+ Discord.Internal.Types.User: [memberAvatar] :: GuildMember -> Maybe Text
+ Discord.Internal.Types.User: [memberDeaf] :: GuildMember -> Bool
+ Discord.Internal.Types.User: [memberJoinedAt] :: GuildMember -> UTCTime
+ Discord.Internal.Types.User: [memberMute] :: GuildMember -> Bool
+ Discord.Internal.Types.User: [memberNick] :: GuildMember -> Maybe Text
+ Discord.Internal.Types.User: [memberPending] :: GuildMember -> Bool
+ Discord.Internal.Types.User: [memberPermissions] :: GuildMember -> Maybe Text
+ Discord.Internal.Types.User: [memberPremiumSince] :: GuildMember -> Maybe UTCTime
+ Discord.Internal.Types.User: [memberRoles] :: GuildMember -> [RoleId]
+ Discord.Internal.Types.User: [memberUser] :: GuildMember -> Maybe User
+ Discord.Internal.Types.User: [userAccentColor] :: User -> Maybe Int
+ Discord.Internal.Types.User: [userBanner] :: User -> Maybe Text
+ Discord.Internal.Types.User: [userFlags] :: User -> Maybe Integer
+ Discord.Internal.Types.User: [userIsSystem] :: User -> Maybe Bool
+ Discord.Internal.Types.User: [userLocale] :: User -> Maybe Text
+ Discord.Internal.Types.User: [userMember] :: User -> Maybe GuildMember
+ Discord.Internal.Types.User: [userPremiumType] :: User -> Maybe Integer
+ Discord.Internal.Types.User: [userPublicFlags] :: User -> Maybe Integer
+ Discord.Internal.Types.User: data GuildMember
+ Discord.Internal.Types.User: instance Data.Aeson.Types.FromJSON.FromJSON Discord.Internal.Types.User.GuildMember
+ Discord.Internal.Types.User: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.User.GuildMember
+ Discord.Internal.Types.User: instance GHC.Classes.Eq Discord.Internal.Types.User.GuildMember
+ Discord.Internal.Types.User: instance GHC.Classes.Ord Discord.Internal.Types.User.GuildMember
+ Discord.Internal.Types.User: instance GHC.Read.Read Discord.Internal.Types.User.GuildMember
+ Discord.Internal.Types.User: instance GHC.Show.Show Discord.Internal.Types.User.GuildMember
+ Discord.Types: AllowedMentions :: Bool -> Bool -> Bool -> [UserId] -> [RoleId] -> Bool -> AllowedMentions
+ Discord.Types: ButtonStyleDanger :: ButtonStyle
+ Discord.Types: ButtonStylePrimary :: ButtonStyle
+ Discord.Types: ButtonStyleSecondary :: ButtonStyle
+ Discord.Types: ButtonStyleSuccess :: ButtonStyle
+ 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: ComponentActionRowButton :: [ComponentButton] -> ComponentActionRow
+ Discord.Types: ComponentActionRowSelectMenu :: ComponentSelectMenu -> ComponentActionRow
+ Discord.Types: ComponentButton :: Text -> Bool -> ButtonStyle -> Text -> Maybe Emoji -> ComponentButton
+ Discord.Types: ComponentButtonUrl :: Url 'Https -> Bool -> Text -> Maybe Emoji -> ComponentButton
+ Discord.Types: ComponentSelectMenu :: Text -> Bool -> [SelectOption] -> Maybe Text -> Maybe Integer -> Maybe Integer -> ComponentSelectMenu
+ Discord.Types: ComponentTypeActionRow :: ComponentType
+ Discord.Types: ComponentTypeButton :: ComponentType
+ Discord.Types: ComponentTypeSelectMenu :: ComponentType
+ Discord.Types: GuildWidget :: Bool -> ChannelId -> GuildWidget
+ Discord.Types: InteractionCreate :: Interaction -> Event
+ 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: MessageActivity :: MessageActivityType -> Maybe Text -> MessageActivity
+ Discord.Types: MessageActivityTypeJoin :: MessageActivityType
+ Discord.Types: MessageActivityTypeJoinRequest :: MessageActivityType
+ Discord.Types: MessageActivityTypeListen :: MessageActivityType
+ Discord.Types: MessageActivityTypeSpectate :: MessageActivityType
+ Discord.Types: MessageFlagCrossposted :: MessageFlag
+ Discord.Types: MessageFlagEphemeral :: MessageFlag
+ Discord.Types: MessageFlagHasThread :: MessageFlag
+ Discord.Types: MessageFlagIsCrosspost :: MessageFlag
+ Discord.Types: MessageFlagLoading :: MessageFlag
+ Discord.Types: MessageFlagSourceMessageDeleted :: MessageFlag
+ Discord.Types: MessageFlagSupressEmbeds :: MessageFlag
+ Discord.Types: MessageFlagUrgent :: MessageFlag
+ Discord.Types: MessageFlags :: [MessageFlag] -> MessageFlags
+ Discord.Types: MessageInteraction :: InteractionId -> InteractionType -> Text -> User -> MessageInteraction
+ Discord.Types: MessageTypeCall :: MessageType
+ Discord.Types: MessageTypeChannelFollowAdd :: MessageType
+ Discord.Types: MessageTypeChannelIconChange :: MessageType
+ Discord.Types: MessageTypeChannelNameChange :: MessageType
+ Discord.Types: MessageTypeChannelPinnedMessage :: MessageType
+ Discord.Types: MessageTypeChatInputCommand :: MessageType
+ Discord.Types: MessageTypeContextMenuCommand :: MessageType
+ Discord.Types: MessageTypeDefault :: MessageType
+ Discord.Types: MessageTypeGuildDiscoveryDisqualified :: MessageType
+ Discord.Types: MessageTypeGuildDiscoveryGracePeriodFinalWarning :: MessageType
+ Discord.Types: MessageTypeGuildDiscoveryGracePeriodInitialWarning :: MessageType
+ Discord.Types: MessageTypeGuildDiscoveryRequalified :: MessageType
+ Discord.Types: MessageTypeGuildInviteReminder :: MessageType
+ Discord.Types: MessageTypeGuildMemberJoin :: MessageType
+ Discord.Types: MessageTypeRecipientAdd :: MessageType
+ Discord.Types: MessageTypeRecipientRemove :: MessageType
+ Discord.Types: MessageTypeReply :: MessageType
+ Discord.Types: MessageTypeThreadCreated :: MessageType
+ Discord.Types: MessageTypeThreadStarterMessage :: MessageType
+ Discord.Types: MessageTypeUserPremiumGuildSubscription :: MessageType
+ Discord.Types: MessageTypeUserPremiumGuildSubscriptionTier1 :: MessageType
+ Discord.Types: MessageTypeUserPremiumGuildSubscriptionTier2 :: MessageType
+ Discord.Types: MessageTypeUserPremiumGuildSubscriptionTier3 :: MessageType
+ Discord.Types: PartialApplication :: ApplicationId -> Int -> PartialApplication
+ Discord.Types: SelectOption :: Text -> Text -> Maybe Text -> Maybe Emoji -> Maybe Bool -> SelectOption
+ Discord.Types: StickerFormatTypeAPNG :: StickerFormatType
+ Discord.Types: StickerFormatTypeLOTTIE :: StickerFormatType
+ Discord.Types: StickerFormatTypePNG :: StickerFormatType
+ Discord.Types: StickerItem :: StickerId -> Text -> StickerFormatType -> StickerItem
+ Discord.Types: [componentButtonCustomId] :: ComponentButton -> Text
+ Discord.Types: [componentButtonDisabled] :: ComponentButton -> Bool
+ Discord.Types: [componentButtonEmoji] :: ComponentButton -> Maybe Emoji
+ Discord.Types: [componentButtonLabel] :: ComponentButton -> Text
+ Discord.Types: [componentButtonStyle] :: ComponentButton -> ButtonStyle
+ Discord.Types: [componentButtonUrl] :: ComponentButton -> Url 'Https
+ 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: [componentSelectMenuCustomId] :: ComponentSelectMenu -> Text
+ Discord.Types: [componentSelectMenuDisabled] :: ComponentSelectMenu -> Bool
+ Discord.Types: [componentSelectMenuMaxValues] :: ComponentSelectMenu -> Maybe Integer
+ Discord.Types: [componentSelectMenuMinValues] :: ComponentSelectMenu -> Maybe Integer
+ Discord.Types: [componentSelectMenuOptions] :: ComponentSelectMenu -> [SelectOption]
+ Discord.Types: [componentSelectMenuPlaceholder] :: ComponentSelectMenu -> Maybe Text
+ Discord.Types: [componentStyle] :: Component -> Maybe InternalButtonStyle
+ Discord.Types: [componentType] :: Component -> ComponentType
+ Discord.Types: [componentUrl] :: Component -> Maybe Text
+ Discord.Types: [guildWidgetChannelId] :: Guild -> Maybe ChannelId
+ Discord.Types: [guildWidgetEnabled] :: Guild -> Maybe Bool
+ Discord.Types: [memberAvatar] :: GuildMember -> Maybe Text
+ Discord.Types: [memberPending] :: GuildMember -> Bool
+ Discord.Types: [memberPermissions] :: GuildMember -> Maybe Text
+ Discord.Types: [memberPremiumSince] :: GuildMember -> Maybe UTCTime
+ Discord.Types: [mentionEveryone] :: AllowedMentions -> Bool
+ Discord.Types: [mentionRepliedUser] :: AllowedMentions -> Bool
+ Discord.Types: [mentionRoleIds] :: AllowedMentions -> [RoleId]
+ Discord.Types: [mentionRoles] :: AllowedMentions -> Bool
+ Discord.Types: [mentionUserIds] :: AllowedMentions -> [UserId]
+ Discord.Types: [mentionUsers] :: AllowedMentions -> Bool
+ Discord.Types: [messageActivityPartyId] :: MessageActivity -> Maybe Text
+ Discord.Types: [messageActivityType] :: MessageActivity -> MessageActivityType
+ Discord.Types: [messageActivity] :: Message -> Maybe MessageActivity
+ Discord.Types: [messageApplicationId] :: Message -> Maybe ApplicationId
+ Discord.Types: [messageChannelId] :: Message -> ChannelId
+ Discord.Types: [messageComponents] :: Message -> Maybe [Component]
+ Discord.Types: [messageContent] :: Message -> Text
+ Discord.Types: [messageFlags] :: Message -> Maybe MessageFlags
+ Discord.Types: [messageGuildId] :: Message -> Maybe GuildId
+ Discord.Types: [messageInteractionId] :: MessageInteraction -> InteractionId
+ Discord.Types: [messageInteractionName] :: MessageInteraction -> Text
+ Discord.Types: [messageInteractionType] :: MessageInteraction -> InteractionType
+ Discord.Types: [messageInteractionUser] :: MessageInteraction -> User
+ Discord.Types: [messageInteraction] :: Message -> Maybe MessageInteraction
+ Discord.Types: [messageMember] :: Message -> Maybe GuildMember
+ Discord.Types: [messageReferencedMessage] :: Message -> Maybe Message
+ Discord.Types: [messageStickerItems] :: Message -> Maybe [StickerItem]
+ Discord.Types: [messageThread] :: Message -> Maybe Channel
+ Discord.Types: [messageType] :: Message -> MessageType
+ Discord.Types: [messageWebhookId] :: Message -> Maybe WebhookId
+ Discord.Types: [partialApplicationFlags] :: PartialApplication -> Int
+ Discord.Types: [partialApplicationID] :: PartialApplication -> ApplicationId
+ Discord.Types: [selectOptionDefault] :: SelectOption -> Maybe Bool
+ Discord.Types: [selectOptionDescription] :: SelectOption -> Maybe Text
+ Discord.Types: [selectOptionEmoji] :: SelectOption -> Maybe Emoji
+ Discord.Types: [selectOptionLabel] :: SelectOption -> Text
+ Discord.Types: [selectOptionValue] :: SelectOption -> Text
+ Discord.Types: [stickerItemFormatType] :: StickerItem -> StickerFormatType
+ Discord.Types: [stickerItemId] :: StickerItem -> StickerId
+ Discord.Types: [stickerItemName] :: StickerItem -> Text
+ Discord.Types: [userAccentColor] :: User -> Maybe Int
+ Discord.Types: [userBanner] :: User -> Maybe Text
+ Discord.Types: [userFlags] :: User -> Maybe Integer
+ Discord.Types: [userIsSystem] :: User -> Maybe Bool
+ Discord.Types: [userLocale] :: User -> Maybe Text
+ Discord.Types: [userMember] :: User -> Maybe GuildMember
+ Discord.Types: [userPremiumType] :: User -> Maybe Integer
+ Discord.Types: [userPublicFlags] :: User -> Maybe Integer
+ Discord.Types: [widgetChannelId] :: GuildWidget -> ChannelId
+ Discord.Types: [widgetEnabled] :: GuildWidget -> Bool
+ Discord.Types: buttonStyles :: [(ButtonStyle, InternalButtonStyle)]
+ Discord.Types: class Internals a b
+ Discord.Types: data AllowedMentions
+ Discord.Types: data ButtonStyle
+ Discord.Types: data Component
+ Discord.Types: data ComponentActionRow
+ Discord.Types: data ComponentButton
+ Discord.Types: data ComponentSelectMenu
+ Discord.Types: data ComponentType
+ Discord.Types: data GuildWidget
+ Discord.Types: data InteractionType
+ Discord.Types: data InternalButtonStyle
+ Discord.Types: data MessageActivity
+ Discord.Types: data MessageActivityType
+ Discord.Types: data MessageFlag
+ Discord.Types: data MessageInteraction
+ Discord.Types: data MessageType
+ Discord.Types: data PartialApplication
+ Discord.Types: data SelectOption
+ Discord.Types: data StickerFormatType
+ Discord.Types: data StickerItem
+ 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: newtype MessageFlags
+ Discord.Types: toInternal :: Internals a b => a -> b
+ Discord.Types: toMaybeJSON :: ToJSON a => a -> Maybe Value
+ Discord.Types: type ApplicationCommandId = Snowflake
+ Discord.Types: type ApplicationId = Snowflake
+ Discord.Types: type AttachmentId = Snowflake
+ Discord.Types: type InteractionId = Snowflake
+ Discord.Types: type InteractionToken = Text
+ Discord.Types: type Shard = (Int, Int)
+ Discord.Types: type StickerId = Snowflake
+ Discord.Types: validPartialEmoji :: Emoji -> Maybe Emoji
- Discord: Cache :: User -> Map ChannelId Channel -> Map GuildId (Guild, GuildInfo) -> Map ChannelId Channel -> Cache
+ Discord: Cache :: User -> Map ChannelId Channel -> Map GuildId (Guild, GuildInfo) -> Map ChannelId Channel -> PartialApplication -> Cache
- Discord.Internal.Gateway: Cache :: User -> Map ChannelId Channel -> Map GuildId (Guild, GuildInfo) -> Map ChannelId Channel -> Cache
+ Discord.Internal.Gateway: Cache :: User -> Map ChannelId Channel -> Map GuildId (Guild, GuildInfo) -> Map ChannelId Channel -> PartialApplication -> Cache
- Discord.Internal.Gateway.Cache: Cache :: User -> Map ChannelId Channel -> Map GuildId (Guild, GuildInfo) -> Map ChannelId Channel -> Cache
+ Discord.Internal.Gateway.Cache: Cache :: User -> Map ChannelId Channel -> Map GuildId (Guild, GuildInfo) -> Map ChannelId Channel -> PartialApplication -> Cache
- Discord.Internal.Rest.Channel: MessageDetailedOpts :: Text -> Bool -> Maybe CreateEmbed -> Maybe (Text, ByteString) -> Maybe AllowedMentions -> Maybe MessageReference -> MessageDetailedOpts
+ Discord.Internal.Rest.Channel: MessageDetailedOpts :: Text -> Bool -> Maybe CreateEmbed -> Maybe (Text, ByteString) -> Maybe AllowedMentions -> Maybe MessageReference -> Maybe [Component] -> Maybe [StickerId] -> MessageDetailedOpts
- Discord.Internal.Rest.Guild: ModifyGuildRoleOpts :: Maybe Text -> Maybe Integer -> Maybe ColorInteger -> Maybe Bool -> Maybe Bool -> ModifyGuildRoleOpts
+ Discord.Internal.Rest.Guild: ModifyGuildRoleOpts :: Maybe Text -> Maybe Text -> Maybe ColorInteger -> Maybe Bool -> Maybe Bool -> ModifyGuildRoleOpts
- Discord.Internal.Rest.Guild: [modifyGuildRoleOptsPermissions] :: ModifyGuildRoleOpts -> Maybe Integer
+ Discord.Internal.Rest.Guild: [modifyGuildRoleOptsPermissions] :: ModifyGuildRoleOpts -> Maybe Text
- Discord.Internal.Types.Channel: Attachment :: Snowflake -> Text -> Integer -> Text -> Text -> Maybe Integer -> Maybe Integer -> Attachment
+ Discord.Internal.Types.Channel: Attachment :: AttachmentId -> Text -> Integer -> Text -> Text -> Maybe Integer -> Maybe Integer -> Attachment
- Discord.Internal.Types.Channel: Message :: MessageId -> ChannelId -> User -> Text -> UTCTime -> Maybe UTCTime -> Bool -> Bool -> [User] -> [RoleId] -> [Attachment] -> [Embed] -> [MessageReaction] -> Maybe Nonce -> Bool -> Maybe GuildId -> Maybe MessageReference -> Maybe Message -> 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 [Component] -> Maybe [StickerItem] -> Message
- Discord.Internal.Types.Channel: Overwrite :: OverwriteId -> Text -> Integer -> Integer -> Overwrite
+ Discord.Internal.Types.Channel: Overwrite :: OverwriteId -> Integer -> Text -> Text -> Overwrite
- Discord.Internal.Types.Channel: [attachmentId] :: Attachment -> Snowflake
+ Discord.Internal.Types.Channel: [attachmentId] :: Attachment -> AttachmentId
- Discord.Internal.Types.Channel: [overwriteAllow] :: Overwrite -> Integer
+ Discord.Internal.Types.Channel: [overwriteAllow] :: Overwrite -> Text
- Discord.Internal.Types.Channel: [overwriteDeny] :: Overwrite -> Integer
+ Discord.Internal.Types.Channel: [overwriteDeny] :: Overwrite -> Text
- Discord.Internal.Types.Channel: [overwriteType] :: Overwrite -> Text
+ Discord.Internal.Types.Channel: [overwriteType] :: Overwrite -> Integer
- Discord.Internal.Types.Events: InternalReady :: Int -> User -> [Channel] -> [GuildUnavailable] -> Text -> EventInternalParse
+ Discord.Internal.Types.Events: InternalReady :: Int -> User -> [Channel] -> [GuildUnavailable] -> Text -> Maybe Shard -> PartialApplication -> EventInternalParse
- Discord.Internal.Types.Events: Ready :: Int -> User -> [Channel] -> [GuildUnavailable] -> Text -> Event
+ Discord.Internal.Types.Events: Ready :: Int -> User -> [Channel] -> [GuildUnavailable] -> Text -> Maybe Shard -> PartialApplication -> Event
- Discord.Internal.Types.Guild: Guild :: GuildId -> Text -> Maybe Text -> Maybe Text -> UserId -> Maybe Integer -> Maybe Text -> Maybe ChannelId -> Integer -> Maybe Bool -> Maybe ChannelId -> Integer -> Integer -> Integer -> [Role] -> [Emoji] -> [Text] -> !Integer -> Maybe Snowflake -> Guild
+ Discord.Internal.Types.Guild: Guild :: GuildId -> Text -> Maybe Text -> Maybe Text -> UserId -> Maybe Text -> Maybe Text -> Maybe ChannelId -> Integer -> Maybe Bool -> Maybe ChannelId -> Integer -> Integer -> Integer -> [Role] -> [Emoji] -> [Text] -> !Integer -> Maybe Snowflake -> Guild
- Discord.Internal.Types.Guild: PartialGuild :: GuildId -> Text -> Maybe Text -> Bool -> Integer -> PartialGuild
+ Discord.Internal.Types.Guild: PartialGuild :: GuildId -> Text -> Maybe Text -> Bool -> Text -> PartialGuild
- Discord.Internal.Types.Guild: Role :: RoleId -> Text -> ColorInteger -> Bool -> Integer -> Integer -> Bool -> Bool -> Role
+ Discord.Internal.Types.Guild: Role :: RoleId -> Text -> ColorInteger -> Bool -> Integer -> Text -> Bool -> Bool -> Role
- Discord.Internal.Types.Guild: [guildPermissions] :: Guild -> Maybe Integer
+ Discord.Internal.Types.Guild: [guildPermissions] :: Guild -> Maybe Text
- Discord.Internal.Types.Guild: [partialGuildPermissions] :: PartialGuild -> Integer
+ Discord.Internal.Types.Guild: [partialGuildPermissions] :: PartialGuild -> Text
- Discord.Internal.Types.Guild: [rolePerms] :: Role -> Integer
+ Discord.Internal.Types.Guild: [rolePerms] :: Role -> Text
- Discord.Internal.Types.User: User :: UserId -> Text -> Text -> Maybe Text -> Bool -> Bool -> Maybe Bool -> Maybe Bool -> Maybe Text -> User
+ Discord.Internal.Types.User: User :: UserId -> Text -> Maybe Text -> Maybe Text -> Bool -> Bool -> Maybe Bool -> Maybe Bool -> Maybe Text -> Maybe Int -> Maybe Text -> Maybe Bool -> Maybe Text -> Maybe Integer -> Maybe Integer -> Maybe Integer -> Maybe GuildMember -> User
- Discord.Internal.Types.User: Webhook :: WebhookId -> Text -> ChannelId -> Webhook
+ Discord.Internal.Types.User: Webhook :: WebhookId -> Maybe Text -> ChannelId -> Webhook
- Discord.Internal.Types.User: [userDiscrim] :: User -> Text
+ Discord.Internal.Types.User: [userDiscrim] :: User -> Maybe Text
- Discord.Internal.Types.User: [webhookToken] :: Webhook -> Text
+ Discord.Internal.Types.User: [webhookToken] :: Webhook -> Maybe Text
- Discord.Types: Attachment :: Snowflake -> Text -> Integer -> Text -> Text -> Maybe Integer -> Maybe Integer -> Attachment
+ Discord.Types: Attachment :: AttachmentId -> Text -> Integer -> Text -> Text -> Maybe Integer -> Maybe Integer -> Attachment
- Discord.Types: Guild :: GuildId -> Text -> Maybe Text -> Maybe Text -> UserId -> Maybe Integer -> Maybe Text -> Maybe ChannelId -> Integer -> Maybe Bool -> Maybe ChannelId -> Integer -> Integer -> Integer -> [Role] -> [Emoji] -> [Text] -> !Integer -> Maybe Snowflake -> Guild
+ Discord.Types: Guild :: GuildId -> Text -> Maybe Text -> Maybe Text -> UserId -> Maybe Text -> Maybe Text -> Maybe ChannelId -> Integer -> Maybe Bool -> Maybe ChannelId -> Integer -> Integer -> Integer -> [Role] -> [Emoji] -> [Text] -> !Integer -> Maybe Snowflake -> Guild
- Discord.Types: GuildMember :: User -> Maybe Text -> [Snowflake] -> UTCTime -> Bool -> Bool -> GuildMember
+ Discord.Types: GuildMember :: Maybe User -> Maybe Text -> Maybe Text -> [RoleId] -> UTCTime -> Maybe UTCTime -> Bool -> Bool -> Bool -> Maybe Text -> GuildMember
- Discord.Types: Message :: MessageId -> ChannelId -> User -> Text -> UTCTime -> Maybe UTCTime -> Bool -> Bool -> [User] -> [RoleId] -> [Attachment] -> [Embed] -> [MessageReaction] -> Maybe Nonce -> Bool -> Maybe GuildId -> Maybe MessageReference -> Maybe Message -> 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 [Component] -> Maybe [StickerItem] -> Message
- Discord.Types: Overwrite :: OverwriteId -> Text -> Integer -> Integer -> Overwrite
+ Discord.Types: Overwrite :: OverwriteId -> Integer -> Text -> Text -> Overwrite
- Discord.Types: PartialGuild :: GuildId -> Text -> Maybe Text -> Bool -> Integer -> PartialGuild
+ Discord.Types: PartialGuild :: GuildId -> Text -> Maybe Text -> Bool -> Text -> PartialGuild
- Discord.Types: Ready :: Int -> User -> [Channel] -> [GuildUnavailable] -> Text -> Event
+ Discord.Types: Ready :: Int -> User -> [Channel] -> [GuildUnavailable] -> Text -> Maybe Shard -> PartialApplication -> Event
- Discord.Types: Role :: RoleId -> Text -> ColorInteger -> Bool -> Integer -> Integer -> Bool -> Bool -> Role
+ Discord.Types: Role :: RoleId -> Text -> ColorInteger -> Bool -> Integer -> Text -> Bool -> Bool -> Role
- Discord.Types: User :: UserId -> Text -> Text -> Maybe Text -> Bool -> Bool -> Maybe Bool -> Maybe Bool -> Maybe Text -> User
+ Discord.Types: User :: UserId -> Text -> Maybe Text -> Maybe Text -> Bool -> Bool -> Maybe Bool -> Maybe Bool -> Maybe Text -> Maybe Int -> Maybe Text -> Maybe Bool -> Maybe Text -> Maybe Integer -> Maybe Integer -> Maybe Integer -> Maybe GuildMember -> User
- Discord.Types: Webhook :: WebhookId -> Text -> ChannelId -> Webhook
+ Discord.Types: Webhook :: WebhookId -> Maybe Text -> ChannelId -> Webhook
- Discord.Types: [attachmentId] :: Attachment -> Snowflake
+ Discord.Types: [attachmentId] :: Attachment -> AttachmentId
- Discord.Types: [guildPermissions] :: Guild -> Maybe Integer
+ Discord.Types: [guildPermissions] :: Guild -> Maybe Text
- Discord.Types: [memberRoles] :: GuildMember -> [Snowflake]
+ Discord.Types: [memberRoles] :: GuildMember -> [RoleId]
- Discord.Types: [memberUser] :: GuildMember -> User
+ Discord.Types: [memberUser] :: GuildMember -> Maybe User
- Discord.Types: [overwriteAllow] :: Overwrite -> Integer
+ Discord.Types: [overwriteAllow] :: Overwrite -> Text
- Discord.Types: [overwriteDeny] :: Overwrite -> Integer
+ Discord.Types: [overwriteDeny] :: Overwrite -> Text
- Discord.Types: [overwriteType] :: Overwrite -> Text
+ Discord.Types: [overwriteType] :: Overwrite -> Integer
- Discord.Types: [partialGuildPermissions] :: PartialGuild -> Integer
+ Discord.Types: [partialGuildPermissions] :: PartialGuild -> Text
- Discord.Types: [rolePerms] :: Role -> Integer
+ Discord.Types: [rolePerms] :: Role -> Text
- Discord.Types: [userDiscrim] :: User -> Text
+ Discord.Types: [userDiscrim] :: User -> Maybe Text
- Discord.Types: [webhookToken] :: Webhook -> Text
+ Discord.Types: [webhookToken] :: Webhook -> Maybe Text
Files
- README.md +43/−87
- changelog.md +9/−0
- discord-haskell.cabal +9/−1
- examples/ping-pong.hs +30/−21
- src/Discord.hs +1/−1
- src/Discord/Interactions.hs +7/−0
- src/Discord/Internal/Gateway/Cache.hs +4/−2
- src/Discord/Internal/Gateway/EventLoop.hs +2/−2
- src/Discord/Internal/Rest.hs +4/−2
- src/Discord/Internal/Rest/ApplicationCommands.hs +103/−0
- src/Discord/Internal/Rest/Channel.hs +8/−33
- src/Discord/Internal/Rest/Guild.hs +12/−12
- src/Discord/Internal/Rest/Interactions.hs +65/−0
- src/Discord/Internal/Rest/Prelude.hs +7/−3
- src/Discord/Internal/Types.hs +11/−1
- src/Discord/Internal/Types/ApplicationCommands.hs +693/−0
- src/Discord/Internal/Types/Channel.hs +409/−49
- src/Discord/Internal/Types/Components.hs +296/−0
- src/Discord/Internal/Types/Events.hs +20/−5
- src/Discord/Internal/Types/Guild.hs +22/−38
- src/Discord/Internal/Types/Interactions.hs +614/−0
- src/Discord/Internal/Types/Prelude.hs +54/−1
- src/Discord/Internal/Types/User.hs +80/−14
- src/Discord/Requests.hs +4/−0
README.md view
@@ -1,54 +1,81 @@-# discord-haskell [](https://app.travis-ci.com/github/aquarial/discord-haskell) [](https://hackage.haskell.org/package/discord-haskell) [](https://discord.gg/eaRAGgX3bK)+# discord-haskell [](https://github.com/aquarial/discord-haskell/actions/) [](https://hackage.haskell.org/package/discord-haskell) [](https://discord.gg/eaRAGgX3bK) -Build that discord bot in Haskell! Also checkout the [calamity haskell library](https://github.com/nitros12/calamity) +## About++Build that discord bot in Haskell! Also checkout the [calamity haskell library](https://github.com/nitros12/calamity) for a more advanced interface than `discord-haskell`. -### Discord Server+### Documentation -Created a discord server: https://discord.gg/eaRAGgX3bK+#### Local Documentation +Find docs on features, metadata, and parts is found in [./docs/README.md#Documentation](./docs/README.md#Documentation)++#### Discord Server++Current project discord server: <https://discord.gg/eaRAGgX3bK>+ Ask questions, get updates, request features, etc +#### Official Discord Documentation++The [official discord documentation](https://discord.com/developers/docs/intro)+lists the rest requests, gateway events, and gateway sendables. The library+matches very closely. ++For example: +[Get Channel](https://discord.com/developers/docs/resources/channel#get-channel)+and discord-haskell has a rest request ADT including +`[GetChannel :: ChannelId -> ChannelRequest Channel]`. Similar matching exists for gateway `Event`s.++#### Open an Issue++If something goes wrong: check the error message, (optional: check log file), make sure you have the most recent version, ask on discord, or open a github issue.++## Implementation and Progress+ ### Quickstart -This is an example bot that replies "pong" to messages that start with "ping". Also checkout the [other examples](./examples/)+This is an example bot that replies "pong" to messages that start with "ping". Also checkout the [other examples](./examples/) for things like state management. ```haskell {-# LANGUAGE OverloadedStrings #-} -- allows "string literals" to be Text- import Control.Monad (when, void) import Data.Text (isPrefixOf, toLower, Text) import qualified Data.Text.IO as TIO- import UnliftIO.Concurrent- import Discord import Discord.Types import qualified Discord.Requests as R -- | Replies "pong" to every message that starts with "ping" pingpongExample :: IO ()-pingpongExample = do userFacingError <- runDiscord $ def- { discordToken = "Bot ZZZZZZZZZZZZZZZZZZZ"- , discordOnEvent = eventHandler }- TIO.putStrLn userFacingError+pingpongExample = do + userFacingError <- runDiscord $ def+ { discordToken = "Bot ZZZZZZZZZZZZZZZZZZZ"+ , discordOnEvent = eventHandler+ , discordOnLog = \s -> TIO.putStrLn s+ , discordForkThreadForEvents = True }+ TIO.putStrLn userFacingError+ -- userFacingError is an unrecoverable error+ -- put normal 'cleanup' code in discordOnEnd (see examples) eventHandler :: Event -> DiscordHandler () eventHandler event = case event of MessageCreate m -> when (not (fromBot m) && isPing m) $ do- void $ restCall (R.CreateReaction (messageChannel m, messageId m) "eyes")+ void $ restCall (R.CreateReaction (messageChannelId m, messageId m) "eyes") threadDelay (2 * 10^6)- void $ restCall (R.CreateMessage (messageChannel m) "Pong!")+ void $ restCall (R.CreateMessage (messageChannelId m) "Pong!") _ -> return () fromBot :: Message -> Bool fromBot = userIsBot . messageAuthor isPing :: Message -> Bool-isPing = ("ping" `isPrefixOf`) . toLower . messageText+isPing = ("ping" `isPrefixOf`) . toLower . messageContent ``` -```+```cabal -- ping-pong.cabal executable haskell-bot@@ -101,75 +128,4 @@ for some help setting up your bot token -### Emoji--For single character Emoji you can use the unicode name ("eyes", "fire", etc).--For multi-character Emoji you must use the discord format. Type `\:emoji:` into-a discord chat and paste that into the Text--For example `:thumbsup::skin-tone-3:` is `"👍\127997"`. -A custom emoji will look like `<name:id_number>` or `name:id_number`.--See [examples/ping-pong.hs](https://github.com/aquarial/discord-haskell/blob/master/examples/ping-pong.hs)- for a `CreateReaction` request in use. -### Embeds--Embeds are special messages with boarders and images. [Example embed created by discord-haskell](./examples/embed-photo.jpg)--The `Embed` record (and sub-records) store embed data received from Discord.--The `CreateEmbed` record stores data when we want to create an embed.--`CreateEmbed` has a `Default` instance, so you only need to specify the fields you use:--```haskell-_ <- restCall (R.CreateMessageEmbed <channel_id> "Pong!" $- def { createEmbedTitle = "Pong Embed"- , createEmbedImage = Just $ CreateEmbedImageUpload <bytestring>- , createEmbedThumbnail = Just $ CreateEmbedImageUrl- "https://avatars2.githubusercontent.com/u/37496339"- })-```--Uploading a file each time is slow, prefer uploading images to a hosting site like imgur.com, and then referencing them.- -### Limitations--The following features are not implemented:--- Voice & Audio-- Authenticating with a user token--### Debugging--Always print the userFacingError Text returned from `runDiscord`. I use this to record-errors that cannot be recovered from.--If something else goes wrong with the library please open an issue. It is helpful,-but not always necessary, to attach a log of what's going on when the library-crashes.--Assign a handler to the `discordOnLog :: Text -> IO ()` to print info as it happens.-Remember to remove sensitive information before posting.--### Getting Help--#### Official discord docs--For a list of rest requests, gateway events, and gateway sendables go ggto the -[official discord documentation](https://discord.com/developers/docs/intro)--The rest requests line up very closely. The documentation lists -[Get Channel](https://discord.com/developers/docs/resources/channel#get-channel)-and discord-haskell has `GetChannel :: ChannelId -> ChannelRequest Channel`. Same for gateway `Event`s.--#### Examples--The [examples](https://github.com/aquarial/discord-haskell/tree/master/examples) were crafted-to display a variety of use cases. Read them with care.--#### Open an Issue--For deeper questions about how the library functions, feel free to open an issue.
changelog.md view
@@ -6,6 +6,15 @@ ## master +## 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!+++[L0neGamer](https://github.com/aquarial/discord-haskell/pull/94) fixed a parse error with webhooktoken+++rename fields `messageText` -> `messageContent`, `messageChannel` -> `messageChannelId` ## 1.10.0
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.10.0+version: 1.11.0 description: Functions and data types to write discord bots. Official discord docs <https://discord.com/developers/docs/reference>. .@@ -34,6 +34,7 @@ , text , unliftio , discord-haskell+ -- , req {- needed for slash commands -} library ghc-options: -Wall@@ -44,6 +45,7 @@ exposed-modules: Discord , Discord.Types , Discord.Handle+ , Discord.Interactions , Discord.Requests , Discord.Internal.Gateway , Discord.Internal.Gateway.Cache@@ -58,6 +60,8 @@ , Discord.Internal.Rest.Channel , Discord.Internal.Rest.Voice , Discord.Internal.Rest.Webhook+ , Discord.Internal.Rest.ApplicationCommands+ , Discord.Internal.Rest.Interactions , Discord.Internal.Types , Discord.Internal.Types.Prelude , Discord.Internal.Types.Channel@@ -66,6 +70,9 @@ , Discord.Internal.Types.Guild , Discord.Internal.Types.User , Discord.Internal.Types.Embed+ , Discord.Internal.Types.ApplicationCommands+ , Discord.Internal.Types.Interactions+ , Discord.Internal.Types.Components build-depends: base >= 4 && <5 , aeson@@ -89,3 +96,4 @@ , wuss , mtl , unliftio+ , scientific
examples/ping-pong.hs view
@@ -13,28 +13,39 @@ -- Allows this code to be an executable. See discord-haskell.cabal main :: IO ()-main = pingpongExample+main = if testserverid == -1+ then TIO.putStrLn "ERROR: modify the source and set testserverid to your serverid"+ else pingpongExample +++-- check the url in a discord server+-- <server id> <channel id>+-- https://discord.com/channels/2385235298674262408/4286572469284672046+testserverid :: Snowflake+testserverid = 453207241294610442+ -- | Replies "pong" to every message that starts with "ping" pingpongExample :: IO () pingpongExample = do tok <- TIO.readFile "./examples/auth-token.secret" -- open ghci and run [[ :info RunDiscordOpts ]] to see available fields- t <- runDiscord $ def { discordToken = tok- , discordOnStart = startHandler- , discordOnEnd = liftIO $ putStrLn "Ended"- , discordOnEvent = eventHandler- , discordOnLog = \s -> TIO.putStrLn s >> TIO.putStrLn ""- }- TIO.putStrLn t+ err <- runDiscord $ def { discordToken = tok+ , discordOnStart = startHandler+ , discordOnEnd = liftIO $ putStrLn "Ended"+ , discordOnEvent = eventHandler+ , discordOnLog = \s -> TIO.putStrLn s >> TIO.putStrLn ""+ } + -- only reached on an unrecoverable error+ -- put normal 'cleanup' code in discordOnEnd+ TIO.putStrLn err+ -- If the start handler throws an exception, discord-haskell will gracefully shutdown -- Use place to execute commands you know you want to complete startHandler :: DiscordHandler () startHandler = do- Right partialGuilds <- restCall R.GetCurrentUserGuilds- let activity = Activity { activityName = "ping-pong" , activityType = ActivityTypeGame , activityUrl = Nothing@@ -46,23 +57,21 @@ } sendCommand (UpdateStatus opts) - forM_ partialGuilds $ \pg -> do- Right guild <- restCall $ R.GetGuild (partialGuildId pg)- Right chans <- restCall $ R.GetGuildChannels (guildId guild)- forM_ (take 1 (filter isTextChannel chans))- (\channel -> restCall $ R.CreateMessage (channelId channel)- "Hello! I will reply to pings with pongs")+ Right chans <- restCall $ R.GetGuildChannels testserverid+ forM_ (take 1 (filter isTextChannel chans))+ (\channel -> restCall $ R.CreateMessage (channelId channel)+ "Hello! I will reply to pings with pongs") -- If an event handler throws an exception, discord-haskell will continue to run eventHandler :: Event -> DiscordHandler () eventHandler event = case event of MessageCreate m -> when (not (fromBot m) && isPing m) $ do- void $ restCall (R.CreateReaction (messageChannel m, messageId m) "eyes")- threadDelay (2 * 10^(6 :: Int))+ void $ restCall (R.CreateReaction (messageChannelId m, messageId m) "eyes")+ threadDelay (2 * 10 ^ (6 :: Int)) -- A very simple message.- void $ restCall (R.CreateMessage (messageChannel m) "Pong!")+ void $ restCall (R.CreateMessage (messageChannelId m) "Pong!") -- A more complex message. Text-to-speech, does not mention everyone nor -- the user, and uses Discord native replies.@@ -77,7 +86,7 @@ , R.messageDetailedReference = Just $ def { referenceMessageId = Just $ messageId m } }- void $ restCall (R.CreateMessageDetailed (messageChannel m) opts)+ void $ restCall (R.CreateMessageDetailed (messageChannelId m) opts) _ -> return () isTextChannel :: Channel -> Bool@@ -88,4 +97,4 @@ fromBot = userIsBot . messageAuthor isPing :: Message -> Bool-isPing = ("ping" `T.isPrefixOf`) . T.toLower . messageText+isPing = ("ping" `T.isPrefixOf`) . T.toLower . messageContent
src/Discord.hs view
@@ -131,7 +131,7 @@ resp <- liftIO $ writeRestCall (discordHandleRestChan h) r case resp of Right x -> pure (Right x)- Left (RestCallInternalErrorCode c e1 e2) ->+ Left (RestCallInternalErrorCode c e1 e2) -> do pure (Left (RestCallErrorCode c (TE.decodeUtf8 e1) (TE.decodeUtf8 e2))) Left (RestCallInternalHttpException _) -> threadDelay (10 * 10^(6 :: Int)) >> restCall r
+ src/Discord/Interactions.hs view
@@ -0,0 +1,7 @@+module Discord.Interactions+ ( 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
@@ -18,6 +18,7 @@ , cacheDMChannels :: M.Map ChannelId Channel , cacheGuilds :: M.Map GuildId (Guild, GuildInfo) , cacheChannels :: M.Map ChannelId Channel+ , cacheApplication :: PartialApplication } deriving (Show) data CacheHandle = CacheHandle@@ -29,9 +30,9 @@ cacheLoop cacheHandle log = do ready <- readChan eventChan case ready of- Right (InternalReady _ user dmChannels _unavailableGuilds _) -> do+ Right (InternalReady _ user dmChannels _unavailableGuilds _ _ pApp) -> do let dmChans = M.fromList (zip (map channelId dmChannels) dmChannels)- putMVar cache (Right (Cache user dmChans M.empty M.empty))+ putMVar cache (Right (Cache user dmChans M.empty M.empty pApp)) loop Right r -> writeChan log ("cache - stopping cache - expected Ready event, but got " <> T.pack (show r))@@ -72,6 +73,7 @@ -- c = M.filterWithKey (\(keyGuildId,_) _ -> keyGuildId /= guildId guild) (cacheChannels minfo) -- m2 = minfo { cacheGuilds = g, cacheChannels = c } -- putMVar cache m2+ InternalReady _ _ _ _ _ _ pa -> minfo { cacheApplication = pa } _ -> minfo setChanGuildID :: GuildId -> Channel -> Channel
src/Discord/Internal/Gateway/EventLoop.hs view
@@ -102,7 +102,7 @@ LoopClosed -> pure Nothing startconnectionpls :: GatewaySendableInternal -> IO LoopState- startconnectionpls first = runSecureClient "gateway.discord.gg" 443 "/?v=6&encoding=json" $ \conn -> do+ startconnectionpls first = runSecureClient "gateway.discord.gg" 443 "/?v=8&encoding=json" $ \conn -> do msg <- getPayload conn log case msg of Right (Hello interval) -> do@@ -141,7 +141,7 @@ Right (Dispatch event sq) -> do writeIORef (gatewayHandleLastSequenceId thehandle) sq writeChan eventChan (Right event) case event of- (InternalReady _ _ _ _ seshID) ->+ (InternalReady _ _ _ _ seshID _ _) -> writeIORef (gatewayHandleSessionId thehandle) seshID _ -> writeIORef (startsendingUsers sendablesData) True loop
src/Discord/Internal/Rest.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE OverloadedStrings #-} -- | Provides a higher level interface to the rest functions.@@ -43,8 +44,9 @@ r <- readMVar m pure $ case eitherDecode <$> r of Right (Right o) -> Right o- Right (Left er) -> Left (RestCallInternalNoParse er (case r of Right x -> x- Left _ -> ""))+ (Right (Left er)) -> Left (RestCallInternalNoParse er (case r of + Right x -> x+ Left _ -> "")) Left e -> Left e
+ src/Discord/Internal/Rest/ApplicationCommands.hs view
@@ -0,0 +1,103 @@+{-# 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 Discord.Internal.Rest.Prelude+import Discord.Internal.Types+import Discord.Internal.Types.ApplicationCommands+++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+ 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+ DeleteGuildApplicationCommand :: ApplicationId -> GuildId -> ApplicationCommandId -> ApplicationCommandRequest ()+ BulkOverWriteGuildApplicationCommand :: ApplicationId -> GuildId -> [CreateApplicationCommand] -> ApplicationCommandRequest ()+ GetGuildApplicationCommandPermissions :: ApplicationId -> GuildId -> ApplicationCommandRequest GuildApplicationCommandPermissions+ GetApplicationCommandPermissions :: ApplicationId -> GuildId -> ApplicationCommandId -> ApplicationCommandRequest GuildApplicationCommandPermissions+ EditApplicationCommandPermissions :: ApplicationId -> GuildId -> ApplicationCommandId -> [ApplicationCommandPermissions] -> ApplicationCommandRequest GuildApplicationCommandPermissions+ -- | 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++applicationCommandMajorRoute :: ApplicationCommandRequest a -> String+applicationCommandMajorRoute a = case a of+ (GetGlobalApplicationCommands aid) -> "get_glob_appcomm" <> show aid+ (CreateGlobalApplicationCommand aid _) -> "write_glob_appcomm" <> show aid+ (GetGlobalApplicationCommand aid _) -> "get_glob_appcomm" <> show aid+ (EditGlobalApplicationCommand aid _ _) -> "write_glob_appcomm" <> show aid+ (DeleteGlobalApplicationCommand aid _) -> "write_glob_appcomm" <> show aid+ (BulkOverWriteGlobalApplicationCommand aid _) -> "write_glob_appcomm" <> show aid+ (GetGuildApplicationCommands aid _) -> "get_appcomm" <> show aid+ (CreateGuildApplicationCommand aid _ _) -> "write_appcomm" <> show aid+ (GetGuildApplicationCommand aid _ _) -> "get_appcomm" <> show aid+ (EditGuildApplicationCommand aid _ _ _) -> "write_appcomm" <> show aid+ (DeleteGuildApplicationCommand aid _ _) -> "write_appcomm" <> show aid+ (BulkOverWriteGuildApplicationCommand aid _ _) -> "write_appcomm" <> show aid+ (GetGuildApplicationCommandPermissions aid _) -> "appcom_perm " <> show aid+ (GetApplicationCommandPermissions aid _ _) -> "appcom_perm " <> show aid+ (EditApplicationCommandPermissions aid _ _ _) -> "appcom_perm " <> show aid+ (BatchEditApplicationCommandPermissions aid _ _) -> "appcom_perm " <> show aid++applicationCommandJsonRequest :: ApplicationCommandRequest a -> JsonRequest+applicationCommandJsonRequest a = case a of+ (GetGlobalApplicationCommands aid) ->+ Get (applications aid /: "commands") mempty+ (CreateGlobalApplicationCommand aid cac) ->+ Post (applications aid /: "commands") (convert cac) mempty+ (GetGlobalApplicationCommand aid aci) ->+ Get (applications aid /: "commands" // aci) mempty+ (EditGlobalApplicationCommand aid aci eac) ->+ Patch (applications aid /: "commands" // aci) (convert eac) mempty+ (DeleteGlobalApplicationCommand aid aci) ->+ Delete (applications aid /: "commands" // aci) mempty+ (BulkOverWriteGlobalApplicationCommand aid cacs) ->+ Put (applications aid /: "commands") (R.ReqBodyJson $ toJSON cacs) mempty+ (GetGuildApplicationCommands aid gid) ->+ Get (applications aid /: "guilds" // gid /: "commands") mempty+ (CreateGuildApplicationCommand aid gid cac) ->+ Post (applications aid /: "guilds" // gid /: "commands") (convert cac) mempty+ (GetGuildApplicationCommand aid gid aci) ->+ Get (applications aid /: "guilds" // gid /: "commands" // aci) mempty+ (EditGuildApplicationCommand aid gid aci eac) ->+ Patch (applications aid /: "guilds" // gid /: "commands" // aci) (convert eac) mempty+ (DeleteGuildApplicationCommand aid gid aci) ->+ Delete (applications aid /: "guilds" // gid /: "commands" // aci) mempty+ (BulkOverWriteGuildApplicationCommand aid gid cacs) ->+ Put (applications aid /: "guilds" // gid /: "commands") (R.ReqBodyJson $ toJSON cacs) mempty+ (GetGuildApplicationCommandPermissions aid gid) ->+ Get (applications aid /: "guilds" // gid /: "commands" /: "permissions") mempty+ (GetApplicationCommandPermissions aid gid cid) ->+ Get (applications aid /: "guilds" // gid /: "commands" // cid /: "permissions") mempty+ (EditApplicationCommandPermissions aid gid cid ps) ->+ Put (applications aid /: "guilds" // gid /: "commands" // cid /: "permissions") (R.ReqBodyJson $ toJSON (GuildApplicationCommandPermissions aid cid gid ps)) mempty+ (BatchEditApplicationCommandPermissions aid gid ps) ->+ Put (applications aid /: "guilds" // gid /: "commands" /: "permissions") (R.ReqBodyJson $ toJSON ps) mempty+ where+ convert :: (ToJSON a) => a -> RestIO (ReqBodyJson Value)+ convert = (pure @RestIO) . R.ReqBodyJson . toJSON
src/Discord/Internal/Rest/Channel.hs view
@@ -106,6 +106,8 @@ , messageDetailedFile :: Maybe (T.Text, B.ByteString) , messageDetailedAllowedMentions :: Maybe AllowedMentions , messageDetailedReference :: Maybe MessageReference+ , messageDetailedComponents :: Maybe [Component]+ , messageDetailedStickerIds :: Maybe [StickerId] } deriving (Show, Read, Eq, Ord) instance Default MessageDetailedOpts where@@ -115,39 +117,10 @@ , messageDetailedFile = Nothing , messageDetailedAllowedMentions = Nothing , messageDetailedReference = Nothing+ , messageDetailedComponents = Nothing+ , messageDetailedStickerIds = Nothing } --- | Data constructor for a part of MessageDetailedOpts.-data AllowedMentions = AllowedMentions- { mentionEveryone :: Bool- , mentionUsers :: Bool- , mentionRoles :: Bool- , mentionUserIds :: [UserId]- , mentionRoleIds :: [RoleId]- , mentionRepliedUser :: Bool- } deriving (Show, Read, Eq, Ord)--instance Default AllowedMentions where- def = AllowedMentions { mentionEveryone = False- , mentionUsers = True- , mentionRoles = True- , mentionUserIds = []- , mentionRoleIds = []- , mentionRepliedUser = True- }--instance ToJSON AllowedMentions where- toJSON AllowedMentions{..} = object [- ("parse" .= [name :: T.Text | (name, True) <-- [ ("everyone", mentionEveryone),- ("users", mentionUsers && mentionUserIds == []),- ("roles", mentionRoles && mentionRoleIds == []) ] ]),- -- https://discord.com/developers/docs/resources/channel#allowed-mentions-object- -- parse.users and users list cannot both be active, prioritize id list- ("roles" .= mentionRoleIds),- ("users" .= mentionUserIds),- ("replied_user" .= mentionRepliedUser) ]- -- | Data constructor for GetReaction requests data ReactionTiming = BeforeReaction MessageId | AfterReaction MessageId@@ -330,12 +303,14 @@ Just f -> [partFileRequestBody "file" (T.unpack $ fst f) $ RequestBodyBS $ snd f] - payloadData = object $ [ "content" .= messageDetailedContent msgOpts+ payloadData = object $ [ "content" .= messageDetailedContent msgOpts , "tts" .= messageDetailedTTS msgOpts ] ++ [ name .= value | (name, Just value) <-- [ ("embed", toJSON <$> createEmbed <$> messageDetailedEmbed msgOpts)+ [ ("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
src/Discord/Internal/Rest/Guild.hs view
@@ -131,12 +131,12 @@ DeleteGuildIntegration :: GuildId -> IntegrationId -> GuildRequest () -- | Sync an 'Integration'. Requires the 'MANAGE_GUILD' permission. SyncGuildIntegration :: GuildId -> IntegrationId -> GuildRequest ()- -- | Returns the 'GuildEmbed' object. Requires the 'MANAGE_GUILD' permission.- GetGuildEmbed :: GuildId -> GuildRequest GuildEmbed- -- | Modify a 'GuildEmbed' object for the guild. All attributes may be passed in with+ -- | Returns the 'GuildWidget' object. Requires the 'MANAGE_GUILD' permission.+ 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- -- 'GuildEmbed' object.- ModifyGuildEmbed :: GuildId -> GuildEmbed -> GuildRequest GuildEmbed+ -- 'GuildWidget' object.+ ModifyGuildWidget :: GuildId -> GuildWidget -> GuildRequest GuildWidget -- | Vanity URL GetGuildVanityURL :: GuildId -> GuildRequest T.Text @@ -167,13 +167,13 @@ instance ToJSON CreateGuildBanOpts where toJSON CreateGuildBanOpts{..} = object [(name, val) | (name, Just val) <-- [("delete-message-days",+ [("delete_message_days", toJSON <$> createGuildBanOptsDeleteLastNMessages ), ("reason", toJSON <$> createGuildBanOptsReason )]] data ModifyGuildRoleOpts = ModifyGuildRoleOpts { modifyGuildRoleOptsName :: Maybe T.Text- , modifyGuildRoleOptsPermissions :: Maybe Integer+ , modifyGuildRoleOptsPermissions :: Maybe T.Text , modifyGuildRoleOptsColor :: Maybe ColorInteger , modifyGuildRoleOptsSeparateSidebar :: Maybe Bool , modifyGuildRoleOptsMentionable :: Maybe Bool@@ -324,8 +324,8 @@ (ModifyGuildIntegration g _ _) -> "guild_intgr " <> show g (DeleteGuildIntegration g _) -> "guild_intgr " <> show g (SyncGuildIntegration g _) -> "guild_sync " <> show g- (GetGuildEmbed g) -> "guild_embed " <> show g- (ModifyGuildEmbed g _) -> "guild_embed " <> show g+ (GetGuildWidget g) -> "guild_widget " <> show g+ (ModifyGuildWidget g _) -> "guild_widget " <> show g (GetGuildVanityURL g) -> "guild " <> show g @@ -436,11 +436,11 @@ (SyncGuildIntegration guild integ) -> Post (guilds // guild /: "integrations" // integ) (pure R.NoReqBody) mempty - (GetGuildEmbed guild) ->+ (GetGuildWidget guild) -> Get (guilds // guild /: "integrations") mempty - (ModifyGuildEmbed guild patch) ->- Patch (guilds // guild /: "embed") (pure (R.ReqBodyJson patch)) mempty+ (ModifyGuildWidget guild patch) ->+ Patch (guilds // guild /: "widget") (pure (R.ReqBodyJson patch)) mempty (GetGuildVanityURL guild) -> Get (guilds // guild /: "vanity-url") mempty
+ src/Discord/Internal/Rest/Interactions.hs view
@@ -0,0 +1,65 @@+{-# 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 Discord.Internal.Rest.Prelude+import Discord.Internal.Types+import Discord.Internal.Types.Interactions++data InteractionResponseRequest a where+ CreateInteractionResponse :: InteractionId -> InteractionToken -> InteractionResponse -> InteractionResponseRequest ()+ GetOriginalInteractionResponse :: ApplicationId -> InteractionToken -> InteractionResponseRequest Message+ EditOriginalInteractionResponse :: ApplicationId -> InteractionToken -> InteractionCallbackMessages -> InteractionResponseRequest Message+ DeleteOriginalInteractionResponse :: ApplicationId -> InteractionToken -> InteractionResponseRequest ()+ CreateFollowupInteractionMessage :: ApplicationId -> InteractionToken -> InteractionCallbackMessages -> InteractionResponseRequest Message+ GetFollowupInteractionMessage :: ApplicationId -> InteractionToken -> MessageId -> InteractionResponseRequest Message+ EditFollowupInteractionMessage :: ApplicationId -> InteractionToken -> MessageId -> InteractionResponse -> InteractionResponseRequest Message+ DeleteFollowupInteractionMessage :: ApplicationId -> InteractionToken -> MessageId -> InteractionResponseRequest ()++instance Request (InteractionResponseRequest a) where+ jsonRequest = interactionResponseJsonRequest+ majorRoute = interactionResponseMajorRoute++interactionResponseMajorRoute :: InteractionResponseRequest a -> String+interactionResponseMajorRoute a = case a of+ (CreateInteractionResponse iid _ _) -> "intresp " <> show iid+ (GetOriginalInteractionResponse aid _) -> "intresp " <> show aid+ (EditOriginalInteractionResponse aid _ _) -> "intresp " <> show aid+ (DeleteOriginalInteractionResponse aid _) -> "intresp " <> show aid+ (CreateFollowupInteractionMessage iid _ _) -> "intrespf " <> show iid+ (GetFollowupInteractionMessage aid _ _) -> "intrespf " <> show aid+ (EditFollowupInteractionMessage aid _ _ _) -> "intrespf " <> show aid+ (DeleteFollowupInteractionMessage aid _ _) -> "intrespf " <> show aid++interaction :: ApplicationId -> InteractionToken -> R.Url 'R.Https+interaction aid it = baseUrl /: "webhooks" // aid /: it /: "messages"++interactionResponseJsonRequest :: InteractionResponseRequest a -> JsonRequest+interactionResponseJsonRequest a = case a of+ (CreateInteractionResponse iid it i) ->+ Post (baseUrl /: "interactions" // iid /: it /: "callback") (convert i) mempty+ (GetOriginalInteractionResponse aid it) ->+ Get (interaction aid it /: "@original") mempty+ (EditOriginalInteractionResponse aid it i) ->+ Patch (interaction aid it /: "@original") (convert i) mempty+ (DeleteOriginalInteractionResponse aid it) ->+ Delete (interaction aid it /: "@original") mempty+ (CreateFollowupInteractionMessage aid it i) ->+ Post (baseUrl /: "webhooks" // aid /: it) (convert i) mempty+ (GetFollowupInteractionMessage aid it mid) ->+ Get (interaction aid it // mid) mempty+ (EditFollowupInteractionMessage aid it mid i) ->+ Patch (interaction aid it // mid) (convert i) mempty+ (DeleteFollowupInteractionMessage aid it mid) ->+ Delete (interaction aid it // mid) mempty+ where+ convert :: (ToJSON a) => a -> RestIO (ReqBodyJson Value)+ convert = (pure @RestIO) . R.ReqBodyJson . toJSON
src/Discord/Internal/Rest/Prelude.hs view
@@ -19,7 +19,7 @@ -- | The base url (Req) for API requests baseUrl :: R.Url 'R.Https baseUrl = R.https "discord.com" R./: "api" R./: apiVersion- where apiVersion = "v6"+ where apiVersion = "v8" -- | Discord requires HTTP headers for authentication. authHeader :: Auth -> R.Option 'R.Https@@ -29,7 +29,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.10.0)"+ agent = "DiscordBot (https://github.com/aquarial/discord-haskell, 1.11.0)" -- Append to an URL infixl 5 //@@ -37,7 +37,7 @@ (//) url part = url R./: T.pack (show part) --- | Represtents a HTTP request made to an API that supplies a Json response+-- | A compiled HTTP request ready to execute data JsonRequest where Delete :: R.Url 'R.Https -> R.Option 'R.Https -> JsonRequest Get :: R.Url 'R.Https -> R.Option 'R.Https -> JsonRequest@@ -46,7 +46,11 @@ Post :: R.HttpBody a => R.Url 'R.Https -> RestIO a -> R.Option 'R.Https -> JsonRequest class Request a where+ -- | used for putting a request into a rate limit bucket+ -- https://discord.com/developers/docs/topics/rate-limits#rate-limits majorRoute :: a -> String++ -- | build a JSON http request jsonRequest :: a -> JsonRequest -- | Same Monad as IO. Overwrite Req settings
src/Discord/Internal/Types.hs view
@@ -8,6 +8,9 @@ , 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@@ -20,14 +23,20 @@ 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) userFacingEvent :: EventInternalParse -> Event userFacingEvent event = case event of- InternalReady a b c d e -> Ready a b c d e+ InternalReady a b c d e f g -> Ready a b c d e f g InternalResumed a -> Resumed a InternalChannelCreate a -> ChannelCreate a InternalChannelUpdate a -> ChannelUpdate a@@ -58,4 +67,5 @@ InternalPresenceUpdate a -> PresenceUpdate a InternalTypingStart a -> TypingStart a InternalUserUpdate a -> UserUpdate a+ InternalInteractionCreate a -> InteractionCreate (fromMaybe (InteractionUnknown a) (fromInternal a)) InternalUnknownEvent a b -> UnknownEvent a b
+ src/Discord/Internal/Types/ApplicationCommands.hs view
@@ -0,0 +1,693 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RecordWildCards #-}++module Discord.Internal.Types.ApplicationCommands+ ( ApplicationCommand (..),+ ApplicationCommandOptionSubcommandOrGroup (..),+ ApplicationCommandOptionSubcommand (..),+ ApplicationCommandOptionValue (..),+ InternalApplicationCommand (..),+ CreateApplicationCommand (..),+ createApplicationCommandChatInput,+ createApplicationCommandUser,+ createApplicationCommandMessage,+ EditApplicationCommand (..),+ ApplicationCommandType (..),+ InternalApplicationCommandOption (..),+ ApplicationCommandOptionType (..),+ InternalApplicationCommandOptionChoice,+ Choice (..),+ ApplicationCommandChannelType (..),+ GuildApplicationCommandPermissions (..),+ ApplicationCommandPermissions (..),+ ApplicationCommandPermissionType (..),+ StringNumberValue (..),+ )+where++import Control.Applicative+import Data.Aeson+import Data.Char (isLower)+import Data.Data (Data)+import Data.Default (Default (..))+import Data.Maybe (fromJust, fromMaybe)+import Data.Scientific (Scientific)+import qualified Data.Text as T+import Discord.Internal.Types.Prelude (ApplicationCommandId, ApplicationId, GuildId, Internals (..), Snowflake, makeTable, toMaybeJSON)++data ApplicationCommand+ = ApplicationCommandUser+ { applicationCommandId :: ApplicationCommandId,+ applicationCommandApplicationId :: ApplicationId,+ applicationCommandGuildId :: Maybe GuildId,+ applicationCommandName :: T.Text,+ applicationCommandDefaultPermission :: Maybe Bool,+ applicationCommandVersion :: Snowflake+ }+ | ApplicationCommandMessage+ { applicationCommandId :: ApplicationCommandId,+ applicationCommandApplicationId :: ApplicationId,+ applicationCommandGuildId :: Maybe GuildId,+ applicationCommandName :: T.Text,+ applicationCommandDefaultPermission :: Maybe Bool,+ applicationCommandVersion :: Snowflake+ }+ | ApplicationCommandChatInput+ { applicationCommandId :: ApplicationCommandId,+ applicationCommandApplicationId :: ApplicationId,+ applicationCommandGuildId :: Maybe GuildId,+ applicationCommandName :: T.Text,+ applicationCommandDescription :: T.Text,+ applicationCommandOptions :: Maybe ApplicationCommandOptions,+ applicationCommandDefaultPermission :: Maybe Bool,+ applicationCommandVersion :: Snowflake+ }+ | ApplicationCommandUnknown InternalApplicationCommand+ deriving (Show, Eq, Read)++data ApplicationCommandOptions+ = ApplicationCommandOptionsSubcommands [ApplicationCommandOptionSubcommandOrGroup]+ | ApplicationCommandOptionsValues [ApplicationCommandOptionValue]+ deriving (Show, Eq, Read)++data ApplicationCommandOptionSubcommandOrGroup+ = ApplicationCommandOptionSubcommandGroup+ { applicationCommandOptionSubcommandGroupName :: T.Text,+ applicationCommandOptionSubcommandGroupDescription :: T.Text,+ applicationCommandOptionSubcommandGroupOptions :: [ApplicationCommandOptionSubcommand]+ }+ | ApplicationCommandOptionSubcommandOrGroupSubcommand ApplicationCommandOptionSubcommand+ deriving (Show, Eq, Read)++data ApplicationCommandOptionSubcommand = ApplicationCommandOptionSubcommand+ { applicationCommandOptionSubcommandName :: T.Text,+ applicationCommandOptionSubcommandDescription :: T.Text,+ applicationCommandOptionSubcommandOptions :: [ApplicationCommandOptionValue]+ }+ deriving (Show, Eq, Read)++data ApplicationCommandOptionValue+ = ApplicationCommandOptionValueString+ { applicationCommandOptionValueName :: T.Text,+ applicationCommandOptionValueDescription :: T.Text,+ applicationCommandOptionValueRequired :: Maybe Bool,+ applicationCommandOptionValueStringChoices :: Maybe [Choice T.Text],+ applicationCommandOptionValueAutocomplete :: Maybe Bool+ }+ | ApplicationCommandOptionValueInteger+ { applicationCommandOptionValueName :: T.Text,+ applicationCommandOptionValueDescription :: T.Text,+ applicationCommandOptionValueRequired :: Maybe Bool,+ applicationCommandOptionValueIntegerChoices :: Maybe [Choice Integer],+ applicationCommandOptionValueIntegerMinVal :: Maybe Integer,+ applicationCommandOptionValueIntegerMaxVal :: Maybe Integer,+ applicationCommandOptionValueAutocomplete :: Maybe Bool+ }+ | ApplicationCommandOptionValueBoolean+ { applicationCommandOptionValueName :: T.Text,+ applicationCommandOptionValueDescription :: T.Text,+ applicationCommandOptionValueRequired :: Maybe Bool+ }+ | ApplicationCommandOptionValueUser+ { applicationCommandOptionValueName :: T.Text,+ applicationCommandOptionValueDescription :: T.Text,+ applicationCommandOptionValueRequired :: Maybe Bool+ }+ | ApplicationCommandOptionValueChannel+ { applicationCommandOptionValueName :: T.Text,+ applicationCommandOptionValueDescription :: T.Text,+ applicationCommandOptionValueRequired :: Maybe Bool,+ applicationCommandOptionValueChannelTypes :: Maybe [ApplicationCommandChannelType]+ }+ | ApplicationCommandOptionValueRole+ { applicationCommandOptionValueName :: T.Text,+ applicationCommandOptionValueDescription :: T.Text,+ applicationCommandOptionValueRequired :: Maybe Bool+ }+ | ApplicationCommandOptionValueMentionable+ { applicationCommandOptionValueName :: T.Text,+ applicationCommandOptionValueDescription :: T.Text,+ applicationCommandOptionValueRequired :: Maybe Bool+ }+ | ApplicationCommandOptionValueNumber+ { applicationCommandOptionValueName :: T.Text,+ applicationCommandOptionValueDescription :: T.Text,+ applicationCommandOptionValueRequired :: Maybe Bool,+ applicationCommandOptionValueNumberChoices :: Maybe [Choice Scientific],+ applicationCommandOptionValueNumberMinVal :: Maybe Scientific,+ applicationCommandOptionValueNumberMaxVal :: Maybe Scientific,+ applicationCommandOptionValueAutocomplete :: Maybe Bool+ }+ 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 Enum ApplicationCommandType where+ fromEnum ApplicationCommandTypeChatInput = 1+ fromEnum ApplicationCommandTypeUser = 2+ fromEnum ApplicationCommandTypeMessage = 3+ toEnum a = fromJust $ lookup a table+ where+ table = makeTable ApplicationCommandTypeChatInput++instance ToJSON ApplicationCommandType where+ toJSON = toJSON . fromEnum++instance FromJSON ApplicationCommandType where+ parseJSON = withScientific "ApplicationCommandType" (return . toEnum . round)++-- | Data type to be used when creating application commands. The specification+-- is below.+--+-- If a command of the same type and and name is sent to the server, it will+-- overwrite any command that already exists in the same scope (guild vs+-- global).+--+-- The description has to be empty for non-slash command application+-- commands, as do the options. The options need to be `Nothing` for non-slash+-- commands, too. If one of the options is a subcommand or subcommand group,+-- the base command will no longer be usable.+--+-- A subcommand group can have subcommands within it. This is the maximum amount+-- 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+ }+ deriving (Show, Eq, Read)++instance ToJSON CreateApplicationCommand where+ toJSON CreateApplicationCommand {..} =+ object+ [ (name, value)+ | (name, Just value) <-+ [ ("name", toMaybeJSON createApplicationCommandName),+ ("description", toMaybeJSON createApplicationCommandDescription),+ ("options", toJSON <$> createApplicationCommandOptions),+ ("default_permission", toJSON <$> createApplicationCommandDefaultPermission),+ ("type", toJSON <$> createApplicationCommandType)+ ]+ ]++-- | 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)+ | 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)+ | 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)+ | 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+ }++instance Default EditApplicationCommand where+ def = EditApplicationCommand Nothing Nothing Nothing Nothing Nothing++instance ToJSON EditApplicationCommand where+ toJSON EditApplicationCommand {..} =+ object+ [ (name, value)+ | (name, Just value) <-+ [ ("name", toJSON <$> editApplicationCommandName),+ ("description", toJSON <$> editApplicationCommandDescription),+ ("options", toJSON <$> editApplicationCommandOptions),+ ("default_permission", toJSON <$> editApplicationCommandDefaultPermission),+ ("type", toJSON <$> editApplicationCommandType)+ ]+ ]++-- | 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 {..} =+ 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)+ ]+ ]++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)++data Choice a = Choice {choiceName :: T.Text, choiceValue :: a}+ deriving (Show, Read, Eq)++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)]++instance (FromJSON a) => FromJSON (Choice a) where+ parseJSON =+ withObject+ "Choice"+ ( \v ->+ Choice+ <$> v .: "name"+ <*> v .: "value"+ )++-- | The different channel types.+--+-- https://discord.com/developers/docs/resources/channel#channel-object-channel-types+data ApplicationCommandChannelType+ = -- | A text channel in a server.+ ApplicationCommandChannelTypeGuildText+ | -- | A direct message between users.+ ApplicationCommandChannelTypeDM+ | -- | A voice channel in a server.+ ApplicationCommandChannelTypeGuildVoice+ | -- | A direct message between multiple users.+ ApplicationCommandChannelTypeGroupDM+ | -- | An organizational category that contains up to 50 channels.+ ApplicationCommandChannelTypeGuildCategory+ | -- | A channel that users can follow and crosspost into their own server.+ ApplicationCommandChannelTypeGuildNews+ | -- | A channel in which game developers can sell their game on discord.+ ApplicationCommandChannelTypeGuildStore+ | -- | A temporary sub-channel within a guild_news channel.+ ApplicationCommandChannelTypeGuildNewsThread+ | -- | 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+ ApplicationCommandChannelTypeGuildPrivateThread+ | -- | A voice channel for hosting events with an audience.+ 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 ToJSON ApplicationCommandChannelType where+ toJSON = toJSON . fromEnum++instance FromJSON ApplicationCommandChannelType where+ parseJSON = withScientific "ApplicationCommandChannelType" (return . toEnum . round)++data GuildApplicationCommandPermissions = GuildApplicationCommandPermissions+ { -- | The id of the command+ guildApplicationCommandPermissionsId :: ApplicationCommandId,+ -- | The id of the application+ guildApplicationCommandPermissionsApplicationId :: ApplicationId,+ -- | The id of the guild+ guildApplicationCommandPermissionsGuildId :: GuildId,+ -- | The permissions for the command in the guild+ guildApplicationCommandPermissionsPermissions :: [ApplicationCommandPermissions]+ }+ deriving (Show, Eq, Ord, Read)++instance FromJSON GuildApplicationCommandPermissions where+ parseJSON =+ withObject+ "GuildApplicationCommandPermissions"+ ( \v ->+ GuildApplicationCommandPermissions+ <$> v .: "id"+ <*> v .: "application_id"+ <*> v .: "guild_id"+ <*> v .: "permissions"+ )++instance ToJSON GuildApplicationCommandPermissions where+ toJSON GuildApplicationCommandPermissions {..} =+ object+ [ (name, value)+ | (name, Just value) <-+ [ ("id", toMaybeJSON guildApplicationCommandPermissionsId),+ ("application_id", toMaybeJSON guildApplicationCommandPermissionsApplicationId),+ ("guild_id", toMaybeJSON guildApplicationCommandPermissionsGuildId),+ ("permissions", toMaybeJSON guildApplicationCommandPermissionsPermissions)+ ]+ ]++data ApplicationCommandPermissions = ApplicationCommandPermissions+ { -- | The id of the role or user+ applicationCommandPermissionsId :: Snowflake,+ -- | Choose either role or user+ applicationCommandPermissionsType :: ApplicationCommandPermissionType,+ -- | Whether to allow or not+ applicationCommandPermissionsPermission :: Bool+ }+ deriving (Show, Eq, Ord, Read)++instance FromJSON ApplicationCommandPermissions where+ parseJSON =+ withObject+ "ApplicationCommandPermissions"+ ( \v ->+ ApplicationCommandPermissions+ <$> v .: "id"+ <*> v .: "type"+ <*> v .: "permission"+ )++instance ToJSON ApplicationCommandPermissions where+ toJSON ApplicationCommandPermissions {..} =+ object+ [ (name, value)+ | (name, Just value) <-+ [ ("id", toMaybeJSON applicationCommandPermissionsId),+ ("type", toMaybeJSON applicationCommandPermissionsType),+ ("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,5 +1,6 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE DeriveDataTypeable #-} -- | Data structures pertaining to Discord Channels module Discord.Internal.Types.Channel where@@ -13,8 +14,12 @@ import qualified Data.Text as T import Discord.Internal.Types.Prelude-import Discord.Internal.Types.User (User(..))+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) -- | Guild channels represent an isolated set of users and messages in a Guild (Server) data Channel@@ -158,6 +163,73 @@ _ -> ChannelUnknownType <$> o .: "id" <*> pure (T.pack (show o)) +instance ToJSON Channel where+ toJSON ChannelText{..} = object [(name,value) | (name, Just value) <-+ [ ("id", toJSON <$> pure channelId)+ , ("guild_id", toJSON <$> pure channelGuild)+ , ("name", toJSON <$> pure channelName)+ , ("position", toJSON <$> pure channelPosition)+ , ("rate_limit_per_user", toJSON <$> pure channelUserRateLimit)+ , ("nsfw", toJSON <$> pure channelNSFW)+ , ("permission_overwrites", toJSON <$> pure channelPermissions)+ , ("topic", toJSON <$> pure channelTopic)+ , ("last_message_id", toJSON <$> channelLastMessage)+ , ("parent_id", toJSON <$> pure channelParentId)+ ] ]+ toJSON ChannelNews{..} = object [(name,value) | (name, Just value) <-+ [ ("id", toJSON <$> pure channelId)+ , ("guild_id", toJSON <$> pure channelGuild)+ , ("name", toJSON <$> pure channelName)+ , ("position", toJSON <$> pure channelPosition)+ , ("permission_overwrites", toJSON <$> pure channelPermissions)+ , ("nsfw", toJSON <$> pure channelNSFW)+ , ("topic", toJSON <$> pure channelTopic)+ , ("last_message_id", toJSON <$> channelLastMessage)+ ] ]+ toJSON ChannelStorePage{..} = object [(name,value) | (name, Just value) <-+ [ ("id", toJSON <$> pure channelId)+ , ("guild_id", toJSON <$> pure channelGuild)+ , ("name", toJSON <$> pure channelName)+ , ("nsfw", toJSON <$> pure channelNSFW)+ , ("position", toJSON <$> pure channelPosition)+ , ("permission_overwrites", toJSON <$> pure channelPermissions)+ ] ]+ toJSON ChannelDirectMessage{..} = object [(name,value) | (name, Just value) <-+ [ ("id", toJSON <$> pure channelId)+ , ("recipients", toJSON <$> pure channelRecipients)+ , ("last_message_id", toJSON <$> channelLastMessage)+ ] ]+ toJSON ChannelVoice{..} = object [(name,value) | (name, Just value) <-+ [ ("id", toJSON <$> pure channelId)+ , ("guild_id", toJSON <$> pure channelGuild)+ , ("name", toJSON <$> pure channelName)+ , ("position", toJSON <$> pure channelPosition)+ , ("nsfw", toJSON <$> pure channelNSFW)+ , ("permission_overwrites", toJSON <$> pure channelPermissions)+ , ("bitrate", toJSON <$> pure channelBitRate)+ , ("user_limit", toJSON <$> pure channelUserLimit)+ ] ]+ toJSON ChannelGroupDM{..} = object [(name,value) | (name, Just value) <-+ [ ("id", toJSON <$> pure channelId)+ , ("recipients", toJSON <$> pure channelRecipients)+ , ("last_message_id", toJSON <$> channelLastMessage)+ ] ]+ toJSON ChannelGuildCategory{..} = object [(name,value) | (name, Just value) <-+ [ ("id", toJSON <$> pure channelId)+ , ("name", toJSON <$> pure channelName)+ , ("guild_id", toJSON <$> pure channelGuild)+ ] ]+ toJSON ChannelStage{..} = object [(name,value) | (name, Just value) <-+ [ ("id", toJSON <$> pure channelId)+ , ("guild_id", toJSON <$> pure channelGuild)+ , ("channel_id", toJSON <$> pure channelStageId)+ , ("topic", toJSON <$> pure channelStageTopic)+ ] ]+ toJSON ChannelUnknownType{..} = object [(name,value) | (name, Just value) <-+ [ ("id", toJSON <$> pure channelId)+ , ("json", toJSON <$> pure channelJSON)+ ] ]+ -- | If the channel is part of a guild (has a guild id field) channelIsInGuild :: Channel -> Bool channelIsInGuild c = case c of@@ -171,9 +243,9 @@ -- | Permission overwrites for a channel. data Overwrite = Overwrite { overwriteId :: OverwriteId -- ^ 'Role' or 'User' id- , overwriteType :: T.Text -- ^ Either "role" or "member- , overwriteAllow :: Integer -- ^ Allowed permission bit set- , overwriteDeny :: Integer -- ^ Denied permission bit set+ , overwriteType :: Integer -- ^ Either role (0) or member (1)+ , overwriteAllow :: T.Text -- ^ Allowed permission bit set+ , overwriteDeny :: T.Text -- ^ Denied permission bit set } deriving (Show, Read, Eq, Ord) instance FromJSON Overwrite where@@ -193,42 +265,55 @@ -- | Represents information about a message in a Discord channel. data Message = Message- { messageId :: MessageId -- ^ The id of the message- , messageChannel :: ChannelId -- ^ Id of the channel the message- -- was sent in- , messageAuthor :: User -- ^ The 'User' the message was sent- -- by- , messageText :: Text -- ^ Contents of the message- , messageTimestamp :: UTCTime -- ^ When the message was sent- , messageEdited :: Maybe UTCTime -- ^ When/if the message was edited- , messageTts :: Bool -- ^ Whether this message was a TTS- -- message- , messageEveryone :: Bool -- ^ Whether this message mentions- -- everyone- , messageMentions :: [User] -- ^ 'User's specifically mentioned in- -- the message- , messageMentionRoles :: [RoleId] -- ^ 'Role's specifically mentioned in- -- the message- , messageAttachments :: [Attachment] -- ^ Any attached files- , messageEmbeds :: [Embed] -- ^ Any embedded content- , messageReactions :: [MessageReaction] -- ^ Any reactions to message- , messageNonce :: Maybe Nonce -- ^ Used for validating if a message- -- was sent- , messagePinned :: Bool -- ^ Whether this message is pinned- , messageGuild :: Maybe GuildId -- ^ The guild the message went to- , messageReference :: Maybe MessageReference -- ^ Reference IDs of the original message- , referencedMessage :: Maybe Message -- ^ The full original message+ { messageId :: MessageId -- ^ The id of the message+ , messageChannelId :: ChannelId -- ^ Id of the channel the message+ -- was sent in+ , messageGuildId :: Maybe GuildId -- ^ The guild the message went to+ , messageAuthor :: User -- ^ The 'User' the message was sent+ -- by+ , messageMember :: Maybe GuildMember -- ^ A partial guild member object+ , messageContent :: Text -- ^ Contents of the message+ , messageTimestamp :: UTCTime -- ^ When the message was sent+ , messageEdited :: Maybe UTCTime -- ^ When/if the message was edited+ , messageTts :: Bool -- ^ Whether this message was a TTS+ -- message+ , messageEveryone :: Bool -- ^ Whether this message mentions+ -- everyone+ , messageMentions :: [User] -- ^ 'User's specifically mentioned in+ -- the message+ , messageMentionRoles :: [RoleId] -- ^ 'Role's specifically mentioned in+ -- the message+ , messageAttachments :: [Attachment] -- ^ Any attached files+ , messageEmbeds :: [Embed] -- ^ Any embedded content+ , messageReactions :: [MessageReaction] -- ^ Any reactions to message+ , messageNonce :: Maybe Nonce -- ^ Used for validating if a message+ -- was sent+ , messagePinned :: Bool -- ^ Whether this message is pinned+ , 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) instance FromJSON Message where parseJSON = withObject "Message" $ \o -> Message <$> o .: "id" <*> o .: "channel_id"+ <*> o .:? "guild_id" .!= Nothing <*> (do isW <- o .:? "webhook_id" a <- o .: "author" case isW :: Maybe WebhookId of Nothing -> pure a Just _ -> pure $ a { userIsWebhook = True })+ <*> o .:? "member" <*> o .:? "content" .!= "" <*> o .:? "timestamp" .!= epochTime <*> o .:? "edited_timestamp"@@ -241,11 +326,84 @@ <*> o .:? "reactions" .!= [] <*> o .:? "nonce" <*> o .:? "pinned" .!= False- <*> o .:? "guild_id" .!= Nothing+ <*> o .:? "webhook_id"+ <*> o .: "type"+ <*> o .:? "activity"+ -- <*> o .:? "application"+ <*> o .:? "application_id" <*> o .:? "message_reference" .!= Nothing+ <*> o .:? "flags" <*> o .:? "referenced_message" .!= Nothing+ <*> o .:? "interaction"+ <*> o .:? "thread"+ <*> o .:? "components"+ <*> o .:? "sticker_items" +instance ToJSON Message where+ toJSON Message {..} = object [(name, value) | (name, Just value) <-+ [ ("id", toJSON <$> pure messageId)+ , ("channel_id", toJSON <$> pure messageChannelId)+ , ("guild_id", toJSON <$> messageGuildId)+ , ("author", toJSON <$> pure messageAuthor)+ , ("member", toJSON <$> messageMember)+ , ("content", toJSON <$> pure messageContent)+ , ("timestamp", toJSON <$> pure messageTimestamp)+ , ("edited_timestamp", toJSON <$> messageEdited)+ , ("tts", toJSON <$> pure messageTts)+ , ("mention_everyone", toJSON <$> pure messageEveryone)+ , ("mentions", toJSON <$> pure messageMentions)+ , ("mention_roles", toJSON <$> pure messageMentionRoles)+ , ("attachments", toJSON <$> pure messageAttachments)+ , ("embeds", toJSON <$> pure messageEmbeds)+ , ("reactions", toJSON <$> pure messageReactions)+ , ("nonce", toJSON <$> messageNonce)+ , ("pinned", toJSON <$> pure messagePinned)+ , ("webhook_id", toJSON <$> messageWebhookId)+ , ("type", toJSON <$> pure messageType)+ , ("activity", toJSON <$> messageActivity)+ -- , ("application", toJSON <$> messageApplication)+ , ("application_id", toJSON <$> messageApplicationId)+ , ("message_reference", toJSON <$> messageReference)+ , ("flags", toJSON <$> messageFlags)+ , ("referenced_message", toJSON <$> messageReferencedMessage)+ , ("interaction", toJSON <$> messageInteraction)+ , ("thread", toJSON <$> messageThread)+ , ("components", toJSON <$> messageComponents)+ , ("sticker_items", toJSON <$> messageStickerItems)+ ] ]++-- | Data constructor for a part of MessageDetailedOpts.+data AllowedMentions = AllowedMentions+ { mentionEveryone :: Bool+ , mentionUsers :: Bool+ , mentionRoles :: Bool+ , mentionUserIds :: [UserId]+ , mentionRoleIds :: [RoleId]+ , mentionRepliedUser :: Bool+ } deriving (Show, Read, Eq, Ord)++instance Default AllowedMentions where+ def = AllowedMentions { mentionEveryone = False+ , mentionUsers = True+ , mentionRoles = True+ , mentionUserIds = []+ , mentionRoleIds = []+ , mentionRepliedUser = True+ }++instance ToJSON AllowedMentions where+ toJSON AllowedMentions{..} = object [+ ("parse" .= [name :: T.Text | (name, True) <-+ [ ("everyone", mentionEveryone),+ ("users", mentionUsers && mentionUserIds == []),+ ("roles", mentionRoles && mentionRoleIds == []) ] ]),+ -- https://discord.com/developers/docs/resources/channel#allowed-mentions-object+ -- parse.users and users list cannot both be active, prioritize id list+ ("roles" .= mentionRoleIds),+ ("users" .= mentionUserIds),+ ("replied_user" .= mentionRepliedUser) ]+ data MessageReaction = MessageReaction { messageReactionCount :: Int , messageReactionMeIncluded :: Bool@@ -258,29 +416,56 @@ <*> o .: "me" <*> o .: "emoji" --- | Represents an emoticon (emoji)-data Emoji = Emoji- { emojiId :: Maybe EmojiId -- ^ The emoji id- , emojiName :: T.Text -- ^ The emoji name- , emojiRoles :: Maybe [RoleId] -- ^ Roles the emoji is active for- , emojiUser :: Maybe User -- ^ User that created this emoji- , emojiManaged :: Maybe Bool -- ^ Whether this emoji is managed- , emojiAnimated :: Maybe Bool -- ^ Whether this emoji is animated- } deriving (Show, Read, Eq, Ord)+instance ToJSON MessageReaction where+ toJSON MessageReaction{..} = object [(name, value) | (name, Just value) <-+ [ ("count", toJSON <$> pure messageReactionCount)+ , ("me", toJSON <$> pure messageReactionMeIncluded)+ , ("emoji", toJSON <$> pure messageReactionEmoji)+ ]] -instance FromJSON Emoji where- parseJSON = withObject "Emoji" $ \o ->- Emoji <$> o .: "id"- <*> o .: "name"- <*> o .:? "roles"- <*> o .:? "user"- <*> o .:? "managed"- <*> o .:? "animated"+-- TODO: expand stickers and have full objects+data StickerItem = StickerItem+ { stickerItemId :: StickerId+ , stickerItemName :: T.Text+ , stickerItemFormatType :: StickerFormatType+ } deriving (Show, Read, Eq, Ord) +instance FromJSON StickerItem where+ parseJSON = withObject "StickerItem" $ \o ->+ StickerItem <$> o .: "id"+ <*> o .: "name"+ <*> o .: "format_type" +instance ToJSON StickerItem where+ toJSON StickerItem{..} = object [(name, value) | (name, Just value) <-+ [ ("id", toJSON <$> pure stickerItemId)+ , ("name", toJSON <$> pure stickerItemName)+ , ("format_type", toJSON <$> pure stickerItemFormatType)+ ]]++data StickerFormatType =+ StickerFormatTypePNG+ | StickerFormatTypeAPNG+ | 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 ToJSON StickerFormatType where+ toJSON = toJSON . fromEnum++instance FromJSON StickerFormatType where+ parseJSON = withScientific "StickerFormatType" (return . toEnum . round)+ -- | Represents an attached to a message file. data Attachment = Attachment- { attachmentId :: Snowflake -- ^ Attachment id+ { attachmentId :: AttachmentId -- ^ Attachment id , attachmentFilename :: T.Text -- ^ Name of attached file , attachmentSize :: Integer -- ^ Size of file (in bytes) , attachmentUrl :: T.Text -- ^ Source of file@@ -299,7 +484,16 @@ <*> o .:? "height" <*> o .:? "width" -+instance ToJSON Attachment where+ toJSON Attachment {..} = object [(name, value) | (name, Just value) <-+ [ ("id", toJSON <$> pure attachmentId)+ , ("filename", toJSON <$> pure attachmentFilename)+ , ("size", toJSON <$> pure attachmentSize)+ , ("url", toJSON <$> pure attachmentUrl)+ , ("proxy_url", toJSON <$> pure attachmentProxy)+ , ("height", toJSON <$> attachmentHeight)+ , ("width", toJSON <$> attachmentWidth)+ ] ] newtype Nonce = Nonce T.Text deriving (Show, Read, Eq, Ord)@@ -309,7 +503,10 @@ parseJSON (Number nonce) = pure . Nonce . T.pack . show $ nonce parseJSON _ = empty +instance ToJSON Nonce where+ toJSON (Nonce t) = String t + -- | Represents a Message Reference data MessageReference = MessageReference { referenceMessageId :: Maybe MessageId -- ^ id of the originating message@@ -339,3 +536,166 @@ , referenceGuildId = Nothing , failIfNotExists = False }+++data MessageType+ = MessageTypeDefault + | MessageTypeRecipientAdd + | MessageTypeRecipientRemove + | MessageTypeCall+ | MessageTypeChannelNameChange+ | MessageTypeChannelIconChange+ | MessageTypeChannelPinnedMessage+ | MessageTypeGuildMemberJoin+ | MessageTypeUserPremiumGuildSubscription+ | MessageTypeUserPremiumGuildSubscriptionTier1+ | MessageTypeUserPremiumGuildSubscriptionTier2+ | MessageTypeUserPremiumGuildSubscriptionTier3+ | MessageTypeChannelFollowAdd+ | MessageTypeGuildDiscoveryDisqualified+ | MessageTypeGuildDiscoveryRequalified+ | MessageTypeGuildDiscoveryGracePeriodInitialWarning+ | MessageTypeGuildDiscoveryGracePeriodFinalWarning+ | MessageTypeThreadCreated+ | MessageTypeReply+ | MessageTypeChatInputCommand+ | MessageTypeThreadStarterMessage+ | MessageTypeGuildInviteReminder+ | 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 ToJSON MessageType where+ toJSON = toJSON . fromEnum++instance FromJSON MessageType where+ parseJSON = withScientific "MessageType" (return . toEnum . round)++data MessageActivity = MessageActivity+ { messageActivityType :: MessageActivityType+ , messageActivityPartyId :: Maybe T.Text+ }+ deriving (Show, Read, Data, Eq, Ord)++instance FromJSON MessageActivity where+ parseJSON = withObject "MessageActivity" $ \o ->+ MessageActivity <$> o .: "type"+ <*> o .:? "party_id"++instance ToJSON MessageActivity where+ toJSON MessageActivity{..} = object [(name,value) | (name, Just value) <-+ [ ("type", toJSON <$> pure messageActivityType)+ , ("party_id", toJSON <$> messageActivityPartyId)+ ] ]++data MessageActivityType+ = MessageActivityTypeJoin -- ^ Join a Rich Presence event+ | MessageActivityTypeSpectate -- ^ Spectate a Rich Presence event+ | MessageActivityTypeListen -- ^ Listen to a Rich Presence event+ | 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 ToJSON MessageActivityType where+ toJSON = toJSON . fromEnum++instance FromJSON MessageActivityType where+ parseJSON = withScientific "MessageActivityType" (return . toEnum . round)++-- | Types of flags to attach to the message.+data MessageFlag = + MessageFlagCrossposted+ | MessageFlagIsCrosspost+ | MessageFlagSupressEmbeds+ | MessageFlagSourceMessageDeleted+ | MessageFlagUrgent+ | MessageFlagHasThread+ | MessageFlagEphemeral+ | MessageFlagLoading+ deriving (Show, Read, Eq, Data, Ord)++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 ToJSON MessageFlags where+ toJSON (MessageFlags fs) = Number $ fromInteger $ fromIntegral $ foldr (.|.) 0 (fromEnum <$> 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++data MessageInteraction = MessageInteraction+ { messageInteractionId :: InteractionId+ , messageInteractionType :: InteractionType+ , messageInteractionName :: T.Text+ , messageInteractionUser :: User+ } deriving (Show, Eq, Ord, Read)++instance ToJSON MessageInteraction where+ toJSON MessageInteraction{..} = object [(name,value) | (name, Just value) <-+ [ ("id", toJSON <$> pure messageInteractionId)+ , ("type", toJSON <$> pure messageInteractionType)+ , ("name", toJSON <$> pure messageInteractionName)+ , ("user", toJSON <$> pure messageInteractionUser)+ ] ]+++instance FromJSON MessageInteraction where+ parseJSON = withObject "MessageInteraction" $ \o ->+ MessageInteraction <$> o .: "id"+ <*> o .: "type"+ <*> o .: "name"+ <*> o .: "user"+
+ src/Discord/Internal/Types/Components.hs view
@@ -0,0 +1,296 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}++module Discord.Internal.Types.Components where++import Data.Aeson+import Data.Data (Data)+import Data.Maybe (fromJust, fromMaybe)+import qualified Data.Text as T+import Data.Tuple (swap)+import Discord.Internal.Types.Prelude (EmojiId, Internals (..), RoleId, makeTable, toMaybeJSON)+import Discord.Internal.Types.User (User)+import qualified Network.HTTP.Req as R++-- | 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,+ componentButtonDisabled :: Bool,+ componentButtonStyle :: ButtonStyle,+ componentButtonLabel :: T.Text,+ componentButtonEmoji :: Maybe Emoji+ }+ | ComponentButtonUrl+ { componentButtonUrl :: R.Url 'R.Https,+ componentButtonDisabled :: Bool,+ componentButtonLabel :: T.Text,+ componentButtonEmoji :: Maybe Emoji+ }+ deriving (Show, Eq)++data ButtonStyle = ButtonStylePrimary | ButtonStyleSecondary | ButtonStyleSuccess | ButtonStyleDanger+ deriving (Show, Eq, Read)++buttonStyles :: [(ButtonStyle, InternalButtonStyle)]+buttonStyles =+ [ (ButtonStylePrimary, InternalButtonStylePrimary),+ (ButtonStyleSecondary, InternalButtonStyleSecondary),+ (ButtonStyleSuccess, InternalButtonStyleSuccess),+ (ButtonStyleDanger, InternalButtonStyleDanger)+ ]++instance Internals ButtonStyle InternalButtonStyle where+ toInternal a = fromJust (lookup a buttonStyles)+ fromInternal b = lookup b (swap <$> buttonStyles)++-- | 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,+ componentSelectMenuDisabled :: Bool,+ componentSelectMenuOptions :: [SelectOption],+ componentSelectMenuPlaceholder :: Maybe T.Text,+ componentSelectMenuMinValues :: Maybe Integer,+ componentSelectMenuMaxValues :: Maybe Integer+ }+ deriving (Show, Eq, Read)++data ComponentActionRow = ComponentActionRowButton [ComponentButton] | ComponentActionRowSelectMenu ComponentSelectMenu+ deriving (Show, Eq)++validPartialEmoji :: Emoji -> Maybe Emoji+validPartialEmoji Emoji {..} = do+ eid <- emojiId+ ean <- emojiAnimated+ return $ Emoji (Just eid) emojiName Nothing Nothing Nothing (Just ean)++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])++ 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++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]+ }+ 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"+ <*> o .:? "emoji"+ <*> o .:? "url"+ <*> o .:? "options"+ <*> o .:? "placeholder"+ <*> o .:? "min_values"+ <*> o .:? "max_values"+ <*> o .:? "components"++instance ToJSON Component where+ toJSON Component {..} =+ 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)+ ]+ ]++-- | 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+ emojiId :: Maybe EmojiId,+ -- | The emoji name+ emojiName :: T.Text,+ -- | Roles the emoji is active for+ emojiRoles :: Maybe [RoleId],+ -- | User that created this emoji+ emojiUser :: Maybe User,+ -- | Whether this emoji is managed+ emojiManaged :: Maybe Bool,+ -- | Whether this emoji is animated+ emojiAnimated :: Maybe Bool+ }+ deriving (Show, Read, Eq, Ord)++instance FromJSON Emoji where+ parseJSON = withObject "Emoji" $ \o ->+ Emoji <$> o .:? "id"+ <*> o .: "name"+ <*> o .:? "roles"+ <*> o .:? "user"+ <*> o .:? "managed"+ <*> o .:? "animated"++instance ToJSON Emoji where+ toJSON Emoji {..} =+ object+ [ (name, value)+ | (name, Just value) <-+ [ ("id", toJSON <$> emojiId),+ ("name", toMaybeJSON emojiName),+ ("roles", toJSON <$> emojiRoles),+ ("user", toJSON <$> emojiUser),+ ("managed", toJSON <$> emojiManaged),+ ("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/Events.hs view
@@ -15,13 +15,15 @@ import Discord.Internal.Types.Prelude import Discord.Internal.Types.Channel-import Discord.Internal.Types.Guild-import Discord.Internal.Types.User (User)+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.Components (Emoji) -- | Represents possible events sent by discord. Detailed information can be found at https://discord.com/developers/docs/topics/gateway. data Event =- Ready Int User [Channel] [GuildUnavailable] T.Text+ Ready Int User [Channel] [GuildUnavailable] T.Text (Maybe Shard) PartialApplication | Resumed [T.Text] | ChannelCreate Channel | ChannelUpdate Channel@@ -52,13 +54,14 @@ | PresenceUpdate PresenceInfo | TypingStart TypingInfo | UserUpdate User+ | InteractionCreate Interaction -- | VoiceStateUpdate -- | VoiceServerUpdate | UnknownEvent T.Text Object deriving (Show, Read, Eq) data EventInternalParse =- InternalReady Int User [Channel] [GuildUnavailable] T.Text+ InternalReady Int User [Channel] [GuildUnavailable] T.Text (Maybe Shard) PartialApplication | InternalResumed [T.Text] | InternalChannelCreate Channel | InternalChannelUpdate Channel@@ -89,11 +92,20 @@ | InternalPresenceUpdate PresenceInfo | InternalTypingStart TypingInfo | InternalUserUpdate User+ | InternalInteractionCreate InternalInteraction -- | InternalVoiceStateUpdate -- | InternalVoiceServerUpdate | InternalUnknownEvent T.Text Object deriving (Show, Read, Eq) +data PartialApplication = PartialApplication+ { partialApplicationID :: ApplicationId+ , partialApplicationFlags :: Int+ } deriving (Show, Eq, Read)++instance FromJSON PartialApplication where+ parseJSON = withObject "PartialApplication" (\v -> PartialApplication <$> v .: "id" <*> v .: "flags")+ data ReactionInfo = ReactionInfo { reactionUserId :: UserId , reactionGuildId :: Maybe GuildId@@ -169,6 +181,8 @@ <*> o .: "private_channels" <*> o .: "guilds" <*> o .: "session_id"+ <*> o .: "shard"+ <*> o .: "application" "RESUMED" -> InternalResumed <$> o .: "_trace" "CHANNEL_CREATE" -> InternalChannelCreate <$> reparse o "CHANNEL_UPDATE" -> InternalChannelUpdate <$> reparse o@@ -202,10 +216,11 @@ "MESSAGE_REACTION_REMOVE" -> InternalMessageReactionRemove <$> reparse o "MESSAGE_REACTION_REMOVE_ALL" -> InternalMessageReactionRemoveAll <$> o .: "channel_id" <*> o .: "message_id"- "MESSAGE_REACTION_REMOVE_EMOJI"-> InternalMessageReactionRemoveEmoji <$> reparse o+ "MESSAGE_REACTION_REMOVE_EMOJI" -> InternalMessageReactionRemoveEmoji <$> reparse o "PRESENCE_UPDATE" -> InternalPresenceUpdate <$> reparse o "TYPING_START" -> InternalTypingStart <$> reparse o "USER_UPDATE" -> InternalUserUpdate <$> reparse o -- "VOICE_STATE_UPDATE" -> InternalVoiceStateUpdate <$> reparse o -- "VOICE_SERVER_UPDATE" -> InternalVoiceServerUpdate <$> reparse o+ "INTERACTION_CREATE" -> InternalInteractionCreate <$> reparse o _other_event -> InternalUnknownEvent t <$> reparse o
src/Discord/Internal/Types/Guild.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-} -- | Types relating to Discord Guilds (servers) module Discord.Internal.Types.Guild where@@ -9,45 +10,28 @@ import qualified Data.Text as T import Discord.Internal.Types.Prelude-import Discord.Internal.Types.Channel (Channel, Emoji)-import Discord.Internal.Types.User (User)+import Discord.Internal.Types.Channel (Channel)+import Discord.Internal.Types.User (User, GuildMember)+import Discord.Internal.Types.Components (Emoji) --- | Representation of a guild member.-data GuildMember = GuildMember- { memberUser :: User- , memberNick :: Maybe T.Text- , memberRoles :: [Snowflake]- , memberJoinedAt :: UTCTime- , memberDeaf :: Bool- , memberMute :: Bool- } deriving (Show, Read, Eq, Ord) -instance FromJSON GuildMember where- parseJSON = withObject "GuildMember" $ \o ->- GuildMember <$> o .: "user"- <*> o .:? "nick"- <*> o .: "roles"- <*> o .: "joined_at"- <*> o .: "deaf"- <*> o .: "mute" ---- https://discord.com/developers/docs/resources/guild#guild-object- -- | Guilds in Discord represent a collection of users and channels into an isolated -- "Server"+--+-- https://discord.com/developers/docs/resources/guild#guild-object data Guild = Guild { guildId :: GuildId -- ^ Gulid id , guildName :: T.Text -- ^ Guild name (2 - 100 chars) , guildIcon :: Maybe T.Text -- ^ Icon hash , guildSplash :: Maybe T.Text -- ^ Splash hash , guildOwnerId :: UserId -- ^ Guild owner id- , guildPermissions :: Maybe Integer+ , guildPermissions :: Maybe T.Text , guildRegion :: Maybe T.Text -- ^ Guild voice region , guildAfkId :: Maybe ChannelId -- ^ Id of afk channel , guildAfkTimeout :: Integer -- ^ Afk timeout in seconds- , guildEmbedEnabled :: Maybe Bool -- ^ Id of embedded channel- , guildEmbedChannel :: Maybe ChannelId -- ^ Id of embedded channel+ , guildWidgetEnabled :: Maybe Bool -- ^ Id of embedded channel+ , guildWidgetChannelId :: Maybe ChannelId -- ^ Id of embedded channel , guildVerificationLevel :: Integer -- ^ Level of verification , guildNotification :: Integer -- ^ Level of default notifications , guildExplicitFilterLevel :: Integer@@ -69,8 +53,8 @@ <*> o .:? "region" <*> o .:? "afk_channel_id" <*> o .: "afk_timeout"- <*> o .:? "embed_enabled"- <*> o .:? "embed_channel_id"+ <*> o .:? "widget_enabled"+ <*> o .:? "widget_channel_id" <*> o .: "verification_level" <*> o .: "default_message_notifications" <*> o .: "explicit_content_filter"@@ -112,7 +96,7 @@ , partialGuildName :: T.Text , partialGuildIcon :: Maybe T.Text , partialGuildOwner :: Bool- , partialGuildPermissions :: Integer+ , partialGuildPermissions :: T.Text } deriving (Show, Read, Eq, Ord) instance FromJSON PartialGuild where@@ -135,7 +119,7 @@ , roleColor :: ColorInteger -- ^ Integer representation of color code , roleHoist :: Bool -- ^ If the role is pinned in the user listing , rolePos :: Integer -- ^ Position of this role- , rolePerms :: Integer -- ^ 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)@@ -261,17 +245,17 @@ IntegrationAccount <$> o .: "id" <*> o .: "name" -- | Represents an image to be used in third party sites to link to a discord channel-data GuildEmbed = GuildEmbed- { embedEnabled :: Bool -- ^ Whether the embed is enabled- , embedChannel :: ChannelId -- ^ The embed channel id+data GuildWidget = GuildWidget+ { widgetEnabled :: Bool -- ^ Whether the widget is enabled+ , widgetChannelId :: ChannelId -- ^ The widget channel id } deriving (Show, Read, Eq, Ord) -instance FromJSON GuildEmbed where- parseJSON = withObject "GuildEmbed" $ \o ->- GuildEmbed <$> o .: "enabled" <*> o .: "snowflake"+instance FromJSON GuildWidget where+ parseJSON = withObject "GuildWidget" $ \o ->+ GuildWidget <$> o .: "enabled" <*> o .: "channel_id" -instance ToJSON GuildEmbed where- toJSON (GuildEmbed enabled snowflake) = object+instance ToJSON GuildWidget where+ toJSON (GuildWidget enabled snowflake) = object [ "enabled" .= enabled- , "snowflake" .= snowflake+ , "channel_id" .= snowflake ]
+ src/Discord/Internal/Types/Interactions.hs view
@@ -0,0 +1,614 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}++module Discord.Internal.Types.Interactions+ ( Interaction (..),+ InteractionDataComponent (..),+ InteractionDataApplicationCommand (..),+ InteractionDataApplicationCommandOptions (..),+ InteractionDataApplicationCommandOptionSubcommandOrGroup (..),+ InteractionDataApplicationCommandOptionSubcommand (..),+ InteractionDataApplicationCommandOptionValue (..),+ ApplicationCommandInteractionDataValue (..),+ InternalInteraction (..),+ InteractionToken,+ InteractionType,+ InternalInteractionData (..),+ ResolvedData (..),+ InternalInteractionDataApplicationCommandOption (..),+ InteractionResponse (..),+ interactionResponseBasic,+ InteractionCallbackType (..),+ InteractionCallbackData (..),+ InteractionCallbackAutocomplete,+ InteractionCallbackMessages (..),+ interactionCallbackMessagesBasic,+ InteractionCallbackDataFlags (..),+ InteractionCallbackDataFlag (..),+ )+where++import Control.Applicative (Alternative ((<|>)))+import Data.Aeson+import Data.Aeson.Types (Parser)+import Data.Bits (Bits (shift, (.|.)))+import Data.Data (Data)+import Data.Maybe (fromJust, fromMaybe)+import Data.Scientific (Scientific)+import qualified Data.Text as T+import Discord.Internal.Types.ApplicationCommands+ (+ InternalApplicationCommandOptionChoice,+ ApplicationCommandOptionType (..),+ ApplicationCommandType (..),+ )+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.User (GuildMember, User)++import Debug.Trace++data Interaction+ = InteractionComponent+ { interactionId :: InteractionId,+ interactionApplicationId :: ApplicationId,+ interactionDataComponent :: Maybe InteractionDataComponent, -- referenced as Data in API+ interactionGuildId :: Maybe GuildId,+ interactionChannelId :: Maybe ChannelId,+ interactionMember :: Maybe GuildMember,+ interactionUser :: Maybe User,+ interactionToken :: InteractionToken,+ interactionVersion :: Int,+ interactionMessage :: Message+ }+ | InteractionPing+ { interactionId :: InteractionId,+ interactionApplicationId :: ApplicationId,+ interactionToken :: InteractionToken,+ interactionVersion :: Int+ }+ | InteractionApplicationCommand+ { interactionId :: InteractionId,+ interactionApplicationId :: ApplicationId,+ interactionDataApplicationCommand :: Maybe InteractionDataApplicationCommand, -- referenced as Data in API+ interactionGuildId :: Maybe GuildId,+ interactionChannelId :: Maybe ChannelId,+ interactionMember :: Maybe GuildMember,+ interactionUser :: Maybe User,+ interactionToken :: InteractionToken,+ interactionVersion :: Int+ }+ | InteractionApplicationCommandAutocomplete+ { interactionId :: InteractionId,+ interactionApplicationId :: ApplicationId,+ interactionDataApplicationCommand :: Maybe InteractionDataApplicationCommand, -- referenced as Data in API+ interactionGuildId :: Maybe GuildId,+ interactionChannelId :: Maybe ChannelId,+ interactionMember :: Maybe GuildMember,+ interactionUser :: Maybe User,+ interactionToken :: InteractionToken,+ interactionVersion :: Int+ }+ | InteractionUnknown InternalInteraction+ deriving (Show, Read, Eq)++data InteractionDataComponent+ = InteractionDataComponentButton+ { -- | Component only, the unique id+ interactionDataComponentCustomId :: T.Text+ }+ | InteractionDataComponentSelectMenu+ { interactionDataComponentCustomId :: T.Text,+ interactionDataComponentValues :: [T.Text]+ }+ deriving (Show, Read, Eq)++data InteractionDataApplicationCommand+ = InteractionDataApplicationCommandUser+ { -- | id of the invoked command+ interactionDataApplicationCommandId :: ApplicationCommandId,+ -- | name of the invoked command+ interactionDataApplicationCommandName :: T.Text,+ -- | the resolved data in the command+ interactionDataApplicationCommandResolvedData :: Maybe ResolvedData,+ -- | the target of the command+ interactionDataApplicationCommandTargetId :: UserId+ }+ | InteractionDataApplicationCommandMessage+ { -- | Application command only, id of the invoked command+ interactionDataApplicationCommandId :: ApplicationCommandId,+ -- | Application command only, name of the invoked command+ interactionDataApplicationCommandName :: T.Text,+ interactionDataApplicationCommandResolvedData :: Maybe ResolvedData,+ interactionDataApplicationCommandTargetId :: MessageId+ }+ | InteractionDataApplicationCommandChatInput+ { -- | Application command only, id of the invoked command+ interactionDataApplicationCommandId :: ApplicationCommandId,+ -- | Application command only, name of the invoked command+ interactionDataApplicationCommandName :: T.Text,+ interactionDataApplicationCommandResolvedData :: Maybe ResolvedData,+ interactionDataApplicationCommandOptions :: Maybe InteractionDataApplicationCommandOptions+ }+ deriving (Show, Read, Eq)++data InteractionDataApplicationCommandOptions+ = InteractionDataApplicationCommandOptionsSubcommands [InteractionDataApplicationCommandOptionSubcommandOrGroup]+ | InteractionDataApplicationCommandOptionsValues [InteractionDataApplicationCommandOptionValue]+ deriving (Show, Read, Eq)++data InteractionDataApplicationCommandOptionSubcommandOrGroup+ = InteractionDataApplicationCommandOptionSubcommandGroup+ { interactionDataApplicationCommandOptionSubcommandGroupName :: T.Text,+ interactionDataApplicationCommandOptionSubcommandGroupOptions :: [InteractionDataApplicationCommandOptionSubcommand],+ interactionDataApplicationCommandOptionSubcommandGroupFocused :: Maybe Bool+ }+ | InteractionDataApplicationCommandOptionSubcommandOrGroupSubcommand InteractionDataApplicationCommandOptionSubcommand+ deriving (Show, Read, Eq)++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+ }+ 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+ 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"+ )++-- | 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+ }+ 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+ 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"+ )++-- | 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.+-- If you need to extract from these values, check out the link below.+--+-- https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-resolved-data-structure+data ResolvedData = ResolvedData+ { resolvedDataUsers :: Maybe Value,+ resolvedDataMembers :: Maybe Value,+ resolvedDataRoles :: Maybe Value,+ resolvedDataChannels :: Maybe Value+ }+ deriving (Show, Read, Eq)++instance ToJSON ResolvedData where+ toJSON ResolvedData {..} =+ object+ [ (name, value)+ | (name, Just value) <-+ [ ("users", resolvedDataUsers),+ ("members", resolvedDataMembers),+ ("roles", resolvedDataRoles),+ ("channels", resolvedDataChannels)+ ]+ ]++instance FromJSON ResolvedData where+ parseJSON =+ withObject+ "ResolvedData"+ ( \v ->+ ResolvedData+ <$> v .:? "users"+ <*> v .:? "members"+ <*> v .:? "roles"+ <*> 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)++interactionResponseBasic :: T.Text -> InteractionResponse+interactionResponseBasic t = InteractionResponse InteractionCallbackTypeChannelMessageWithSource (Just . InteractionCallbackDataMessages $ interactionCallbackMessagesBasic 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)++instance ToJSON InteractionCallbackData where+ toJSON (InteractionCallbackDataMessages icdm) = toJSON icdm+ toJSON (InteractionCallbackDataAutocomplete icda) = toJSON icda++type InteractionCallbackAutocomplete = [InternalApplicationCommandOptionChoice]++-- | 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]+ }+ deriving (Show, Read, Eq)++interactionCallbackMessagesBasic :: T.Text -> InteractionCallbackMessages+interactionCallbackMessagesBasic t = InteractionCallbackMessages Nothing (Just t) Nothing Nothing Nothing Nothing Nothing++instance ToJSON InteractionCallbackMessages where+ toJSON InteractionCallbackMessages {..} =+ 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)+ ]+ ]++-- | Types of flags to attach to the interaction message.+--+-- Currently the only flag is EPHERMERAL, which means only the user can see the+-- message.+data InteractionCallbackDataFlag = InteractionCallbackDataFlagEphermeral+ deriving (Show, Read, Eq)++newtype InteractionCallbackDataFlags = InteractionCallbackDataFlags [InteractionCallbackDataFlag]+ deriving (Show, Read, Eq)++instance Enum InteractionCallbackDataFlag where+ fromEnum InteractionCallbackDataFlagEphermeral = 1 `shift` 6+ toEnum i+ | i == 1 `shift` 6 = InteractionCallbackDataFlagEphermeral+ | 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
src/Discord/Internal/Types/Prelude.hs view
@@ -1,5 +1,8 @@+{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances #-} -- | Provides base types and utility functions needed for modules in Discord.Internal.Types module Discord.Internal.Types.Prelude where@@ -15,6 +18,9 @@ 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@@ -41,20 +47,29 @@ toJSON (Snowflake snowflake) = String . T.pack $ show snowflake instance FromJSON Snowflake where- parseJSON (String snowflake) = pure . read $ T.unpack snowflake+ parseJSON (String snowflake) = case readMaybe (T.unpack snowflake) of+ Nothing -> fail "null snowflake"+ (Just i) -> pure i parseJSON _ = mzero type ChannelId = Snowflake type StageId = Snowflake type GuildId = Snowflake type MessageId = Snowflake+type AttachmentId = Snowflake type EmojiId = Snowflake+type StickerId = Snowflake type UserId = Snowflake type OverwriteId = Snowflake type RoleId = Snowflake type IntegrationId = Snowflake type WebhookId = Snowflake type ParentId = Snowflake+type ApplicationId = Snowflake +type ApplicationCommandId = Snowflake+type InteractionId = Snowflake+type InteractionToken = T.Text+type Shard = (Int, Int) -- | Gets a creation date from a snowflake. snowflakeCreationDate :: Snowflake -> UTCTime@@ -66,3 +81,41 @@ 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++-- | 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)++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++instance ToJSON InteractionType where+ toJSON = toJSON . fromEnum++instance FromJSON InteractionType where+ parseJSON = withScientific "InteractionType" (return . toEnum . round)++class Internals a b where+ toInternal :: a -> b+ fromInternal :: b -> Maybe a++instance Internals a a where+ toInternal = id+ fromInternal = Just
src/Discord/Internal/Types/User.hs view
@@ -8,55 +8,79 @@ import Data.Text (Text) import qualified Data.Text as T import Discord.Internal.Types.Prelude+import Data.Time (UTCTime) -- | Represents information about a user. data User = User- { userId :: UserId -- ^ The user's id.- , userName :: T.Text -- ^ The user's username (not unique)- , userDiscrim :: T.Text -- ^ The user's 4-digit discord-tag.- , userAvatar :: Maybe T.Text -- ^ The user's avatar hash.- , userIsBot :: Bool -- ^ User is an OAuth2 application.- , userIsWebhook:: Bool -- ^ User is a webhook- , userMfa :: Maybe Bool -- ^ User has two factor authentication enabled on the account.- , userVerified :: Maybe Bool -- ^ Whether the email has been verified.- , userEmail :: Maybe T.Text -- ^ The user's email.+ { userId :: UserId -- ^ The user's id.+ , userName :: T.Text -- ^ The user's username (not unique)+ , userDiscrim :: Maybe T.Text -- ^ The user's 4-digit discord-tag.+ , userAvatar :: Maybe T.Text -- ^ The user's avatar hash.+ , userIsBot :: Bool -- ^ User is an OAuth2 application.+ , userIsWebhook :: Bool -- ^ User is a webhook.+ , userIsSystem :: Maybe Bool -- ^ User is an official discord system user.+ , userMfa :: Maybe Bool -- ^ User has two factor authentication enabled on the account.+ , userBanner :: Maybe T.Text -- ^ User's banner hash+ , userAccentColor :: Maybe Int -- ^ User's banner color+ , userLocale :: Maybe T.Text -- ^ User's chosen language+ , userVerified :: Maybe Bool -- ^ Whether the email has been verified.+ , userEmail :: Maybe T.Text -- ^ The user's email.+ , userFlags :: Maybe Integer -- ^ The user's flags.+ , userPremiumType :: Maybe Integer -- ^ The user's premium type.+ , userPublicFlags :: Maybe Integer -- ^ The user's public flags.+ , userMember :: Maybe GuildMember -- ^ Some guild member info (message create/update) } deriving (Show, Read, Eq, Ord) instance FromJSON User where parseJSON = withObject "User" $ \o -> User <$> o .: "id" <*> o .: "username"- <*> o .: "discriminator"+ <*> o .:? "discriminator" -- possibly not there in the case of webhooks <*> o .:? "avatar" <*> o .:? "bot" .!= False <*> pure False -- webhook+ <*> o .:? "system" <*> o .:? "mfa_enabled"+ <*> o .:? "banner"+ <*> o .:? "accent_color"+ <*> o .:? "locale" <*> o .:? "verified" <*> o .:? "email"+ <*> o .:? "flags"+ <*> o .:? "premium_type"+ <*> o .:? "public_flags"+ <*> o .:? "member" instance ToJSON User where toJSON User{..} = object [(name,value) | (name, Just value) <- [ ("id", toJSON <$> pure userId) , ("username", toJSON <$> pure userName)- , ("discriminator", toJSON <$> pure userDiscrim)+ , ("discriminator", toJSON <$> userDiscrim) , ("avatar", toJSON <$> userAvatar) , ("bot", toJSON <$> pure userIsBot)- , ("webhook", toJSON <$> pure userIsWebhook)+ , ("system", toJSON <$> userIsSystem) , ("mfa_enabled", toJSON <$> userMfa)+ , ("banner", toJSON <$> userBanner)+ , ("accent_color", toJSON <$> userAccentColor) , ("verified", toJSON <$> userVerified) , ("email", toJSON <$> userEmail)+ , ("flags", toJSON <$> userFlags)+ , ("premium_type", toJSON <$> userPremiumType)+ , ("public_flags", toJSON <$> userPublicFlags)+ , ("member", toJSON <$> userPublicFlags) ] ] +-- TODO: fully update webhook structure data Webhook = Webhook { webhookId :: WebhookId- , webhookToken :: Text+ , webhookToken :: Maybe Text , webhookChannelId :: ChannelId } deriving (Show, Read, Eq, Ord) instance FromJSON Webhook where parseJSON = withObject "Webhook" $ \o -> Webhook <$> o .: "id"- <*> o .: "token"+ <*> o .:? "token" <*> o .: "channel_id" data ConnectionObject = ConnectionObject@@ -83,3 +107,45 @@ <*> o .: "friend_sync" <*> o .: "show_activity" <*> ( (==) (1::Int) <$> o .: "visibility")+++-- | Representation of a guild member.+data GuildMember = GuildMember+ { memberUser :: Maybe User -- ^ User object - not included in message_create or update+ , memberNick :: Maybe T.Text -- ^ User's guild nickname+ , memberAvatar :: Maybe T.Text -- ^ User's guild avatar hash+ , memberRoles :: [RoleId] -- ^ Array of role ids+ , memberJoinedAt :: UTCTime -- ^ When the user joined the guild+ , memberPremiumSince :: Maybe UTCTime -- ^ When the user started boosting the guild+ , memberDeaf :: Bool -- ^ Whether the user is deafened+ , memberMute :: Bool -- ^ Whether the user is muted+ , memberPending :: Bool -- ^ Whether the user has passed the guild's membership screening+ , memberPermissions :: Maybe T.Text -- ^ total permissions of the member+ } deriving (Show, Read, Eq, Ord)++instance FromJSON GuildMember where+ parseJSON = withObject "GuildMember" $ \o ->+ GuildMember <$> o .:? "user"+ <*> o .:? "nick"+ <*> o .:? "avatar"+ <*> o .: "roles"+ <*> o .: "joined_at"+ <*> o .:? "premium_since"+ <*> o .: "deaf"+ <*> o .: "mute"+ <*> o .:? "pending" .!= False+ <*> o .:? "permissions"++instance ToJSON GuildMember where+ toJSON GuildMember {..} = object [(name, value) | (name, Just value) <-+ [ ("user", toJSON <$> memberUser)+ , ("nick", toJSON <$> memberNick)+ , ("avatar", toJSON <$> memberAvatar)+ , ("roles", toJSON <$> pure memberRoles)+ , ("joined_at", toJSON <$> pure memberJoinedAt)+ , ("premium_since", toJSON <$> memberPremiumSince)+ , ("deaf", toJSON <$> pure memberDeaf)+ , ("mute", toJSON <$> pure memberMute)+ , ("pending", toJSON <$> pure memberPending)+ , ("permissions", toJSON <$> memberPermissions)+ ] ]
src/Discord/Requests.hs view
@@ -6,6 +6,8 @@ , module Discord.Internal.Rest.User , module Discord.Internal.Rest.Voice , module Discord.Internal.Rest.Webhook+ , module Discord.Internal.Rest.ApplicationCommands+ , module Discord.Internal.Rest.Interactions ) where import Discord.Internal.Rest.Channel@@ -15,3 +17,5 @@ import Discord.Internal.Rest.User import Discord.Internal.Rest.Voice import Discord.Internal.Rest.Webhook+import Discord.Internal.Rest.ApplicationCommands+import Discord.Internal.Rest.Interactions