twitchapi-0.0.3: src/Web/TwitchAPI/Helix/Bits.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Web.TwitchAPI.Helix.Bits where
import Prelude
import qualified Data.ByteString.Char8 as BS
import qualified Data.Time as Time
import qualified Data.Time.RFC3339 as Time ( formatTimeRFC3339, parseTimeRFC3339 )
import qualified Data.Text as Text
import qualified Data.Text.Encoding as Text ( encodeUtf8 )
import qualified Network.HTTP.Client as HTTP
import Data.Aeson ( FromJSON(..), (.:), withObject
, Object
)
import qualified Web.TwitchAPI.Helix.Request as Req
data Leaderboard = Leaderboard { count :: Maybe Integer
, period :: Maybe Period
, start :: Maybe Time.UTCTime
, searchId :: Maybe Integer
} deriving ( Show, Eq )
data Period = Day | Week | Month | Year | All deriving ( Eq )
instance Show Period where
show Day = "day"
show Week = "week"
show Month = "month"
show Year = "year"
show All = "all"
instance Req.HelixRequest Leaderboard where
toRequest leaderboard =
let count' :: [(BS.ByteString, Maybe BS.ByteString)] = maybe [] (\c -> [("count", Just . BS.pack . show $ c)]) (count leaderboard)
period' :: [(BS.ByteString, Maybe BS.ByteString)] = maybe [] (\p -> [("period", Just . BS.pack . show $ p)]) (period leaderboard)
start' :: [(BS.ByteString, Maybe BS.ByteString)] = maybe [] (\s -> [("started_at", Just . Text.encodeUtf8 $ (Time.formatTimeRFC3339 $ Time.utcToZonedTime Time.utc s :: Text.Text))]) (start leaderboard)
searchId' :: [(BS.ByteString, Maybe BS.ByteString)] = maybe [] (\u -> [("user_id", Just . Text.encodeUtf8 . Text.pack . show $ u)]) (searchId leaderboard)
setQuery = HTTP.setQueryString $ concat [count', period', start', searchId']
in setQuery $ HTTP.parseRequest_ "GET https://api.twitch.tv/helix/bits/leaderboard"
scope Leaderboard{} = Just "bits:read"
data LeaderboardEntry = LeaderboardEntry { userId :: Integer
, userLogin :: String
, userName :: String
, rank :: Integer
, score :: Integer
} deriving ( Show, Eq )
instance FromJSON LeaderboardEntry where
parseJSON = withObject "LeaderboardEntry" $ \o -> do
uid <- o .: "user_id"
userLogin <- o .: "user_login"
userName <- o .: "user_login"
rank <- o .: "rank"
score <- o .: "score"
let userId = read uid :: Integer
return LeaderboardEntry{..}
data LeaderboardResponse = LeaderboardResponse { endedAt :: Maybe Time.UTCTime
, startedAt :: Maybe Time.UTCTime
, total :: Integer
, entries :: [LeaderboardEntry]
} deriving ( Show, Eq)
instance FromJSON LeaderboardResponse where
parseJSON = withObject "LeaderboardResponse" $ \o -> do
dates :: Object <- o .: "date_range"
ended :: String <- dates .: "ended_at"
started :: String <- dates .: "started_at"
entries :: [LeaderboardEntry] <- o .: "data"
total <- o .: "total"
let endedAt = Time.zonedTimeToUTC <$> Time.parseTimeRFC3339 ended
startedAt = Time.zonedTimeToUTC <$> Time.parseTimeRFC3339 started
return LeaderboardResponse{..}
newtype Cheermotes = Cheermotes { broadcasterId :: Integer } deriving ( Show, Eq )
instance Req.HelixRequest Cheermotes where
toRequest c =
let setQuery = HTTP.setQueryString [("broadcaster_id", Just . BS.pack . show $ (broadcasterId :: Cheermotes -> Integer) c)]
in setQuery $ HTTP.parseRequest_ "GET https://api.twitch.tv/helix/bits/leaderboard"
scope Cheermotes{} = Nothing
data CheermoteClass = GlobalFirstParty | GlobalThirdParty | ChannelCustom | DisplayOnly | Sponsored | Unknown deriving ( Eq, Show )
instance Read CheermoteClass where
readsPrec _ "global_first_party" = [(GlobalFirstParty, "")]
readsPrec _ "global_third_party" = [(GlobalThirdParty, "")]
readsPrec _ "channel_custom" = [(ChannelCustom, "")]
readsPrec _ "display_only" = [(DisplayOnly, "")]
readsPrec _ "sponsored" = [(Sponsored, "")]
readsPrec _ _ = [(Unknown, "")]
data CheermoteData = CheermoteData { tinyURI :: Maybe String
, smallURI :: Maybe String
, mediumURI :: Maybe String
, largeURI :: Maybe String
, hugeURI :: Maybe String
} deriving ( Eq, Show )
instance FromJSON CheermoteData where
parseJSON = withObject "CheermoteData" $ \o -> do
tinyURI <- o .: "1"
smallURI <- o .: "1.5"
mediumURI <- o .: "2"
largeURI <- o .: "3"
hugeURI <- o .: "4"
return CheermoteData{..}
data CheermoteImages = CheermoteImages { darkAnimated :: CheermoteData
, darkStatic :: CheermoteData
, lightAnimated :: CheermoteData
, lightStatic :: CheermoteData
} deriving ( Eq, Show )
instance FromJSON CheermoteImages where
parseJSON = withObject "CheermoteImages" $ \o -> do
dark :: Object <- o .: "dark"
light :: Object <- o .: "light"
darkAnimated <- dark .: "animated"
darkStatic <- dark .: "static"
lightAnimated <- light .: "animated"
lightStatic <- light .: "static"
return CheermoteImages{..}
data CheermoteTier = CheermoteTier { minBits :: Integer
, cheermoteId :: Integer
, color :: String
, images :: CheermoteImages
, enabled :: Bool
, visible :: Bool
} deriving ( Eq, Show )
instance FromJSON CheermoteTier where
parseJSON = withObject "CheermoteTier" $ \o -> do
minBits <- o .: "min_bits"
cheermoteId <- o .: "id"
color <- o .: "color"
images <- o .: "images"
enabled <- o .: "can_cheer"
visible <- o .: "show_in_bits_card"
return CheermoteTier{..}
data CheermotesResponse = CheermotesResponse { prefix :: String
, tiers :: [CheermoteTier]
, cheermoteType :: String
, order :: Integer
, lastUpdated :: Maybe Time.UTCTime
, charitable :: Bool
} deriving ( Eq, Show )
instance FromJSON CheermotesResponse where
parseJSON = withObject "CheermotesResponse" $ \o -> do
updated :: String <- o .: "last_updated"
let lastUpdated = Time.zonedTimeToUTC <$> Time.parseTimeRFC3339 updated
prefix <- o .: "prefix"
tiers <- o .: "tiers"
cheermoteType <- o .: "type"
order <- o .: "order"
charitable <- o .: "is_charitable"
return CheermotesResponse{..}