module Network.Discord.Types.Gateway where
import Control.Monad (mzero)
import System.Info
import Data.Aeson
import Data.Aeson.Types
import Network.Discord.Types.Prelude
data Payload
= Dispatch
Object
Integer
String
| Heartbeat
Integer
| Identify
Auth
Bool
Integer
(Int, Int)
| StatusUpdate
(Maybe Integer)
(Maybe String)
| VoiceStatusUpdate
!Snowflake
!(Maybe Snowflake)
Bool
Bool
| Resume
String
String
Integer
| Reconnect
| RequestGuildMembers
!Snowflake
String
Integer
| InvalidSession
| Hello
Int
| HeartbeatAck
| ParseError String
deriving Show
instance FromJSON Payload where
parseJSON = withObject "payload" $ \o -> do
op <- o .: "op" :: Parser Int
case op of
0 -> Dispatch <$> o .: "d" <*> o .: "s" <*> o .: "t"
1 -> Heartbeat <$> o .: "d"
7 -> return Reconnect
9 -> return InvalidSession
10 -> (\od -> Hello <$> od .: "heartbeat_interval") =<< o .: "d"
11 -> return HeartbeatAck
_ -> mzero
instance ToJSON Payload where
toJSON (Heartbeat i) = object [ "op" .= (1 :: Int), "d" .= i ]
toJSON (Identify token compress large shard) = object [
"op" .= (2 :: Int)
, "d" .= object [
"token" .= authToken token
, "properties" .= object [
"$os" .= os
, "$browser" .= ("discord.hs" :: String)
, "$device" .= ("discord.hs" :: String)
, "$referrer" .= ("" :: String)
, "$referring_domain" .= ("" :: String)
]
, "compress" .= compress
, "large_threshold" .= large
, "shard" .= shard
]
]
toJSON (StatusUpdate idle game) = object [
"op" .= (3 :: Int)
, "d" .= object [
"idle_since" .= idle
, "game" .= object [
"name" .= game
]
]
]
toJSON (VoiceStatusUpdate guild channel mute deaf) = object [
"op" .= (4 :: Int)
, "d" .= object [
"guild_id" .= guild
, "channel_id" .= channel
, "self_mute" .= mute
, "self_deaf" .= deaf
]
]
toJSON (Resume token session seqId) = object [
"op" .= (6 :: Int)
, "d" .= object [
"token" .= token
, "session_id" .= session
, "seq" .= seqId
]
]
toJSON (RequestGuildMembers guild query limit) = object [
"op" .= (8 :: Int)
, "d" .= object [
"guild_id" .= guild
, "query" .= query
, "limit" .= limit
]
]
toJSON _ = object []