discord-haskell 1.9.2 → 1.10.0
raw patch · 22 files changed
+250/−238 lines, 22 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Discord.Internal.Gateway: data Event
- Discord.Internal.Rest.Guild: CreateGuildOpts :: Text -> [Channel] -> CreateGuildOpts
- Discord.Internal.Rest.Guild: [CreateGuild] :: CreateGuildOpts -> GuildRequest Guild
- Discord.Internal.Rest.Guild: [createGuildOptsChannels] :: CreateGuildOpts -> [Channel]
- Discord.Internal.Rest.Guild: [createGuildOptsName] :: CreateGuildOpts -> Text
- Discord.Internal.Rest.Guild: data CreateGuildOpts
- Discord.Internal.Rest.Guild: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Rest.Guild.CreateGuildOpts
- Discord.Internal.Rest.Guild: instance GHC.Classes.Eq Discord.Internal.Rest.Guild.CreateGuildOpts
- Discord.Internal.Rest.Guild: instance GHC.Classes.Ord Discord.Internal.Rest.Guild.CreateGuildOpts
- Discord.Internal.Rest.Guild: instance GHC.Show.Show Discord.Internal.Rest.Guild.CreateGuildOpts
- Discord.Internal.Types.Channel: [parentId] :: Channel -> Maybe ParentId
- Discord.Internal.Types.Channel: instance Data.Aeson.Types.ToJSON.ToJSON Discord.Internal.Types.Channel.Channel
- Discord.Types: [parentId] :: Channel -> Maybe ParentId
- Discord.Types: pattern Identify :: () => Auth -> GatewayIntent -> (Int, Int) -> GatewaySendableInternal
- Discord.Types: pattern InvalidSession :: () => Bool -> GatewayReceivable
- Discord.Types: pattern Dispatch :: () => Event -> Integer -> GatewayReceivable
- Discord.Types: pattern Reconnect :: () => GatewayReceivable
- Discord.Types: pattern HeartbeatRequest :: () => Integer -> GatewayReceivable
- Discord.Types: pattern ParseError :: () => Text -> GatewayReceivable
+ Discord: instance GHC.Read.Read Discord.RestCallErrorCode
+ Discord.Internal.Gateway: data EventInternalParse
+ Discord.Internal.Rest.Channel: instance GHC.Read.Read Discord.Internal.Rest.Channel.AllowedMentions
+ Discord.Internal.Rest.Channel: instance GHC.Read.Read Discord.Internal.Rest.Channel.ChannelInviteOpts
+ Discord.Internal.Rest.Channel: instance GHC.Read.Read Discord.Internal.Rest.Channel.ChannelPermissionsOpts
+ Discord.Internal.Rest.Channel: instance GHC.Read.Read Discord.Internal.Rest.Channel.ChannelPermissionsOptsType
+ Discord.Internal.Rest.Channel: instance GHC.Read.Read Discord.Internal.Rest.Channel.GroupDMAddRecipientOpts
+ Discord.Internal.Rest.Channel: instance GHC.Read.Read Discord.Internal.Rest.Channel.MessageDetailedOpts
+ Discord.Internal.Rest.Channel: instance GHC.Read.Read Discord.Internal.Rest.Channel.MessageTiming
+ Discord.Internal.Rest.Channel: instance GHC.Read.Read Discord.Internal.Rest.Channel.ModifyChannelOpts
+ Discord.Internal.Rest.Channel: instance GHC.Read.Read Discord.Internal.Rest.Channel.ReactionTiming
+ Discord.Internal.Rest.Emoji: instance GHC.Read.Read Discord.Internal.Rest.Emoji.EmojiImageParsed
+ Discord.Internal.Rest.Emoji: instance GHC.Read.Read Discord.Internal.Rest.Emoji.ModifyGuildEmojiOpts
+ Discord.Internal.Rest.Guild: instance GHC.Read.Read Discord.Internal.Rest.Guild.AddGuildMemberOpts
+ Discord.Internal.Rest.Guild: instance GHC.Read.Read Discord.Internal.Rest.Guild.CreateGuildBanOpts
+ Discord.Internal.Rest.Guild: instance GHC.Read.Read Discord.Internal.Rest.Guild.CreateGuildChannelOpts
+ Discord.Internal.Rest.Guild: instance GHC.Read.Read Discord.Internal.Rest.Guild.CreateGuildIntegrationOpts
+ Discord.Internal.Rest.Guild: instance GHC.Read.Read Discord.Internal.Rest.Guild.GuildMembersTiming
+ Discord.Internal.Rest.Guild: instance GHC.Read.Read Discord.Internal.Rest.Guild.ModifyGuildIntegrationOpts
+ Discord.Internal.Rest.Guild: instance GHC.Read.Read Discord.Internal.Rest.Guild.ModifyGuildMemberOpts
+ Discord.Internal.Rest.Guild: instance GHC.Read.Read Discord.Internal.Rest.Guild.ModifyGuildOpts
+ Discord.Internal.Rest.Guild: instance GHC.Read.Read Discord.Internal.Rest.Guild.ModifyGuildRoleOpts
+ Discord.Internal.Rest.User: instance GHC.Read.Read Discord.Internal.Rest.User.CurrentUserAvatar
+ Discord.Internal.Rest.Webhook: instance GHC.Read.Read Discord.Internal.Rest.Webhook.CreateWebhookOpts
+ Discord.Internal.Rest.Webhook: instance GHC.Read.Read Discord.Internal.Rest.Webhook.ExecuteWebhookWithTokenOpts
+ Discord.Internal.Rest.Webhook: instance GHC.Read.Read Discord.Internal.Rest.Webhook.ModifyWebhookOpts
+ Discord.Internal.Rest.Webhook: instance GHC.Read.Read Discord.Internal.Rest.Webhook.WebhookContent
+ Discord.Internal.Types: userFacingEvent :: EventInternalParse -> Event
+ Discord.Internal.Types.Channel: [channelParentId] :: Channel -> Maybe ParentId
+ Discord.Internal.Types.Channel: [emojiAnimated] :: Emoji -> Maybe Bool
+ Discord.Internal.Types.Channel: instance GHC.Read.Read Discord.Internal.Types.Channel.Attachment
+ Discord.Internal.Types.Channel: instance GHC.Read.Read Discord.Internal.Types.Channel.Channel
+ Discord.Internal.Types.Channel: instance GHC.Read.Read Discord.Internal.Types.Channel.Emoji
+ Discord.Internal.Types.Channel: instance GHC.Read.Read Discord.Internal.Types.Channel.Message
+ Discord.Internal.Types.Channel: instance GHC.Read.Read Discord.Internal.Types.Channel.MessageReaction
+ Discord.Internal.Types.Channel: instance GHC.Read.Read Discord.Internal.Types.Channel.MessageReference
+ Discord.Internal.Types.Channel: instance GHC.Read.Read Discord.Internal.Types.Channel.Nonce
+ Discord.Internal.Types.Channel: instance GHC.Read.Read Discord.Internal.Types.Channel.Overwrite
+ Discord.Internal.Types.Embed: instance GHC.Read.Read Discord.Internal.Types.Embed.CreateEmbed
+ Discord.Internal.Types.Embed: instance GHC.Read.Read Discord.Internal.Types.Embed.CreateEmbedImage
+ Discord.Internal.Types.Embed: instance GHC.Read.Read Discord.Internal.Types.Embed.Embed
+ Discord.Internal.Types.Embed: instance GHC.Read.Read Discord.Internal.Types.Embed.EmbedAuthor
+ Discord.Internal.Types.Embed: instance GHC.Read.Read Discord.Internal.Types.Embed.EmbedField
+ Discord.Internal.Types.Embed: instance GHC.Read.Read Discord.Internal.Types.Embed.EmbedFooter
+ Discord.Internal.Types.Embed: instance GHC.Read.Read Discord.Internal.Types.Embed.EmbedImage
+ Discord.Internal.Types.Embed: instance GHC.Read.Read Discord.Internal.Types.Embed.EmbedProvider
+ Discord.Internal.Types.Embed: instance GHC.Read.Read Discord.Internal.Types.Embed.EmbedThumbnail
+ Discord.Internal.Types.Embed: instance GHC.Read.Read Discord.Internal.Types.Embed.EmbedVideo
+ Discord.Internal.Types.Events: InternalChannelCreate :: Channel -> EventInternalParse
+ Discord.Internal.Types.Events: InternalChannelDelete :: Channel -> EventInternalParse
+ Discord.Internal.Types.Events: InternalChannelPinsUpdate :: ChannelId -> Maybe UTCTime -> EventInternalParse
+ Discord.Internal.Types.Events: InternalChannelUpdate :: Channel -> EventInternalParse
+ Discord.Internal.Types.Events: InternalGuildBanAdd :: GuildId -> User -> EventInternalParse
+ Discord.Internal.Types.Events: InternalGuildBanRemove :: GuildId -> User -> EventInternalParse
+ Discord.Internal.Types.Events: InternalGuildCreate :: Guild -> GuildInfo -> EventInternalParse
+ Discord.Internal.Types.Events: InternalGuildDelete :: GuildUnavailable -> EventInternalParse
+ Discord.Internal.Types.Events: InternalGuildEmojiUpdate :: GuildId -> [Emoji] -> EventInternalParse
+ Discord.Internal.Types.Events: InternalGuildIntegrationsUpdate :: GuildId -> EventInternalParse
+ Discord.Internal.Types.Events: InternalGuildMemberAdd :: GuildId -> GuildMember -> EventInternalParse
+ Discord.Internal.Types.Events: InternalGuildMemberChunk :: GuildId -> [GuildMember] -> EventInternalParse
+ Discord.Internal.Types.Events: InternalGuildMemberRemove :: GuildId -> User -> EventInternalParse
+ Discord.Internal.Types.Events: InternalGuildMemberUpdate :: GuildId -> [RoleId] -> User -> Maybe Text -> EventInternalParse
+ Discord.Internal.Types.Events: InternalGuildRoleCreate :: GuildId -> Role -> EventInternalParse
+ Discord.Internal.Types.Events: InternalGuildRoleDelete :: GuildId -> RoleId -> EventInternalParse
+ Discord.Internal.Types.Events: InternalGuildRoleUpdate :: GuildId -> Role -> EventInternalParse
+ Discord.Internal.Types.Events: InternalGuildUpdate :: Guild -> EventInternalParse
+ Discord.Internal.Types.Events: InternalMessageCreate :: Message -> EventInternalParse
+ Discord.Internal.Types.Events: InternalMessageDelete :: ChannelId -> MessageId -> EventInternalParse
+ Discord.Internal.Types.Events: InternalMessageDeleteBulk :: ChannelId -> [MessageId] -> EventInternalParse
+ Discord.Internal.Types.Events: InternalMessageReactionAdd :: ReactionInfo -> EventInternalParse
+ Discord.Internal.Types.Events: InternalMessageReactionRemove :: ReactionInfo -> EventInternalParse
+ Discord.Internal.Types.Events: InternalMessageReactionRemoveAll :: ChannelId -> MessageId -> EventInternalParse
+ Discord.Internal.Types.Events: InternalMessageReactionRemoveEmoji :: ReactionRemoveInfo -> EventInternalParse
+ Discord.Internal.Types.Events: InternalMessageUpdate :: ChannelId -> MessageId -> EventInternalParse
+ Discord.Internal.Types.Events: InternalPresenceUpdate :: PresenceInfo -> EventInternalParse
+ Discord.Internal.Types.Events: InternalReady :: Int -> User -> [Channel] -> [GuildUnavailable] -> Text -> EventInternalParse
+ Discord.Internal.Types.Events: InternalResumed :: [Text] -> EventInternalParse
+ Discord.Internal.Types.Events: InternalTypingStart :: TypingInfo -> EventInternalParse
+ Discord.Internal.Types.Events: InternalUnknownEvent :: Text -> Object -> EventInternalParse
+ Discord.Internal.Types.Events: InternalUserUpdate :: User -> EventInternalParse
+ Discord.Internal.Types.Events: data EventInternalParse
+ Discord.Internal.Types.Events: instance GHC.Classes.Eq Discord.Internal.Types.Events.EventInternalParse
+ Discord.Internal.Types.Events: instance GHC.Read.Read Discord.Internal.Types.Events.Event
+ Discord.Internal.Types.Events: instance GHC.Read.Read Discord.Internal.Types.Events.EventInternalParse
+ Discord.Internal.Types.Events: instance GHC.Read.Read Discord.Internal.Types.Events.PresenceInfo
+ Discord.Internal.Types.Events: instance GHC.Read.Read Discord.Internal.Types.Events.ReactionInfo
+ Discord.Internal.Types.Events: instance GHC.Read.Read Discord.Internal.Types.Events.ReactionRemoveInfo
+ Discord.Internal.Types.Events: instance GHC.Read.Read Discord.Internal.Types.Events.TypingInfo
+ Discord.Internal.Types.Events: instance GHC.Show.Show Discord.Internal.Types.Events.EventInternalParse
+ Discord.Internal.Types.Gateway: instance GHC.Read.Read Discord.Internal.Types.Gateway.Activity
+ Discord.Internal.Types.Gateway: instance GHC.Read.Read Discord.Internal.Types.Gateway.ActivityType
+ Discord.Internal.Types.Gateway: instance GHC.Read.Read Discord.Internal.Types.Gateway.GatewayIntent
+ Discord.Internal.Types.Gateway: instance GHC.Read.Read Discord.Internal.Types.Gateway.GatewayReceivable
+ Discord.Internal.Types.Gateway: instance GHC.Read.Read Discord.Internal.Types.Gateway.GatewaySendable
+ Discord.Internal.Types.Gateway: instance GHC.Read.Read Discord.Internal.Types.Gateway.GatewaySendableInternal
+ Discord.Internal.Types.Gateway: instance GHC.Read.Read Discord.Internal.Types.Gateway.RequestGuildMembersOpts
+ Discord.Internal.Types.Gateway: instance GHC.Read.Read Discord.Internal.Types.Gateway.UpdateStatusOpts
+ Discord.Internal.Types.Gateway: instance GHC.Read.Read Discord.Internal.Types.Gateway.UpdateStatusType
+ Discord.Internal.Types.Gateway: instance GHC.Read.Read Discord.Internal.Types.Gateway.UpdateStatusVoiceOpts
+ Discord.Internal.Types.Guild: instance GHC.Read.Read Discord.Internal.Types.Guild.Guild
+ Discord.Internal.Types.Guild: instance GHC.Read.Read Discord.Internal.Types.Guild.GuildBan
+ 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.GuildInfo
+ Discord.Internal.Types.Guild: instance GHC.Read.Read Discord.Internal.Types.Guild.GuildMember
+ Discord.Internal.Types.Guild: instance GHC.Read.Read Discord.Internal.Types.Guild.GuildUnavailable
+ Discord.Internal.Types.Guild: instance GHC.Read.Read Discord.Internal.Types.Guild.Integration
+ Discord.Internal.Types.Guild: instance GHC.Read.Read Discord.Internal.Types.Guild.IntegrationAccount
+ Discord.Internal.Types.Guild: instance GHC.Read.Read Discord.Internal.Types.Guild.Invite
+ Discord.Internal.Types.Guild: instance GHC.Read.Read Discord.Internal.Types.Guild.InviteMeta
+ Discord.Internal.Types.Guild: instance GHC.Read.Read Discord.Internal.Types.Guild.PartialGuild
+ Discord.Internal.Types.Guild: instance GHC.Read.Read Discord.Internal.Types.Guild.Role
+ Discord.Internal.Types.Guild: instance GHC.Read.Read Discord.Internal.Types.Guild.VoiceRegion
+ Discord.Internal.Types.Prelude: instance GHC.Read.Read Discord.Internal.Types.Prelude.Auth
+ Discord.Internal.Types.User: instance GHC.Read.Read Discord.Internal.Types.User.ConnectionObject
+ Discord.Internal.Types.User: instance GHC.Read.Read Discord.Internal.Types.User.User
+ Discord.Internal.Types.User: instance GHC.Read.Read Discord.Internal.Types.User.Webhook
+ Discord.Types: [channelParentId] :: Channel -> Maybe ParentId
+ Discord.Types: [emojiAnimated] :: Emoji -> Maybe Bool
+ Discord.Types: userFacingEvent :: EventInternalParse -> Event
- Discord.Internal.Gateway: CacheHandle :: Chan (Either GatewayException Event) -> MVar (Either (Cache, GatewayException) Cache) -> CacheHandle
+ Discord.Internal.Gateway: CacheHandle :: Chan (Either GatewayException EventInternalParse) -> MVar (Either (Cache, GatewayException) Cache) -> CacheHandle
- Discord.Internal.Gateway: GatewayHandle :: Chan (Either GatewayException Event) -> Chan GatewaySendable -> IORef (Maybe UpdateStatusOpts) -> IORef Integer -> IORef Text -> GatewayHandle
+ Discord.Internal.Gateway: GatewayHandle :: Chan (Either GatewayException EventInternalParse) -> Chan GatewaySendable -> IORef (Maybe UpdateStatusOpts) -> IORef Integer -> IORef Text -> GatewayHandle
- Discord.Internal.Gateway: [cacheHandleEvents] :: CacheHandle -> Chan (Either GatewayException Event)
+ Discord.Internal.Gateway: [cacheHandleEvents] :: CacheHandle -> Chan (Either GatewayException EventInternalParse)
- Discord.Internal.Gateway: [gatewayHandleEvents] :: GatewayHandle -> Chan (Either GatewayException Event)
+ Discord.Internal.Gateway: [gatewayHandleEvents] :: GatewayHandle -> Chan (Either GatewayException EventInternalParse)
- Discord.Internal.Gateway.Cache: CacheHandle :: Chan (Either GatewayException Event) -> MVar (Either (Cache, GatewayException) Cache) -> CacheHandle
+ Discord.Internal.Gateway.Cache: CacheHandle :: Chan (Either GatewayException EventInternalParse) -> MVar (Either (Cache, GatewayException) Cache) -> CacheHandle
- Discord.Internal.Gateway.Cache: [cacheHandleEvents] :: CacheHandle -> Chan (Either GatewayException Event)
+ Discord.Internal.Gateway.Cache: [cacheHandleEvents] :: CacheHandle -> Chan (Either GatewayException EventInternalParse)
- Discord.Internal.Gateway.Cache: adjustCache :: Cache -> Event -> Cache
+ Discord.Internal.Gateway.Cache: adjustCache :: Cache -> EventInternalParse -> Cache
- Discord.Internal.Gateway.EventLoop: GatewayHandle :: Chan (Either GatewayException Event) -> Chan GatewaySendable -> IORef (Maybe UpdateStatusOpts) -> IORef Integer -> IORef Text -> GatewayHandle
+ Discord.Internal.Gateway.EventLoop: GatewayHandle :: Chan (Either GatewayException EventInternalParse) -> Chan GatewaySendable -> IORef (Maybe UpdateStatusOpts) -> IORef Integer -> IORef Text -> GatewayHandle
- Discord.Internal.Gateway.EventLoop: [gatewayHandleEvents] :: GatewayHandle -> Chan (Either GatewayException Event)
+ Discord.Internal.Gateway.EventLoop: [gatewayHandleEvents] :: GatewayHandle -> Chan (Either GatewayException EventInternalParse)
- Discord.Internal.Types.Channel: Emoji :: Maybe EmojiId -> Text -> Maybe [RoleId] -> Maybe User -> Maybe Bool -> Emoji
+ Discord.Internal.Types.Channel: Emoji :: Maybe EmojiId -> Text -> Maybe [RoleId] -> Maybe User -> Maybe Bool -> Maybe Bool -> Emoji
- Discord.Internal.Types.Events: eventParse :: Text -> Object -> Parser Event
+ Discord.Internal.Types.Events: eventParse :: Text -> Object -> Parser EventInternalParse
- Discord.Internal.Types.Gateway: Dispatch :: Event -> Integer -> GatewayReceivable
+ Discord.Internal.Types.Gateway: Dispatch :: EventInternalParse -> Integer -> GatewayReceivable
- Discord.Types: Emoji :: Maybe EmojiId -> Text -> Maybe [RoleId] -> Maybe User -> Maybe Bool -> Emoji
+ Discord.Types: Emoji :: Maybe EmojiId -> Text -> Maybe [RoleId] -> Maybe User -> Maybe Bool -> Maybe Bool -> Emoji
- Discord.Types: eventParse :: Text -> Object -> Parser Event
+ Discord.Types: eventParse :: Text -> Object -> Parser EventInternalParse
Files
- README.md +16/−11
- changelog.md +9/−0
- discord-haskell.cabal +1/−1
- src/Discord.hs +3/−2
- src/Discord/Internal/Gateway.hs +3/−3
- src/Discord/Internal/Gateway/Cache.hs +9/−9
- src/Discord/Internal/Gateway/EventLoop.hs +2/−2
- src/Discord/Internal/Rest/Channel.hs +9/−9
- src/Discord/Internal/Rest/Emoji.hs +2/−2
- src/Discord/Internal/Rest/Guild.hs +12/−25
- src/Discord/Internal/Rest/Prelude.hs +1/−1
- src/Discord/Internal/Rest/User.hs +1/−1
- src/Discord/Internal/Rest/Webhook.hs +4/−4
- src/Discord/Internal/Types.hs +37/−0
- src/Discord/Internal/Types/Channel.hs +18/−83
- src/Discord/Internal/Types/Embed.hs +10/−10
- src/Discord/Internal/Types/Events.hs +81/−44
- src/Discord/Internal/Types/Gateway.hs +12/−12
- src/Discord/Internal/Types/Guild.hs +13/−13
- src/Discord/Internal/Types/Prelude.hs +1/−1
- src/Discord/Internal/Types/User.hs +3/−3
- src/Discord/Types.hs +3/−2
README.md view
@@ -1,10 +1,18 @@-# discord-haskell [](https://app.travis-ci.com/github/aquarial/discord-haskell) [](https://hackage.haskell.org/package/discord-haskell)+# discord-haskell [](https://app.travis-ci.com/github/aquarial/discord-haskell) [](https://hackage.haskell.org/package/discord-haskell) [](https://discord.gg/eaRAGgX3bK) -Build that discord bot in Haskell! Also checkout the [calamity](https://github.com/nitros12/calamity) -haskell discord library for a more advanced interface than `discord-haskell`.+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`. -This is an example bot that replies "pong" to messages that start with "ping".+### Discord Server +Created a discord server: https://discord.gg/eaRAGgX3bK++Ask questions, get updates, request features, etc++### Quickstart++This is an example bot that replies "pong" to messages that start with "ping". Also checkout the [other examples](./examples/)+ ```haskell {-# LANGUAGE OverloadedStrings #-} -- allows "string literals" to be Text @@ -55,10 +63,11 @@ ### Biggest TODOs -- [ ] APIv9-- [x] rewrite eventloop [issue 70](https://github.com/aquarial/discord-haskell/issues/70)+- [ ] Add slash commands [issue](https://github.com/aquarial/discord-haskell/issues/59)+- [ ] APIv9 [issue](https://github.com/aquarial/discord-haskell/issues/72) - [ ] Event type includes roles and other cached info - [ ] higher level bot interface? easier to add state and stuff+- [x] rewrite eventloop [issue](https://github.com/aquarial/discord-haskell/issues/70) ### Installing @@ -149,7 +158,7 @@ #### Official discord docs -For a list of rest requests, gateway events, and gateway sendables go to the +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 @@ -164,7 +173,3 @@ #### Open an Issue For deeper questions about how the library functions, feel free to open an issue.--#### Discord server--Coming sometime!
changelog.md view
@@ -6,7 +6,16 @@ ## master ++## 1.10.0+ [drewolson](https://github.com/aquarial/discord-haskell/pull/80) allows parsing an optional guild region++[L0neGamer](https://github.com/aquarial/discord-haskell/pull/82) add 'animated' flag for Emoji++Removed `CreateGuild` rest call! You can only do it if your bot is in fewer than 10 guilds, and it's [a pain to support](https://discord.com/developers/docs/resources/guild#create-guild). Just do it manually.++Added `Read` instance to complement `Show` for lots of types. Removed ToJSON for `Channel`. ## 1.9.1
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.9.2+version: 1.10.0 description: Functions and data types to write discord bots. Official discord docs <https://discord.com/developers/docs/reference>. .
src/Discord.hs view
@@ -106,9 +106,10 @@ case next of Left err -> libError err Right (Right event) -> do+ let userEvent = userFacingEvent event let action = if discordForkThreadForEvents opts then void . forkIO else id- action $ do me <- liftIO . runReaderT (try $ discordOnEvent opts event) $ handle+ action $ do me <- liftIO . runReaderT (try $ discordOnEvent opts userEvent) $ handle case me of Left (e :: SomeException) -> writeChan (discordHandleLog handle) ("discord-haskell stopped on an exception:\n\n" <> T.pack (show e))@@ -118,7 +119,7 @@ data RestCallErrorCode = RestCallErrorCode Int T.Text T.Text- deriving (Show, Eq, Ord)+ deriving (Show, Read, Eq, Ord) -- | Execute one http request and get a response restCall :: (FromJSON a, Request (r a)) => r a -> DiscordHandler (Either RestCallErrorCode a)
src/Discord/Internal/Gateway.hs view
@@ -18,20 +18,20 @@ import Data.IORef (newIORef) import qualified Data.Text as T -import Discord.Internal.Types (Auth, Event, GatewayIntent)+import Discord.Internal.Types (Auth, EventInternalParse, GatewayIntent) import Discord.Internal.Gateway.EventLoop (connectionLoop, GatewayHandle(..), GatewayException(..)) import Discord.Internal.Gateway.Cache (cacheLoop, Cache(..), CacheHandle(..)) startCacheThread :: Chan T.Text -> IO (CacheHandle, ThreadId) startCacheThread log = do- events <- newChan :: IO (Chan (Either GatewayException Event))+ events <- newChan :: IO (Chan (Either GatewayException EventInternalParse)) cache <- newEmptyMVar :: IO (MVar (Either (Cache, GatewayException) Cache)) let cacheHandle = CacheHandle events cache tid <- forkIO $ cacheLoop cacheHandle log pure (cacheHandle, tid) -- | Create a Chan for websockets. This creates a thread that--- writes all the received Events to the Chan+-- writes all the received EventsInternalParse to the Chan startGatewayThread :: Auth -> GatewayIntent -> CacheHandle -> Chan T.Text -> IO (GatewayHandle, ThreadId) startGatewayThread auth intent cacheHandle log = do events <- dupChan (cacheHandleEvents cacheHandle)
src/Discord/Internal/Gateway/Cache.hs view
@@ -21,7 +21,7 @@ } deriving (Show) data CacheHandle = CacheHandle- { cacheHandleEvents :: Chan (Either GatewayException Event)+ { cacheHandleEvents :: Chan (Either GatewayException EventInternalParse) , cacheHandleCache :: MVar (Either (Cache, GatewayException) Cache) } @@ -29,7 +29,7 @@ cacheLoop cacheHandle log = do ready <- readChan eventChan case ready of- Right (Ready _ user dmChannels _unavailableGuilds _) -> do+ Right (InternalReady _ user dmChannels _unavailableGuilds _) -> do let dmChans = M.fromList (zip (map channelId dmChannels) dmChannels) putMVar cache (Right (Cache user dmChans M.empty M.empty)) loop@@ -51,23 +51,23 @@ Left e -> putMVar cache (Left (info, e)) Right event -> putMVar cache (Right (adjustCache info event)) -adjustCache :: Cache -> Event -> Cache+adjustCache :: Cache -> EventInternalParse -> Cache adjustCache minfo event = case event of- --ChannelCreate Channel- --ChannelUpdate Channel- --ChannelDelete Channel- GuildCreate guild info ->+ --InternalChannelCreate Channel+ --InternalChannelUpdate Channel+ --InternalChannelDelete Channel+ InternalGuildCreate guild info -> let newChans = map (setChanGuildID (guildId guild)) $ guildChannels info g = M.insert (guildId guild) (guild, info { guildChannels = newChans }) (cacheGuilds minfo) c = M.unionWith (\a _ -> a) (M.fromList [ (channelId ch, ch) | ch <- newChans ]) (cacheChannels minfo) in minfo { cacheGuilds = g, cacheChannels = c }- --GuildUpdate guild -> do+ --InternalGuildUpdate guild -> do -- let g = M.insert (guildId guild) guild (cacheGuilds minfo) -- m2 = minfo { cacheGuilds = g } -- putMVar cache m2- --GuildDelete guild -> do+ --InternalGuildDelete guild -> do -- let g = M.delete (guildId guild) (cacheGuilds minfo) -- c = M.filterWithKey (\(keyGuildId,_) _ -> keyGuildId /= guildId guild) (cacheChannels minfo) -- m2 = minfo { cacheGuilds = g, cacheChannels = c }
src/Discord/Internal/Gateway/EventLoop.hs view
@@ -27,7 +27,7 @@ data GatewayHandle = GatewayHandle- { gatewayHandleEvents :: Chan (Either GatewayException Event)+ { gatewayHandleEvents :: Chan (Either GatewayException EventInternalParse) , gatewayHandleUserSendables :: Chan GatewaySendable , gatewayHandleLastStatus :: IORef (Maybe UpdateStatusOpts) , gatewayHandleLastSequenceId :: IORef Integer@@ -141,7 +141,7 @@ Right (Dispatch event sq) -> do writeIORef (gatewayHandleLastSequenceId thehandle) sq writeChan eventChan (Right event) case event of- (Ready _ _ _ _ seshID) ->+ (InternalReady _ _ _ _ seshID) -> writeIORef (gatewayHandleSessionId thehandle) seshID _ -> writeIORef (startsendingUsers sendablesData) True loop
src/Discord/Internal/Rest/Channel.hs view
@@ -106,7 +106,7 @@ , messageDetailedFile :: Maybe (T.Text, B.ByteString) , messageDetailedAllowedMentions :: Maybe AllowedMentions , messageDetailedReference :: Maybe MessageReference- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance Default MessageDetailedOpts where def = MessageDetailedOpts { messageDetailedContent = ""@@ -125,7 +125,7 @@ , mentionUserIds :: [UserId] , mentionRoleIds :: [RoleId] , mentionRepliedUser :: Bool- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance Default AllowedMentions where def = AllowedMentions { mentionEveryone = False@@ -152,7 +152,7 @@ data ReactionTiming = BeforeReaction MessageId | AfterReaction MessageId | LatestReaction- deriving (Show, Eq, Ord)+ deriving (Show, Read, Eq, Ord) reactionTimingToQuery :: ReactionTiming -> R.Option 'R.Https reactionTimingToQuery t = case t of@@ -165,7 +165,7 @@ | BeforeMessage MessageId | AfterMessage MessageId | LatestMessages- deriving (Show, Eq, Ord)+ deriving (Show, Read, Eq, Ord) messageTimingToQuery :: MessageTiming -> R.Option 'R.Https messageTimingToQuery t = case t of@@ -179,7 +179,7 @@ , channelInviteOptsMaxUsages :: Maybe Integer , channelInviteOptsIsTemporary :: Maybe Bool , channelInviteOptsDontReuseSimilarInvite :: Maybe Bool- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance ToJSON ChannelInviteOpts where toJSON ChannelInviteOpts{..} = object [(name, val) | (name, Just val) <-@@ -197,7 +197,7 @@ , modifyChannelUserRateLimit :: Maybe Integer , modifyChannelPermissionOverwrites :: Maybe [Overwrite] , modifyChannelParentId :: Maybe ChannelId- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance ToJSON ModifyChannelOpts where toJSON ModifyChannelOpts{..} = object [(name, val) | (name, Just val) <-@@ -214,11 +214,11 @@ { channelPermissionsOptsAllow :: Integer , channelPermissionsOptsDeny :: Integer , channelPermissionsOptsType :: ChannelPermissionsOptsType- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) data ChannelPermissionsOptsType = ChannelPermissionsOptsUser | ChannelPermissionsOptsRole- deriving (Show, Eq, Ord)+ deriving (Show, Read, Eq, Ord) instance ToJSON ChannelPermissionsOptsType where toJSON t = case t of ChannelPermissionsOptsUser -> String "member"@@ -234,7 +234,7 @@ { groupDMAddRecipientUserToAdd :: UserId , groupDMAddRecipientUserToAddNickName :: T.Text , groupDMAddRecipientGDMJoinAccessToken :: T.Text- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) channelMajorRoute :: ChannelRequest a -> String channelMajorRoute c = case c of
src/Discord/Internal/Rest/Emoji.hs view
@@ -45,7 +45,7 @@ data ModifyGuildEmojiOpts = ModifyGuildEmojiOpts { modifyGuildEmojiName :: T.Text , modifyGuildEmojiRoles :: [RoleId]- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance ToJSON ModifyGuildEmojiOpts where toJSON (ModifyGuildEmojiOpts name roles) =@@ -53,7 +53,7 @@ data EmojiImageParsed = EmojiImageParsed T.Text- deriving (Show, Eq, Ord)+ deriving (Show, Read, Eq, Ord) parseEmojiImage :: B.ByteString -> Either T.Text EmojiImageParsed parseEmojiImage bs =
src/Discord/Internal/Rest/Guild.hs view
@@ -8,7 +8,6 @@ module Discord.Internal.Rest.Guild ( GuildRequest(..) , CreateGuildChannelOpts(..)- , CreateGuildOpts(..) , ModifyGuildOpts(..) , AddGuildMemberOpts(..) , ModifyGuildMemberOpts(..)@@ -34,7 +33,9 @@ -- | Data constructor for requests. See <https://discord.com/developers/docs/resources/ API> data GuildRequest a where- CreateGuild :: CreateGuildOpts -> GuildRequest Guild+ -- -- Creating a guild with the API is annoying. Do it manually.+ -- -- https://discord.com/developers/docs/resources/guild#create-guild+ -- | Returns the new 'Guild' object for the given id GetGuild :: GuildId -> GuildRequest Guild -- | Modify a guild's settings. Returns the updated 'Guild' object on success. Fires a@@ -139,21 +140,11 @@ -- | Vanity URL GetGuildVanityURL :: GuildId -> GuildRequest T.Text -data CreateGuildOpts = CreateGuildOpts- { createGuildOptsName :: T.Text- , createGuildOptsChannels :: [Channel]- } deriving (Show, Eq, Ord)--instance ToJSON CreateGuildOpts where- toJSON CreateGuildOpts{..} = object [(name, val) | (name, Just val) <-- [ ("name", toJSON <$> pure createGuildOptsName )- , ("channels", toJSON <$> pure createGuildOptsChannels ) ]]- data ModifyGuildIntegrationOpts = ModifyGuildIntegrationOpts { modifyGuildIntegrationOptsExpireBehavior :: Integer , modifyGuildIntegrationOptsExpireGraceSeconds :: Integer , modifyGuildIntegrationOptsEmoticonsEnabled :: Bool- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance ToJSON ModifyGuildIntegrationOpts where toJSON ModifyGuildIntegrationOpts{..} = object [(name, val) | (name, Just val) <-@@ -163,7 +154,7 @@ data CreateGuildIntegrationOpts = CreateGuildIntegrationOpts { createGuildIntegrationOptsType :: T.Text- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance ToJSON CreateGuildIntegrationOpts where toJSON CreateGuildIntegrationOpts{..} = object [(name, val) | (name, Just val) <-@@ -172,7 +163,7 @@ data CreateGuildBanOpts = CreateGuildBanOpts { createGuildBanOptsDeleteLastNMessages :: Maybe Int , createGuildBanOptsReason :: Maybe T.Text- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance ToJSON CreateGuildBanOpts where toJSON CreateGuildBanOpts{..} = object [(name, val) | (name, Just val) <-@@ -186,7 +177,7 @@ , modifyGuildRoleOptsColor :: Maybe ColorInteger , modifyGuildRoleOptsSeparateSidebar :: Maybe Bool , modifyGuildRoleOptsMentionable :: Maybe Bool- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance ToJSON ModifyGuildRoleOpts where toJSON ModifyGuildRoleOpts{..} = object [(name, val) | (name, Just val) <-@@ -202,7 +193,7 @@ , addGuildMemberOptsRoles :: Maybe [RoleId] , addGuildMemberOptsIsMuted :: Maybe Bool , addGuildMemberOptsIsDeafened :: Maybe Bool- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance ToJSON AddGuildMemberOpts where toJSON AddGuildMemberOpts{..} = object [(name, val) | (name, Just val) <-@@ -218,7 +209,7 @@ , modifyGuildMemberOptsIsMuted :: Maybe Bool , modifyGuildMemberOptsIsDeafened :: Maybe Bool , modifyGuildMemberOptsMoveToChannel :: Maybe ChannelId- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance ToJSON ModifyGuildMemberOpts where toJSON ModifyGuildMemberOpts{..} = object [(name, val) | (name, Just val) <-@@ -238,7 +229,7 @@ , createGuildChannelOptsMaxUsers :: Maybe Integer , createGuildChannelOptsCategoryId :: Maybe ChannelId } | CreateGuildChannelOptsCategory- deriving (Show, Eq, Ord)+ deriving (Show, Read, Eq, Ord) createChannelOptsToJSON :: T.Text -> [Overwrite] -> CreateGuildChannelOpts -> Value createChannelOptsToJSON name perms opts = object [(key, val) | (key, Just val) <- optsJSON]@@ -275,7 +266,7 @@ -- VerificationLevel -- DefaultMessageNotification -- ExplicitContentFilter- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance ToJSON ModifyGuildOpts where toJSON ModifyGuildOpts{..} = object [(name, val) | (name, Just val) <-@@ -287,7 +278,7 @@ data GuildMembersTiming = GuildMembersTiming { guildMembersTimingLimit :: Maybe Int , guildMembersTimingAfter :: Maybe UserId- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) guildMembersTimingToQuery :: GuildMembersTiming -> R.Option 'R.Https guildMembersTimingToQuery (GuildMembersTiming mLimit mAfter) =@@ -301,7 +292,6 @@ guildMajorRoute :: GuildRequest a -> String guildMajorRoute c = case c of- (CreateGuild _) -> "guild " (GetGuild g) -> "guild " <> show g (ModifyGuild g _) -> "guild " <> show g (DeleteGuild g) -> "guild " <> show g@@ -344,9 +334,6 @@ guildJsonRequest :: GuildRequest r -> JsonRequest guildJsonRequest c = case c of- (CreateGuild opts) ->- Post (guilds) (pure (R.ReqBodyJson opts)) mempty- (GetGuild guild) -> Get (guilds // guild) mempty
src/Discord/Internal/Rest/Prelude.hs view
@@ -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.9.2)"+ agent = "DiscordBot (https://github.com/aquarial/discord-haskell, 1.10.0)" -- Append to an URL infixl 5 //
src/Discord/Internal/Rest/User.hs view
@@ -54,7 +54,7 @@ -- | Formatted avatar data https://discord.com/developers/docs/resources/user#avatar-data data CurrentUserAvatar = CurrentUserAvatar T.Text- deriving (Show, Eq, Ord)+ deriving (Show, Read, Eq, Ord) parseCurrentUserAvatar :: B.ByteString -> Either T.Text CurrentUserAvatar parseCurrentUserAvatar bs =
src/Discord/Internal/Rest/Webhook.hs view
@@ -61,7 +61,7 @@ { modifyWebhookOptsName :: Maybe T.Text , modifyWebhookOptsAvatar :: Maybe T.Text , modifyWebhookOptsChannelId :: Maybe ChannelId- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance ToJSON ModifyWebhookOpts where toJSON ModifyWebhookOpts{..} = object [(toKey name, val) | (name, Just val) <-@@ -72,7 +72,7 @@ data CreateWebhookOpts = CreateWebhookOpts { createWebhookOptsName :: T.Text , createWebhookOptsAvatar :: Maybe T.Text- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance ToJSON CreateWebhookOpts where toJSON CreateWebhookOpts{..} = object [(name, val) | (name, Just val) <-@@ -82,12 +82,12 @@ data ExecuteWebhookWithTokenOpts = ExecuteWebhookWithTokenOpts { executeWebhookWithTokenOptsUsername :: Maybe T.Text , executeWebhookWithTokenOptsContent :: WebhookContent- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) data WebhookContent = WebhookContentText T.Text | WebhookContentFile T.Text B.ByteString | WebhookContentEmbeds [CreateEmbed]- deriving (Show, Eq, Ord)+ deriving (Show, Read, Eq, Ord) webhookContentJson :: WebhookContent -> [(T.Text, Maybe Value)] webhookContentJson c = case c of
src/Discord/Internal/Types.hs view
@@ -10,6 +10,7 @@ , module Discord.Internal.Types.Embed , module Data.Aeson , module Data.Time.Clock+ , userFacingEvent ) where import Discord.Internal.Types.Channel@@ -22,3 +23,39 @@ import Data.Aeson (Object) import Data.Time.Clock (UTCTime(..))+++userFacingEvent :: EventInternalParse -> Event+userFacingEvent event = case event of+ InternalReady a b c d e -> Ready a b c d e+ InternalResumed a -> Resumed a+ InternalChannelCreate a -> ChannelCreate a+ InternalChannelUpdate a -> ChannelUpdate a+ InternalChannelDelete a -> ChannelDelete a+ InternalChannelPinsUpdate a b -> ChannelPinsUpdate a b+ InternalGuildCreate a b -> GuildCreate a b+ InternalGuildUpdate a -> GuildUpdate a+ InternalGuildDelete a -> GuildDelete a+ InternalGuildBanAdd a b -> GuildBanAdd a b+ InternalGuildBanRemove a b -> GuildBanRemove a b+ InternalGuildEmojiUpdate a b -> GuildEmojiUpdate a b+ InternalGuildIntegrationsUpdate a -> GuildIntegrationsUpdate a+ InternalGuildMemberAdd a b -> GuildMemberAdd a b+ InternalGuildMemberRemove a b -> GuildMemberRemove a b+ InternalGuildMemberUpdate a b c d -> GuildMemberUpdate a b c d+ InternalGuildMemberChunk a b -> GuildMemberChunk a b+ InternalGuildRoleCreate a b -> GuildRoleCreate a b+ InternalGuildRoleUpdate a b -> GuildRoleUpdate a b+ InternalGuildRoleDelete a b -> GuildRoleDelete a b+ InternalMessageCreate a -> MessageCreate a+ InternalMessageUpdate a b -> MessageUpdate a b+ InternalMessageDelete a b -> MessageDelete a b+ InternalMessageDeleteBulk a b -> MessageDeleteBulk a b+ InternalMessageReactionAdd a -> MessageReactionAdd a+ InternalMessageReactionRemove a -> MessageReactionRemove a+ InternalMessageReactionRemoveAll a b -> MessageReactionRemoveAll a b+ InternalMessageReactionRemoveEmoji a -> MessageReactionRemoveEmoji a+ InternalPresenceUpdate a -> PresenceUpdate a+ InternalTypingStart a -> TypingStart a+ InternalUserUpdate a -> UserUpdate a+ InternalUnknownEvent a b -> UnknownEvent a b
src/Discord/Internal/Types/Channel.hs view
@@ -31,7 +31,7 @@ , channelTopic :: T.Text -- ^ The topic of the channel. (0 - 1024 chars). , channelLastMessage :: Maybe MessageId -- ^ The id of the last message sent in the -- channel- , parentId :: Maybe ParentId -- ^ The id of the parent channel (category)+ , channelParentId :: Maybe ParentId -- ^ The id of the parent channel (category) } | ChannelNews { channelId :: ChannelId@@ -50,7 +50,7 @@ , channelPosition :: Integer , channelNSFW :: Bool , channelPermissions :: [Overwrite]- , parentId :: Maybe ParentId+ , channelParentId :: Maybe ParentId } -- | A voice channel in a guild. | ChannelVoice@@ -62,7 +62,7 @@ , channelNSFW :: Bool , channelBitRate :: Integer -- ^ The bitrate (in bits) of the channel. , channelUserLimit :: Integer -- ^ The user limit of the voice channel.- , parentId :: Maybe ParentId+ , channelParentId :: Maybe ParentId } -- | DM Channels represent a one-to-one conversation between two users, outside the scope -- of guilds@@ -92,7 +92,7 @@ | ChannelUnknownType { channelId :: ChannelId , channelJSON :: Text- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON Channel where parseJSON = withObject "Channel" $ \o -> do@@ -158,73 +158,6 @@ _ -> 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 parentId)- ] ]- 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@@ -241,7 +174,7 @@ , overwriteType :: T.Text -- ^ Either "role" or "member , overwriteAllow :: Integer -- ^ Allowed permission bit set , overwriteDeny :: Integer -- ^ Denied permission bit set- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON Overwrite where parseJSON = withObject "Overwrite" $ \o ->@@ -285,7 +218,7 @@ , 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- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON Message where parseJSON = withObject "Message" $ \o ->@@ -317,7 +250,7 @@ { messageReactionCount :: Int , messageReactionMeIncluded :: Bool , messageReactionEmoji :: Emoji- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON MessageReaction where parseJSON = withObject "MessageReaction" $ \o ->@@ -327,12 +260,13 @@ -- | 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- } deriving (Show, Eq, Ord)+ { 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 FromJSON Emoji where parseJSON = withObject "Emoji" $ \o ->@@ -341,6 +275,7 @@ <*> o .:? "roles" <*> o .:? "user" <*> o .:? "managed"+ <*> o .:? "animated" -- | Represents an attached to a message file.@@ -352,7 +287,7 @@ , attachmentProxy :: T.Text -- ^ Proxied url of file , attachmentHeight :: Maybe Integer -- ^ Height of file (if image) , attachmentWidth :: Maybe Integer -- ^ Width of file (if image)- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON Attachment where parseJSON = withObject "Attachment" $ \o ->@@ -367,7 +302,7 @@ newtype Nonce = Nonce T.Text- deriving (Show, Eq, Ord)+ deriving (Show, Read, Eq, Ord) instance FromJSON Nonce where parseJSON (String nonce) = pure $ Nonce nonce@@ -381,7 +316,7 @@ , referenceChannelId :: Maybe ChannelId -- ^ id of the originating message's channel , referenceGuildId :: Maybe GuildId -- ^ id of the originating message's guild , failIfNotExists :: Bool -- ^ Whether to not send if reference not exist- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON MessageReference where parseJSON = withObject "MessageReference" $ \o ->
src/Discord/Internal/Types/Embed.hs view
@@ -66,11 +66,11 @@ , createEmbedFooterIcon :: Maybe CreateEmbedImage , createEmbedColor :: Maybe ColorInteger --, createEmbedTimestamp :: Maybe UTCTime- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) data CreateEmbedImage = CreateEmbedImageUrl T.Text | CreateEmbedImageUpload B.ByteString- deriving (Show, Eq, Ord)+ deriving (Show, Read, Eq, Ord) instance Default CreateEmbed where def = CreateEmbed "" "" Nothing "" "" Nothing "" [] Nothing "" Nothing Nothing -- Nothing@@ -90,7 +90,7 @@ , embedType :: Maybe T.Text -- ^ Type of embed (Always "rich" for users) , embedVideo :: Maybe EmbedVideo -- ^ Only present for "video" types , embedProvider :: Maybe EmbedProvider -- ^ Only present for "video" types- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) -- TODO instance ToJSON Embed where@@ -132,7 +132,7 @@ , embedThumbnailProxyUrl :: Maybe T.Text , embedThumbnailHeight :: Maybe Integer , embedThumbnailWidth :: Maybe Integer- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance ToJSON EmbedThumbnail where toJSON (EmbedThumbnail a b c d) = object@@ -153,7 +153,7 @@ { embedVideoUrl :: Maybe T.Text , embedVideoHeight :: Maybe Integer , embedVideoWidth :: Maybe Integer- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance ToJSON EmbedVideo where toJSON (EmbedVideo a b c) = object@@ -173,7 +173,7 @@ , embedImageProxyUrl :: Maybe T.Text , embedImageHeight :: Maybe Integer , embedImageWidth :: Maybe Integer- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance ToJSON EmbedImage where toJSON (EmbedImage a b c d) = object@@ -193,7 +193,7 @@ data EmbedProvider = EmbedProvider { embedProviderName :: Maybe T.Text , embedProviderUrl :: Maybe T.Text- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance ToJSON EmbedProvider where toJSON (EmbedProvider a b) = object@@ -211,7 +211,7 @@ , embedAuthorUrl :: Maybe T.Text , embedAuthorIconUrl :: Maybe T.Text , embedAuthorProxyIconUrl :: Maybe T.Text- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance ToJSON EmbedAuthor where toJSON (EmbedAuthor a b c d) = object@@ -232,7 +232,7 @@ { embedFooterText :: T.Text , embedFooterIconUrl :: Maybe T.Text , embedFooterProxyIconUrl :: Maybe T.Text- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance ToJSON EmbedFooter where toJSON (EmbedFooter a b c) = object@@ -251,7 +251,7 @@ { embedFieldName :: T.Text , embedFieldValue :: T.Text , embedFieldInline :: Maybe Bool- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance ToJSON EmbedField where toJSON (EmbedField a b c) = object
src/Discord/Internal/Types/Events.hs view
@@ -55,15 +55,52 @@ -- | VoiceStateUpdate -- | VoiceServerUpdate | UnknownEvent T.Text Object- deriving (Show, Eq)+ deriving (Show, Read, Eq) +data EventInternalParse =+ InternalReady Int User [Channel] [GuildUnavailable] T.Text+ | InternalResumed [T.Text]+ | InternalChannelCreate Channel+ | InternalChannelUpdate Channel+ | InternalChannelDelete Channel+ | InternalChannelPinsUpdate ChannelId (Maybe UTCTime)+ | InternalGuildCreate Guild GuildInfo+ | InternalGuildUpdate Guild+ | InternalGuildDelete GuildUnavailable+ | InternalGuildBanAdd GuildId User+ | InternalGuildBanRemove GuildId User+ | InternalGuildEmojiUpdate GuildId [Emoji]+ | InternalGuildIntegrationsUpdate GuildId+ | InternalGuildMemberAdd GuildId GuildMember+ | InternalGuildMemberRemove GuildId User+ | InternalGuildMemberUpdate GuildId [RoleId] User (Maybe T.Text)+ | InternalGuildMemberChunk GuildId [GuildMember]+ | InternalGuildRoleCreate GuildId Role+ | InternalGuildRoleUpdate GuildId Role+ | InternalGuildRoleDelete GuildId RoleId+ | InternalMessageCreate Message+ | InternalMessageUpdate ChannelId MessageId+ | InternalMessageDelete ChannelId MessageId+ | InternalMessageDeleteBulk ChannelId [MessageId]+ | InternalMessageReactionAdd ReactionInfo+ | InternalMessageReactionRemove ReactionInfo+ | InternalMessageReactionRemoveAll ChannelId MessageId+ | InternalMessageReactionRemoveEmoji ReactionRemoveInfo+ | InternalPresenceUpdate PresenceInfo+ | InternalTypingStart TypingInfo+ | InternalUserUpdate User+ -- | InternalVoiceStateUpdate+ -- | InternalVoiceServerUpdate+ | InternalUnknownEvent T.Text Object+ deriving (Show, Read, Eq)+ data ReactionInfo = ReactionInfo { reactionUserId :: UserId , reactionGuildId :: Maybe GuildId , reactionChannelId :: ChannelId , reactionMessageId :: MessageId , reactionEmoji :: Emoji- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON ReactionInfo where parseJSON = withObject "ReactionInfo" $ \o ->@@ -78,7 +115,7 @@ , reactionRemoveGuildId :: GuildId , reactionRemoveMessageId :: MessageId , reactionRemoveEmoji :: Emoji- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON ReactionRemoveInfo where parseJSON = withObject "ReactionRemoveInfo" $ \o ->@@ -93,7 +130,7 @@ -- , presenceGame :: Maybe Activity , presenceGuildId :: GuildId , presenceStatus :: T.Text- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON PresenceInfo where parseJSON = withObject "PresenceInfo" $ \o ->@@ -107,7 +144,7 @@ { typingUserId :: UserId , typingChannelId :: ChannelId , typingTimestamp :: UTCTime- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON TypingInfo where parseJSON = withObject "TypingInfo" $ \o ->@@ -125,50 +162,50 @@ Left r -> fail r Right b -> pure b -eventParse :: T.Text -> Object -> Parser Event+eventParse :: T.Text -> Object -> Parser EventInternalParse eventParse t o = case t of- "READY" -> Ready <$> o .: "v"+ "READY" -> InternalReady <$> o .: "v" <*> o .: "user" <*> o .: "private_channels" <*> o .: "guilds" <*> o .: "session_id"- "RESUMED" -> Resumed <$> o .: "_trace"- "CHANNEL_CREATE" -> ChannelCreate <$> reparse o- "CHANNEL_UPDATE" -> ChannelUpdate <$> reparse o- "CHANNEL_DELETE" -> ChannelDelete <$> reparse o+ "RESUMED" -> InternalResumed <$> o .: "_trace"+ "CHANNEL_CREATE" -> InternalChannelCreate <$> reparse o+ "CHANNEL_UPDATE" -> InternalChannelUpdate <$> reparse o+ "CHANNEL_DELETE" -> InternalChannelDelete <$> reparse o "CHANNEL_PINS_UPDATE" -> do id <- o .: "channel_id" stamp <- o .:? "last_pin_timestamp" let utc = stamp >>= parseISO8601- pure (ChannelPinsUpdate id utc)- "GUILD_CREATE" -> GuildCreate <$> reparse o <*> reparse o- "GUILD_UPDATE" -> GuildUpdate <$> reparse o- "GUILD_DELETE" -> GuildDelete <$> reparse o- "GUILD_BAN_ADD" -> GuildBanAdd <$> o .: "guild_id" <*> o .: "user"- "GUILD_BAN_REMOVE" -> GuildBanRemove <$> o .: "guild_id" <*> o .: "user"- "GUILD_EMOJI_UPDATE" -> GuildEmojiUpdate <$> o .: "guild_id" <*> o .: "emojis"- "GUILD_INTEGRATIONS_UPDATE" -> GuildIntegrationsUpdate <$> o .: "guild_id"- "GUILD_MEMBER_ADD" -> GuildMemberAdd <$> o .: "guild_id" <*> reparse o- "GUILD_MEMBER_REMOVE" -> GuildMemberRemove <$> o .: "guild_id" <*> o .: "user"- "GUILD_MEMBER_UPDATE" -> GuildMemberUpdate <$> o .: "guild_id"- <*> o .: "roles"- <*> o .: "user"- <*> o .:? "nick"- "GUILD_MEMBERS_CHUNK" -> GuildMemberChunk <$> o .: "guild_id" <*> o .: "members"- "GUILD_ROLE_CREATE" -> GuildRoleCreate <$> o .: "guild_id" <*> o .: "role"- "GUILD_ROLE_UPDATE" -> GuildRoleUpdate <$> o .: "guild_id" <*> o .: "role"- "GUILD_ROLE_DELETE" -> GuildRoleDelete <$> o .: "guild_id" <*> o .: "role_id"- "MESSAGE_CREATE" -> MessageCreate <$> reparse o- "MESSAGE_UPDATE" -> MessageUpdate <$> o .: "channel_id" <*> o .: "id"- "MESSAGE_DELETE" -> MessageDelete <$> o .: "channel_id" <*> o .: "id"- "MESSAGE_DELETE_BULK" -> MessageDeleteBulk <$> o .: "channel_id" <*> o .: "ids"- "MESSAGE_REACTION_ADD" -> MessageReactionAdd <$> reparse o- "MESSAGE_REACTION_REMOVE" -> MessageReactionRemove <$> reparse o- "MESSAGE_REACTION_REMOVE_ALL" -> MessageReactionRemoveAll <$> o .: "channel_id"- <*> o .: "message_id"- "MESSAGE_REACTION_REMOVE_EMOJI" -> MessageReactionRemoveEmoji <$> reparse o- "PRESENCE_UPDATE" -> PresenceUpdate <$> reparse o- "TYPING_START" -> TypingStart <$> reparse o- "USER_UPDATE" -> UserUpdate <$> reparse o- -- "VOICE_STATE_UPDATE" -> VoiceStateUpdate <$> reparse o- -- "VOICE_SERVER_UPDATE" -> VoiceServerUpdate <$> reparse o- _other_event -> UnknownEvent t <$> reparse o+ pure (InternalChannelPinsUpdate id utc)+ "GUILD_CREATE" -> InternalGuildCreate <$> reparse o <*> reparse o+ "GUILD_UPDATE" -> InternalGuildUpdate <$> reparse o+ "GUILD_DELETE" -> InternalGuildDelete <$> reparse o+ "GUILD_BAN_ADD" -> InternalGuildBanAdd <$> o .: "guild_id" <*> o .: "user"+ "GUILD_BAN_REMOVE" -> InternalGuildBanRemove <$> o .: "guild_id" <*> o .: "user"+ "GUILD_EMOJI_UPDATE" -> InternalGuildEmojiUpdate <$> o .: "guild_id" <*> o .: "emojis"+ "GUILD_INTEGRATIONS_UPDATE" -> InternalGuildIntegrationsUpdate <$> o .: "guild_id"+ "GUILD_MEMBER_ADD" -> InternalGuildMemberAdd <$> o .: "guild_id" <*> reparse o+ "GUILD_MEMBER_REMOVE" -> InternalGuildMemberRemove <$> o .: "guild_id" <*> o .: "user"+ "GUILD_MEMBER_UPDATE" -> InternalGuildMemberUpdate <$> o .: "guild_id"+ <*> o .: "roles"+ <*> o .: "user"+ <*> o .:? "nick"+ "GUILD_MEMBERS_CHUNK" -> InternalGuildMemberChunk <$> o .: "guild_id" <*> o .: "members"+ "GUILD_ROLE_CREATE" -> InternalGuildRoleCreate <$> o .: "guild_id" <*> o .: "role"+ "GUILD_ROLE_UPDATE" -> InternalGuildRoleUpdate <$> o .: "guild_id" <*> o .: "role"+ "GUILD_ROLE_DELETE" -> InternalGuildRoleDelete <$> o .: "guild_id" <*> o .: "role_id"+ "MESSAGE_CREATE" -> InternalMessageCreate <$> reparse o+ "MESSAGE_UPDATE" -> InternalMessageUpdate <$> o .: "channel_id" <*> o .: "id"+ "MESSAGE_DELETE" -> InternalMessageDelete <$> o .: "channel_id" <*> o .: "id"+ "MESSAGE_DELETE_BULK" -> InternalMessageDeleteBulk <$> o .: "channel_id" <*> o .: "ids"+ "MESSAGE_REACTION_ADD" -> InternalMessageReactionAdd <$> reparse o+ "MESSAGE_REACTION_REMOVE" -> InternalMessageReactionRemove <$> reparse o+ "MESSAGE_REACTION_REMOVE_ALL" -> InternalMessageReactionRemoveAll <$> o .: "channel_id"+ <*> o .: "message_id"+ "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+ _other_event -> InternalUnknownEvent t <$> reparse o
src/Discord/Internal/Types/Gateway.hs view
@@ -23,21 +23,21 @@ -- | Sent by gateway data GatewayReceivable- = Dispatch Event Integer+ = Dispatch EventInternalParse Integer | HeartbeatRequest Integer | Reconnect | InvalidSession Bool | Hello Integer | HeartbeatAck | ParseError T.Text- deriving (Show, Eq)+ deriving (Show, Read, Eq) -- | Sent to gateway by our library data GatewaySendableInternal = Heartbeat Integer | Identify Auth GatewayIntent (Int, Int) | Resume Auth T.Text Integer- deriving (Show, Eq, Ord)+ deriving (Show, Read, Eq, Ord) -- | https://discord.com/developers/docs/topics/gateway#list-of-intents@@ -57,7 +57,7 @@ , gatewayIntentDirectMessageChanges :: Bool , gatewayIntentDirectMessageReactions :: Bool , gatewayIntentDirectMessageTyping :: Bool- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance Default GatewayIntent where def = GatewayIntent { gatewayIntentGuilds = True@@ -103,13 +103,13 @@ = RequestGuildMembers RequestGuildMembersOpts | UpdateStatus UpdateStatusOpts | UpdateStatusVoice UpdateStatusVoiceOpts- deriving (Show, Eq, Ord)+ deriving (Show, Read, Eq, Ord) data RequestGuildMembersOpts = RequestGuildMembersOpts { requestGuildMembersOptsGuildId :: GuildId , requestGuildMembersOptsNamesStartingWith :: T.Text , requestGuildMembersOptsLimit :: Integer }- deriving (Show, Eq, Ord)+ deriving (Show, Read, Eq, Ord) data UpdateStatusVoiceOpts = UpdateStatusVoiceOpts { updateStatusVoiceOptsGuildId :: GuildId@@ -117,7 +117,7 @@ , updateStatusVoiceOptsIsMuted :: Bool , updateStatusVoiceOptsIsDeaf :: Bool }- deriving (Show, Eq, Ord)+ deriving (Show, Read, Eq, Ord) data UpdateStatusOpts = UpdateStatusOpts { updateStatusOptsSince :: Maybe UTCTime@@ -125,20 +125,20 @@ , updateStatusOptsNewStatus :: UpdateStatusType , updateStatusOptsAFK :: Bool }- deriving (Show, Eq, Ord)+ deriving (Show, Read, Eq, Ord) data Activity = Activity { activityName :: T.Text , activityType :: ActivityType , activityUrl :: Maybe T.Text }- deriving (Show, Eq, Ord)+ deriving (Show, Read, Eq, Ord) data ActivityType = ActivityTypeGame | ActivityTypeStreaming | ActivityTypeListening | ActivityTypeCompeting- deriving (Show, Eq, Ord)+ deriving (Show, Read, Eq, Ord) activityTypeId :: ActivityType -> Int activityTypeId a = case a of ActivityTypeGame -> 0@@ -151,7 +151,7 @@ | UpdateStatusAwayFromKeyboard | UpdateStatusInvisibleOffline | UpdateStatusOffline- deriving (Show, Eq, Ord, Enum)+ deriving (Show, Read, Eq, Ord, Enum) statusString :: UpdateStatusType -> T.Text statusString s = case s of@@ -169,7 +169,7 @@ ejson <- o .: "d" case ejson of Object hm -> Dispatch <$> eventParse etype hm <*> o .: "s"- _other -> Dispatch (UnknownEvent ("Dispatch payload wasn't an object") o)+ _other -> Dispatch (InternalUnknownEvent ("Dispatch payload wasn't an object") o) <$> o .: "s" 1 -> HeartbeatRequest . fromMaybe 0 . readMaybe <$> o .: "d" 7 -> pure Reconnect
src/Discord/Internal/Types/Guild.hs view
@@ -20,7 +20,7 @@ , memberJoinedAt :: UTCTime , memberDeaf :: Bool , memberMute :: Bool- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON GuildMember where parseJSON = withObject "GuildMember" $ \o ->@@ -56,7 +56,7 @@ , guildFeatures :: [T.Text] , guildMultiFactAuth :: !Integer , guildApplicationId :: Maybe Snowflake- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON Guild where parseJSON = withObject "Guild" $ \o ->@@ -82,7 +82,7 @@ data GuildUnavailable = GuildUnavailable { idOnceAvailable :: GuildId- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON GuildUnavailable where parseJSON = withObject "GuildUnavailable" $ \o ->@@ -96,7 +96,7 @@ , guildMembers :: [GuildMember] , guildChannels :: [Channel] -- ^ Channels in the guild (sent in GuildCreate) -- , guildPresences :: [Presence]- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON GuildInfo where parseJSON = withObject "GuildInfo" $ \o ->@@ -113,7 +113,7 @@ , partialGuildIcon :: Maybe T.Text , partialGuildOwner :: Bool , partialGuildPermissions :: Integer- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON PartialGuild where parseJSON = withObject "PartialGuild" $ \o ->@@ -138,7 +138,7 @@ , rolePerms :: Integer -- ^ Permission bit set , roleManaged :: Bool -- ^ Whether this role is managed by an integration , roleMention :: Bool -- ^ Whether this role is mentionable- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON Role where parseJSON = withObject "Role" $ \o ->@@ -159,7 +159,7 @@ , voiceRegionOptimal :: Bool -- ^ True for the closest server to a client , voiceRegionDeprecated :: Bool -- ^ Whether this is a deprecated region , voiceRegionCustom :: Bool -- ^ Whether this is a custom region- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON VoiceRegion where parseJSON = withObject "VoiceRegion" $ \o ->@@ -174,7 +174,7 @@ data GuildBan = GuildBan { guildBanReason :: T.Text , guildBanUser :: User- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON GuildBan where parseJSON = withObject "GuildBan" $ \o -> GuildBan <$> o .: "reason" <*> o .: "user"@@ -184,7 +184,7 @@ { inviteCode :: T.Text -- ^ The invite code , inviteGuildId :: Maybe GuildId -- ^ The guild the code will invite to , inviteChannelId :: ChannelId -- ^ The channel the code will invite to- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON Invite where parseJSON = withObject "Invite" $ \o ->@@ -209,7 +209,7 @@ , inviteTemp :: Bool -- ^ Whether this invite only grants temporary membership , inviteCreated :: UTCTime -- ^ When the invite was created , inviteRevoked :: Bool -- ^ If the invite is revoked- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON InviteMeta where parseJSON = withObject "InviteMeta" $ \o ->@@ -234,7 +234,7 @@ , integrationOwner :: User -- ^ The user of the integration , integrationAccount :: IntegrationAccount -- ^ The account the integration links to , integrationSync :: UTCTime -- ^ When the integration was last synced- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON Integration where parseJSON = withObject "Integration" $ \o ->@@ -254,7 +254,7 @@ data IntegrationAccount = IntegrationAccount { accountId :: T.Text -- ^ The id of the account. , accountName :: T.Text -- ^ The name of the account.- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON IntegrationAccount where parseJSON = withObject "IntegrationAccount" $ \o ->@@ -264,7 +264,7 @@ data GuildEmbed = GuildEmbed { embedEnabled :: Bool -- ^ Whether the embed is enabled , embedChannel :: ChannelId -- ^ The embed channel id- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON GuildEmbed where parseJSON = withObject "GuildEmbed" $ \o ->
src/Discord/Internal/Types/Prelude.hs view
@@ -18,7 +18,7 @@ -- | Authorization token for the Discord API data Auth = Auth T.Text- deriving (Show, Eq, Ord)+ deriving (Show, Read, Eq, Ord) -- | Get the raw token formatted for use with the websocket gateway
src/Discord/Internal/Types/User.hs view
@@ -20,7 +20,7 @@ , 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.- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON User where parseJSON = withObject "User" $ \o ->@@ -51,7 +51,7 @@ { webhookId :: WebhookId , webhookToken :: Text , webhookChannelId :: ChannelId- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON Webhook where parseJSON = withObject "Webhook" $ \o ->@@ -69,7 +69,7 @@ , connectionObjectFriendSyncOn :: Bool , connectionObjectShownInPresenceUpdates :: Bool , connectionObjectVisibleToOthers :: Bool- } deriving (Show, Eq, Ord)+ } deriving (Show, Read, Eq, Ord) instance FromJSON ConnectionObject where parseJSON = withObject "ConnectionObject" $ \o -> do
src/Discord/Types.hs view
@@ -3,6 +3,7 @@ ) where import Discord.Internal.Types hiding- ( GatewaySendableInternal- , GatewayReceivable+ ( GatewaySendableInternal(..)+ , GatewayReceivable(..)+ , EventInternalParse(..) )