twitchapi-0.0.3: src/Web/TwitchAPI/Helix/ChannelPoints.hs
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Web.TwitchAPI.Helix.ChannelPoints where
import Prelude
import qualified Data.ByteString.Char8 as BS
import qualified Data.Time as Time
import qualified Data.Time.RFC3339 as Time ( parseTimeRFC3339 )
import qualified Data.Text as Text
import qualified Network.HTTP.Client as HTTP
import Data.Maybe ( fromMaybe )
import Data.Aeson ( FromJSON(..), (.:), withObject
, ToJSON(..), (.=), object, encode
, Object
)
import qualified Web.TwitchAPI.Helix.Request as Req
class RewardDetails a where
broadcasterId :: a -> Integer
prompt :: a -> Maybe String
backgroundColor :: a -> String
maxPerStream :: a -> Maybe Integer
maxPerUser :: a -> Maybe Integer
autoFulfilled :: a -> Bool
data Create = Create { forBroadcasterId :: Integer
, title :: String
, setPrompt :: Maybe String
, cost :: Integer
, enabled :: Maybe Bool
, setBackgroundColor :: Maybe String
, setMaxPerStream :: Maybe Integer
, setMaxPerUser :: Maybe Integer
, cooldownSeconds :: Maybe Integer
, setAutoFulfilled :: Maybe Bool
} deriving ( Show, Eq )
instance ToJSON Create where
toJSON Create{..} =
object [ "title" .= Text.pack title
, "prompt" .= (Text.pack <$> setPrompt)
, "cost" .= cost
, "is_enabled" .= fromMaybe True enabled
, "background_color" .= (Text.pack <$> setBackgroundColor)
, "is_user_input_required" .= fmap (const True) setPrompt
, "is_max_per_stream_enabled" .= fmap (const True) setMaxPerStream
, "max_per_stream" .= setMaxPerStream
, "is_max_per_user_per_stream_enabled" .= fmap (const True) setMaxPerUser
, "max_per_user_per_stream" .= setMaxPerUser
, "is_global_cooldown_enabled" .= fmap (const True) cooldownSeconds
, "global_cooldown_seconds" .= cooldownSeconds
, "should_redemptions_skip_request_queue" .= setAutoFulfilled
]
instance Req.HelixRequest Create where
toRequest create =
let setQuery = HTTP.setQueryString [("broadcaster_id", Just . BS.pack . show $ (broadcasterId :: Create -> Integer) create)]
setBody r = r{ HTTP.requestBody = HTTP.RequestBodyLBS . encode . toJSON $ create }
in setBody . setQuery $ HTTP.parseRequest_ "POST https://api.twitch.tv/helix/channel_points/custom_rewards"
scope Create{} = Just "channel:manage:redemptions"
instance RewardDetails Create where
broadcasterId = forBroadcasterId
prompt = setPrompt
backgroundColor = fromMaybe "" . setBackgroundColor
maxPerStream = setMaxPerStream
maxPerUser = setMaxPerUser
autoFulfilled = fromMaybe False . setAutoFulfilled
data RewardImages = RewardImages { tiny :: Maybe String
, large :: Maybe String
, huge :: Maybe String
} deriving ( Show, Eq )
instance FromJSON RewardImages where
parseJSON = withObject "RewardImages" $ \o -> do
tiny <- o .: "url_1x"
large <- o .: "url_2x"
huge <- o .: "url_4x"
return RewardImages{..}
data CreateResponse = CreateResponse { broadcaster :: Integer
, broadcasterLogin :: String
, broadcasterName :: String
, rewardId :: String
, rewardTitle :: String
, rewardPrompt :: Maybe String
, rewardCost :: Integer
, rewardImage :: Maybe RewardImages
, defaultImage :: RewardImages
, rewardBackgroundColor :: String
, rewardMaxPerStream :: Maybe Integer
, rewardMaxPerUser :: Maybe Integer
, cooldown :: Maybe Integer
, paused :: Bool
, inStock :: Bool
, rewardAutoFulfilled :: Bool
, redemptionCount :: Integer
, cooldownExpires :: Maybe Time.UTCTime
} deriving ( Show, Eq )
instance FromJSON CreateResponse where
parseJSON = withObject "CreateResponse" $ \o -> do
bid <- o .: "broadcaster_id"
let broadcaster = read bid :: Integer
broadcasterLogin <- o .: "broadcaster_login"
broadcasterName <- o .: "broadcaster_name"
rewardId <- o .: "id"
rewardTitle <- o .: "title"
promptText <- o .: "prompt"
promptEnabled :: Bool <- o .: "is_user_input_required"
let rewardPrompt = if promptEnabled then Just promptText else Nothing
rewardCost <- o .: "cost"
rewardImage <- o .: "image"
defaultImage <- o .: "default_image"
rewardBackgroundColor <- o .: "background_color"
maxObject :: Object <- o .: "max_per_stream_setting"
maxEnabled <- maxObject .: "is_enabled"
streamMax <- maxObject .: "max_per_stream"
let rewardMaxPerStream = if maxEnabled then Just streamMax else Nothing
userMaxObject :: Object <- o .: "max_per_user_per_stream_setting"
userMaxEnabled <- userMaxObject .: "is_enabled"
userMax <- userMaxObject .: "max_per_user_per_stream"
let rewardMaxPerUser = if userMaxEnabled then Just userMax else Nothing
cooldownObject :: Object <- o .: "global_cooldown_setting"
cooldownEnabled <- cooldownObject .: "is_enabled"
cooldownSeconds <- cooldownObject .: "global_cooldown_seconds"
let cooldown = if cooldownEnabled then Just cooldownSeconds else Nothing
paused <- o .: "is_paused"
inStock <- o .: "is_in_stock"
rewardAutoFulfilled <- o .: "should_redemptions_skip_request_queue"
redemptionCount <- o .: "redemptions_redeemed_current_stream"
cooldownExpiry :: Maybe String <- o .: "cooldown_expires_at"
let cooldownExpires = Time.zonedTimeToUTC <$> (Time.parseTimeRFC3339 =<< cooldownExpiry)
return CreateResponse{..}
instance RewardDetails CreateResponse where
broadcasterId = broadcaster
prompt = rewardPrompt
backgroundColor = rewardBackgroundColor
maxPerStream = rewardMaxPerStream
maxPerUser = rewardMaxPerUser
autoFulfilled = rewardAutoFulfilled