twitchapi-0.0.1: src/Web/TwitchAPI/Helix/Bits.hs
{-# LANGUAGE DuplicateRecordFields #-}
{-# 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.Maybe ( fromMaybe )
import Data.Aeson ( FromJSON(..), (.:), withObject
, Object
)
import qualified Web.TwitchAPI.Helix.Request as Req
data Leaderboard = Leaderboard { count :: Maybe Integer
, period :: Maybe Period
, startedAt :: Maybe Time.UTCTime
, userId :: 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)] = fromMaybe [] $ (\c -> ("count", Just . BS.pack . show $ c):[]) <$> (count leaderboard)
period' :: [(BS.ByteString, Maybe BS.ByteString)] = fromMaybe [] $ (\p -> ("period", Just . BS.pack . show $ p):[]) <$> (period leaderboard)
startedAt' :: [(BS.ByteString, Maybe BS.ByteString)] = fromMaybe [] $ (\s -> ("started_at", Just . Text.encodeUtf8 $ (Time.formatTimeRFC3339 $ Time.utcToZonedTime Time.utc s :: Text.Text)):[]) <$> ((startedAt :: Leaderboard -> Maybe Time.UTCTime) leaderboard)
userId' :: [(BS.ByteString, Maybe BS.ByteString)] = fromMaybe [] $ (\u -> ("user_id", Just . Text.encodeUtf8 . Text.pack . show $ u):[]) <$> ((userId :: Leaderboard -> Maybe Integer) leaderboard)
setQuery = HTTP.setQueryString $ foldl (++) [] [count', period', startedAt', userId']
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{..}
data 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{..}