{-# LANGUAGE DeriveGeneric         #-}
{-# LANGUAGE LambdaCase            #-}
{-# LANGUAGE RecordWildCards       #-}
{-# LANGUAGE OverloadedStrings     #-}
{-# LANGUAGE ScopedTypeVariables   #-}

{- |
Module      :  TwitchAPI.PubSub
Copyright   :  (c) Christina Wuest 2021
License     :  BSD-style

Maintainer  :  tina@wuest.me
Stability   :  experimental
Portability :  non-portable

Messages sent over Twitch's PubSub interface.
-}

module Web.TwitchAPI.PubSub where

import Prelude


import qualified Data.Aeson            as JSON
import qualified Data.Maybe            as Maybe
import qualified Data.Time             as Time
import qualified Data.Time.RFC3339     as Time ( parseTimeRFC3339 )
import qualified Data.Time.Clock.POSIX as Time ( posixSecondsToUTCTime )

import Data.Aeson ( FromJSON(..), (.:), (.:?), withObject, withText, withEmbeddedJSON
                  , ToJSON(..), (.=), object
                  , Object
                  )

import Control.Monad ( mzero )
import GHC.Generics  ( Generic )

import qualified Data.Aeson.Types as JSON.Types

data Topic = BitsV1 { Topic -> Integer
channel :: Integer }
           | BitsV2 { channel :: Integer }
           | BitsBadge { channel :: Integer }
           | ChannelPoints { channel :: Integer }
           | ChannelSubscriptions { channel :: Integer }
           | ChatModeratorActions { channel :: Integer, Topic -> Integer
user :: Integer }
           | Whispers { user :: Integer }
           deriving ( Topic -> Topic -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Topic -> Topic -> Bool
$c/= :: Topic -> Topic -> Bool
== :: Topic -> Topic -> Bool
$c== :: Topic -> Topic -> Bool
Eq, Int -> Topic -> ShowS
[Topic] -> ShowS
Topic -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Topic] -> ShowS
$cshowList :: [Topic] -> ShowS
show :: Topic -> String
$cshow :: Topic -> String
showsPrec :: Int -> Topic -> ShowS
$cshowsPrec :: Int -> Topic -> ShowS
Show )

toRequest :: Topic -> String
toRequest :: Topic -> String
toRequest BitsV1{Integer
channel :: Integer
channel :: Topic -> Integer
..} = (String
"channel-bits-events-v1." forall a. [a] -> [a] -> [a]
++) forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show Integer
channel
toRequest BitsV2{Integer
channel :: Integer
channel :: Topic -> Integer
..} = (String
"channel-bits-events-v2." forall a. [a] -> [a] -> [a]
++) forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show Integer
channel
toRequest BitsBadge{Integer
channel :: Integer
channel :: Topic -> Integer
..} = (String
"channel-bits-badge-unlocks." forall a. [a] -> [a] -> [a]
++) forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show Integer
channel
toRequest ChannelPoints{Integer
channel :: Integer
channel :: Topic -> Integer
..} = (String
"channel-points-channel-v1." forall a. [a] -> [a] -> [a]
++) forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show Integer
channel
toRequest ChannelSubscriptions{Integer
channel :: Integer
channel :: Topic -> Integer
..} = (String
"channel-subscribe-events-v1." forall a. [a] -> [a] -> [a]
++) forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show Integer
channel
toRequest ChatModeratorActions{Integer
user :: Integer
channel :: Integer
user :: Topic -> Integer
channel :: Topic -> Integer
..} = String
"chat_moderator_actions." forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Integer
user forall a. [a] -> [a] -> [a]
++ String
"." forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Integer
channel
toRequest Whispers{Integer
user :: Integer
user :: Topic -> Integer
..} = (String
"whispers." forall a. [a] -> [a] -> [a]
++) forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show Integer
user

scope :: Topic -> String
scope :: Topic -> String
scope BitsV1{} = String
"bits:read"
scope BitsV2{} = String
"bits:read"
scope BitsBadge{} = String
"bits:read"
scope ChannelPoints{} = String
"channel:read:redemptions"
scope ChannelSubscriptions{} = String
"channel:read:subscriptions"
scope ChatModeratorActions{} = String
"channel:moderate"
scope Whispers{} = String
"whispers:read"

data RequestType = Listen | Unlisten deriving ( RequestType -> RequestType -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RequestType -> RequestType -> Bool
$c/= :: RequestType -> RequestType -> Bool
== :: RequestType -> RequestType -> Bool
$c== :: RequestType -> RequestType -> Bool
Eq )

instance Show RequestType where
    show :: RequestType -> String
show RequestType
Listen   = String
"LISTEN"
    show RequestType
Unlisten = String
"UNLISTEN"

data Request = Request { Request -> RequestType
requestType :: RequestType
                       , Request -> Maybe String
requestNonce :: Maybe String
                       , Request -> [Topic]
topics :: [Topic]
                       , Request -> String
authToken :: String
                       } deriving ( Request -> Request -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Request -> Request -> Bool
$c/= :: Request -> Request -> Bool
== :: Request -> Request -> Bool
$c== :: Request -> Request -> Bool
Eq, Int -> Request -> ShowS
[Request] -> ShowS
Request -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Request] -> ShowS
$cshowList :: [Request] -> ShowS
show :: Request -> String
$cshow :: Request -> String
showsPrec :: Int -> Request -> ShowS
$cshowsPrec :: Int -> Request -> ShowS
Show )

instance ToJSON Request where
    toJSON :: Request -> Value
toJSON Request{String
[Topic]
Maybe String
RequestType
authToken :: String
topics :: [Topic]
requestNonce :: Maybe String
requestType :: RequestType
authToken :: Request -> String
topics :: Request -> [Topic]
requestNonce :: Request -> Maybe String
requestType :: Request -> RequestType
..} =
        [Pair] -> Value
object [ Key
"type" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= forall a. Show a => a -> String
show RequestType
requestType
               , Key
"nonce" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe String
requestNonce
               , Key
"data" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= [Pair] -> Value
object [ Key
"topics" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= (Topic -> String
toRequest forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Topic]
topics)
                                  , Key
"auth_token" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= String
authToken
                                  ]
               ]

data RequestError = BadMessage | BadAuth | ServerFail | BadTopic | None deriving ( RequestError -> RequestError -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RequestError -> RequestError -> Bool
$c/= :: RequestError -> RequestError -> Bool
== :: RequestError -> RequestError -> Bool
$c== :: RequestError -> RequestError -> Bool
Eq, Int -> RequestError -> ShowS
[RequestError] -> ShowS
RequestError -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RequestError] -> ShowS
$cshowList :: [RequestError] -> ShowS
show :: RequestError -> String
$cshow :: RequestError -> String
showsPrec :: Int -> RequestError -> ShowS
$cshowsPrec :: Int -> RequestError -> ShowS
Show )

instance Read RequestError where
    readsPrec :: Int -> ReadS RequestError
readsPrec Int
_ String
"ERR_BADMESSAGE" = [(RequestError
BadMessage, String
"")]
    readsPrec Int
_ String
"ERR_BADAUTH"    = [(RequestError
BadAuth, String
"")]
    readsPrec Int
_ String
"ERR_SERVER"     = [(RequestError
ServerFail, String
"")]
    readsPrec Int
_ String
"ERR_BADTOPIC"   = [(RequestError
BadTopic, String
"")]
    readsPrec Int
_ String
_                = [(RequestError
None, String
"")]

data Response = Response { Response -> Maybe String
responseNonce :: Maybe String
                         , Response -> RequestError
errorReported :: RequestError
                         } deriving ( Int -> Response -> ShowS
[Response] -> ShowS
Response -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Response] -> ShowS
$cshowList :: [Response] -> ShowS
show :: Response -> String
$cshow :: Response -> String
showsPrec :: Int -> Response -> ShowS
$cshowsPrec :: Int -> Response -> ShowS
Show, Response -> Response -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Response -> Response -> Bool
$c/= :: Response -> Response -> Bool
== :: Response -> Response -> Bool
$c== :: Response -> Response -> Bool
Eq )

instance FromJSON Response where
    parseJSON :: Value -> Parser Response
parseJSON = forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"Response" forall a b. (a -> b) -> a -> b
$ \Object
o ->
        Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"type" forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \(String
reportedType :: String) ->
        -- This value is required per Twitch or else any response is invalid
        if String
reportedType forall a. Eq a => a -> a -> Bool
== String
"RESPONSE" then do
            Maybe String
responseNonce <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"nonce"
            String
err <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"error"
            let errorReported :: RequestError
errorReported = forall a. Read a => String -> a
read String
err :: RequestError
            forall (m :: * -> *) a. Monad m => a -> m a
return Response{Maybe String
RequestError
errorReported :: RequestError
responseNonce :: Maybe String
errorReported :: RequestError
responseNonce :: Maybe String
..}
        else forall (m :: * -> *) a. MonadPlus m => m a
mzero

-- Used for Channel Points rewards
data RewardImages = RewardImages { RewardImages -> Maybe String
tiny :: Maybe String
                                 , RewardImages -> Maybe String
large :: Maybe String
                                 , RewardImages -> Maybe String
huge :: Maybe String
                                 } deriving ( Int -> RewardImages -> ShowS
[RewardImages] -> ShowS
RewardImages -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RewardImages] -> ShowS
$cshowList :: [RewardImages] -> ShowS
show :: RewardImages -> String
$cshow :: RewardImages -> String
showsPrec :: Int -> RewardImages -> ShowS
$cshowsPrec :: Int -> RewardImages -> ShowS
Show, RewardImages -> RewardImages -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RewardImages -> RewardImages -> Bool
$c/= :: RewardImages -> RewardImages -> Bool
== :: RewardImages -> RewardImages -> Bool
$c== :: RewardImages -> RewardImages -> Bool
Eq, forall x. Rep RewardImages x -> RewardImages
forall x. RewardImages -> Rep RewardImages x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep RewardImages x -> RewardImages
$cfrom :: forall x. RewardImages -> Rep RewardImages x
Generic )

instance FromJSON RewardImages where
    parseJSON :: Value -> Parser RewardImages
parseJSON = forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"RewardImages" forall a b. (a -> b) -> a -> b
$ \Object
o -> do
        Maybe String
tiny <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"url_1x"
        Maybe String
large <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"url_2x"
        Maybe String
huge <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"url_4x"
        forall (m :: * -> *) a. Monad m => a -> m a
return RewardImages{Maybe String
huge :: Maybe String
large :: Maybe String
tiny :: Maybe String
huge :: Maybe String
large :: Maybe String
tiny :: Maybe String
..}

data UserInfo = UserInfo { UserInfo -> Integer
userId :: Integer
                         , UserInfo -> String
userName :: String
                         , UserInfo -> Maybe String
displayName :: Maybe String
                         } deriving ( UserInfo -> UserInfo -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: UserInfo -> UserInfo -> Bool
$c/= :: UserInfo -> UserInfo -> Bool
== :: UserInfo -> UserInfo -> Bool
$c== :: UserInfo -> UserInfo -> Bool
Eq, Int -> UserInfo -> ShowS
[UserInfo] -> ShowS
UserInfo -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [UserInfo] -> ShowS
$cshowList :: [UserInfo] -> ShowS
show :: UserInfo -> String
$cshow :: UserInfo -> String
showsPrec :: Int -> UserInfo -> ShowS
$cshowsPrec :: Int -> UserInfo -> ShowS
Show, forall x. Rep UserInfo x -> UserInfo
forall x. UserInfo -> Rep UserInfo x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep UserInfo x -> UserInfo
$cfrom :: forall x. UserInfo -> Rep UserInfo x
Generic )

instance FromJSON UserInfo where
    parseJSON :: Value -> Parser UserInfo
parseJSON = forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"UserInfo" forall a b. (a -> b) -> a -> b
$ \Object
o -> do
        String
userId' <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"id"
        let userId :: Integer
userId = forall a. Read a => String -> a
read String
userId' :: Integer
        String
userName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"login"
        Maybe String
displayName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"display_name"
        forall (m :: * -> *) a. Monad m => a -> m a
return UserInfo{Integer
String
Maybe String
displayName :: Maybe String
userName :: String
userId :: Integer
displayName :: Maybe String
userName :: String
userId :: Integer
..}

data RewardStatus = Fulfilled | Unfulfilled deriving ( RewardStatus -> RewardStatus -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RewardStatus -> RewardStatus -> Bool
$c/= :: RewardStatus -> RewardStatus -> Bool
== :: RewardStatus -> RewardStatus -> Bool
$c== :: RewardStatus -> RewardStatus -> Bool
Eq, Int -> RewardStatus -> ShowS
[RewardStatus] -> ShowS
RewardStatus -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RewardStatus] -> ShowS
$cshowList :: [RewardStatus] -> ShowS
show :: RewardStatus -> String
$cshow :: RewardStatus -> String
showsPrec :: Int -> RewardStatus -> ShowS
$cshowsPrec :: Int -> RewardStatus -> ShowS
Show, forall x. Rep RewardStatus x -> RewardStatus
forall x. RewardStatus -> Rep RewardStatus x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep RewardStatus x -> RewardStatus
$cfrom :: forall x. RewardStatus -> Rep RewardStatus x
Generic )

instance Read RewardStatus where
    readsPrec :: Int -> ReadS RewardStatus
readsPrec Int
_ String
"FULFILLED" = [(RewardStatus
Fulfilled, String
"")]
    readsPrec Int
_ String
_ = [(RewardStatus
Unfulfilled, String
"")]


data BadgeUnlock = BadgeUnlock { BadgeUnlock -> Integer
newVersion :: Integer
                               , BadgeUnlock -> Integer
previousVersion :: Integer
                               } deriving ( BadgeUnlock -> BadgeUnlock -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BadgeUnlock -> BadgeUnlock -> Bool
$c/= :: BadgeUnlock -> BadgeUnlock -> Bool
== :: BadgeUnlock -> BadgeUnlock -> Bool
$c== :: BadgeUnlock -> BadgeUnlock -> Bool
Eq, Int -> BadgeUnlock -> ShowS
[BadgeUnlock] -> ShowS
BadgeUnlock -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BadgeUnlock] -> ShowS
$cshowList :: [BadgeUnlock] -> ShowS
show :: BadgeUnlock -> String
$cshow :: BadgeUnlock -> String
showsPrec :: Int -> BadgeUnlock -> ShowS
$cshowsPrec :: Int -> BadgeUnlock -> ShowS
Show, forall x. Rep BadgeUnlock x -> BadgeUnlock
forall x. BadgeUnlock -> Rep BadgeUnlock x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep BadgeUnlock x -> BadgeUnlock
$cfrom :: forall x. BadgeUnlock -> Rep BadgeUnlock x
Generic )

instance FromJSON BadgeUnlock where
    parseJSON :: Value -> Parser BadgeUnlock
parseJSON = forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"BadgeUnlock" forall a b. (a -> b) -> a -> b
$ \Object
o -> do
        Integer
newVersion <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"new_version"
        Integer
previousVersion <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"previous_version"
        forall (m :: * -> *) a. Monad m => a -> m a
return BadgeUnlock{Integer
previousVersion :: Integer
newVersion :: Integer
previousVersion :: Integer
newVersion :: Integer
..}

data SubscriptionTier = Prime | Tier1 | Tier2 | Tier3 deriving ( SubscriptionTier -> SubscriptionTier -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SubscriptionTier -> SubscriptionTier -> Bool
$c/= :: SubscriptionTier -> SubscriptionTier -> Bool
== :: SubscriptionTier -> SubscriptionTier -> Bool
$c== :: SubscriptionTier -> SubscriptionTier -> Bool
Eq, Int -> SubscriptionTier -> ShowS
[SubscriptionTier] -> ShowS
SubscriptionTier -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SubscriptionTier] -> ShowS
$cshowList :: [SubscriptionTier] -> ShowS
show :: SubscriptionTier -> String
$cshow :: SubscriptionTier -> String
showsPrec :: Int -> SubscriptionTier -> ShowS
$cshowsPrec :: Int -> SubscriptionTier -> ShowS
Show, forall x. Rep SubscriptionTier x -> SubscriptionTier
forall x. SubscriptionTier -> Rep SubscriptionTier x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SubscriptionTier x -> SubscriptionTier
$cfrom :: forall x. SubscriptionTier -> Rep SubscriptionTier x
Generic )

instance FromJSON SubscriptionTier where
    parseJSON :: Value -> Parser SubscriptionTier
parseJSON = forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"SubscriptionTier" forall a b. (a -> b) -> a -> b
$ \case
        Text
"1000" -> forall (m :: * -> *) a. Monad m => a -> m a
return SubscriptionTier
Tier1
        Text
"2000" -> forall (m :: * -> *) a. Monad m => a -> m a
return SubscriptionTier
Tier2
        Text
"3000" -> forall (m :: * -> *) a. Monad m => a -> m a
return SubscriptionTier
Tier3
        Text
"Prime" -> forall (m :: * -> *) a. Monad m => a -> m a
return SubscriptionTier
Prime
        Text
_ -> forall (m :: * -> *) a. MonadPlus m => m a
mzero

data EmoteSpec = EmoteSpec { EmoteSpec -> Integer
emoteStart :: Integer
                           , EmoteSpec -> Integer
emoteLength :: Integer
                           , EmoteSpec -> Integer
emoteId :: Integer
                           } deriving ( EmoteSpec -> EmoteSpec -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: EmoteSpec -> EmoteSpec -> Bool
$c/= :: EmoteSpec -> EmoteSpec -> Bool
== :: EmoteSpec -> EmoteSpec -> Bool
$c== :: EmoteSpec -> EmoteSpec -> Bool
Eq, Int -> EmoteSpec -> ShowS
[EmoteSpec] -> ShowS
EmoteSpec -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [EmoteSpec] -> ShowS
$cshowList :: [EmoteSpec] -> ShowS
show :: EmoteSpec -> String
$cshow :: EmoteSpec -> String
showsPrec :: Int -> EmoteSpec -> ShowS
$cshowsPrec :: Int -> EmoteSpec -> ShowS
Show, forall x. Rep EmoteSpec x -> EmoteSpec
forall x. EmoteSpec -> Rep EmoteSpec x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep EmoteSpec x -> EmoteSpec
$cfrom :: forall x. EmoteSpec -> Rep EmoteSpec x
Generic )

instance FromJSON EmoteSpec where
    parseJSON :: Value -> Parser EmoteSpec
parseJSON = forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"EmoteSpec" forall a b. (a -> b) -> a -> b
$ \Object
o -> do
        Integer
emoteStart <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"start"
        Integer
emoteEnd :: Integer <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"end"
        Maybe String
emoteId' :: Maybe String <- Object
o forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"id"
        let emoteLength :: Integer
emoteLength = Integer
1 forall a. Num a => a -> a -> a
+ Integer
emoteEnd forall a. Num a => a -> a -> a
- Integer
emoteStart
        case Maybe String
emoteId' of
            Just String
emoteId'' ->
                let emoteId :: Integer
emoteId = forall a. Read a => String -> a
read String
emoteId'' :: Integer
                in forall (m :: * -> *) a. Monad m => a -> m a
return EmoteSpec{Integer
emoteId :: Integer
emoteLength :: Integer
emoteStart :: Integer
emoteId :: Integer
emoteLength :: Integer
emoteStart :: Integer
..}
            Maybe String
Nothing -> do
                String
altEmoteId :: String <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"emote_id"
                let emoteId :: Integer
emoteId = forall a. Read a => String -> a
read String
altEmoteId :: Integer
                forall (m :: * -> *) a. Monad m => a -> m a
return EmoteSpec{Integer
emoteId :: Integer
emoteLength :: Integer
emoteStart :: Integer
emoteId :: Integer
emoteLength :: Integer
emoteStart :: Integer
..}

data SubscriptionMessage = SubscriptionMessage { SubscriptionMessage -> String
subscriptionMessage :: String
                                               , SubscriptionMessage -> [EmoteSpec]
subscriptionEmotes :: [EmoteSpec]
                                               } deriving ( SubscriptionMessage -> SubscriptionMessage -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SubscriptionMessage -> SubscriptionMessage -> Bool
$c/= :: SubscriptionMessage -> SubscriptionMessage -> Bool
== :: SubscriptionMessage -> SubscriptionMessage -> Bool
$c== :: SubscriptionMessage -> SubscriptionMessage -> Bool
Eq, Int -> SubscriptionMessage -> ShowS
[SubscriptionMessage] -> ShowS
SubscriptionMessage -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SubscriptionMessage] -> ShowS
$cshowList :: [SubscriptionMessage] -> ShowS
show :: SubscriptionMessage -> String
$cshow :: SubscriptionMessage -> String
showsPrec :: Int -> SubscriptionMessage -> ShowS
$cshowsPrec :: Int -> SubscriptionMessage -> ShowS
Show, forall x. Rep SubscriptionMessage x -> SubscriptionMessage
forall x. SubscriptionMessage -> Rep SubscriptionMessage x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SubscriptionMessage x -> SubscriptionMessage
$cfrom :: forall x. SubscriptionMessage -> Rep SubscriptionMessage x
Generic )

instance FromJSON SubscriptionMessage where
    parseJSON :: Value -> Parser SubscriptionMessage
parseJSON = forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"SubscriptionMessage" forall a b. (a -> b) -> a -> b
$ \Object
o -> do
        String
subscriptionMessage <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"message"
        Maybe [EmoteSpec]
emotes' <- Object
o forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"emotes"
        let subscriptionEmotes :: [EmoteSpec]
subscriptionEmotes = forall a. a -> Maybe a -> a
Maybe.fromMaybe [] Maybe [EmoteSpec]
emotes'
        forall (m :: * -> *) a. Monad m => a -> m a
return SubscriptionMessage{String
[EmoteSpec]
subscriptionEmotes :: [EmoteSpec]
subscriptionMessage :: String
subscriptionEmotes :: [EmoteSpec]
subscriptionMessage :: String
..}

data Message = BitsV2Message { Message -> Maybe BadgeUnlock
badge :: Maybe BadgeUnlock
                             , Message -> Integer
bits :: Integer
                             , Message -> Integer
channelId :: Integer
                             , Message -> Maybe String
chatMessage :: Maybe String
                             , Message -> String
context :: String
                             , Message -> String
messageId :: String
                             , Message -> String
messageType :: String
                             , Message -> Maybe UTCTime
time :: Maybe Time.UTCTime
                             , Message -> Integer
userTotal :: Integer
                             , Message -> Maybe Integer
messageUser :: Maybe Integer
                             , Message -> Maybe String
messageUserName :: Maybe String
                             , Message -> String
version :: String
                             }
             | BitsV2AnonymousMessage { bits :: Integer
                                      , channelId :: Integer
                                      , chatMessage :: Maybe String
                                      , context :: String
                                      , messageId :: String
                                      , messageType :: String
                                      , time :: Maybe Time.UTCTime
                                      , version :: String
                                      }
             | BitsV1Message { badge :: Maybe BadgeUnlock
                             , bits :: Integer
                             , channelId :: Integer
                             , Message -> String
channelName :: String
                             , chatMessage :: Maybe String
                             , context :: String
                             , messageId :: String
                             , messageType :: String
                             , time :: Maybe Time.UTCTime
                             , userTotal :: Integer
                             , messageUser :: Maybe Integer
                             , messageUserName :: Maybe String
                             , version :: String
                             }
             | BitsBadgeMessage { messageUser :: Maybe Integer
                                , messageUserName :: Maybe String
                                , channelId :: Integer
                                , channelName :: String
                                , Message -> Integer
bitsTier :: Integer
                                , chatMessage :: Maybe String
                                , time :: Maybe Time.UTCTime
                                }
             | ChannelPointsMessage { Message -> Maybe UTCTime
serverTime :: Maybe Time.UTCTime
                                    , Message -> Maybe UTCTime
redeemedTime :: Maybe Time.UTCTime
                                    , Message -> UserInfo
userInfo :: UserInfo
                                    , Message -> String
rewardId :: String
                                    , channelId :: Integer
                                    , Message -> String
title :: String
                                    , Message -> Maybe String
prompt :: Maybe String
                                    , Message -> Integer
cost :: Integer
                                    , Message -> Maybe String
userInput :: Maybe String
                                    , Message -> Bool
subOnly :: Bool
                                    , Message -> Maybe RewardImages
image :: Maybe RewardImages
                                    , Message -> RewardImages
defaultImage :: RewardImages
                                    , Message -> String
backgroundColor :: String
                                    , Message -> Bool
enabled :: Bool
                                    , Message -> Bool
paused :: Bool
                                    , Message -> Bool
inStock :: Bool
                                    , Message -> Maybe Integer
maxPerStream :: Maybe Integer
                                    , Message -> Bool
autoFulfilled :: Bool
                                    , Message -> RewardStatus
status :: RewardStatus
                                    }
             | ChannelSubscriptionMessage { userInfo :: UserInfo
                                          , channelName :: String
                                          , channelId :: Integer
                                          , time :: Maybe Time.UTCTime
                                          , Message -> SubscriptionTier
subTier :: SubscriptionTier
                                          , Message -> String
subPlanName :: String
                                          , Message -> SubscriptionMessage
subMessage :: SubscriptionMessage
                                          }
             | ChannelResubscriptionMessage { userInfo :: UserInfo
                                            , channelName :: String
                                            , channelId :: Integer
                                            , time :: Maybe Time.UTCTime
                                            , subTier :: SubscriptionTier
                                            , subPlanName :: String
                                            , Message -> Integer
totalMonths :: Integer
                                            , Message -> Maybe Integer
streakMonths :: Maybe Integer
                                            , subMessage :: SubscriptionMessage
                                            }
             | ChannelExtendSubscriptionMessage { userInfo :: UserInfo
                                                , channelName :: String
                                                , channelId :: Integer
                                                , time :: Maybe Time.UTCTime
                                                , subTier :: SubscriptionTier
                                                , subPlanName :: String
                                                , totalMonths :: Integer
                                                , streakMonths :: Maybe Integer
                                                , Message -> Integer
endMonth :: Integer
                                                , subMessage :: SubscriptionMessage
                                                }
             | ChannelSubscriptionGiftMessage { userInfo :: UserInfo
                                              , channelName :: String
                                              , channelId :: Integer
                                              , time :: Maybe Time.UTCTime
                                              , subTier :: SubscriptionTier
                                              , subPlanName :: String
                                              , Message -> UserInfo
recipient :: UserInfo
                                              }
             | ChannelMultiMonthSubscriptionGiftMessage { userInfo :: UserInfo
                                                        , channelName :: String
                                                        , channelId :: Integer
                                                        , time :: Maybe Time.UTCTime
                                                        , subTier :: SubscriptionTier
                                                        , subPlanName :: String
                                                        , recipient :: UserInfo
                                                        , Message -> Integer
months :: Integer
                                                        }
             | ChannelAnonymousSubscriptionGiftMessage { channelName :: String
                                                       , channelId :: Integer
                                                       , time :: Maybe Time.UTCTime
                                                       , subTier :: SubscriptionTier
                                                       , subPlanName :: String
                                                       , recipient :: UserInfo
                                                       }
             | ChannelAnonymousMultiMonthSubscriptionGiftMessage { channelName :: String
                                                                 , channelId :: Integer
                                                                 , time :: Maybe Time.UTCTime
                                                                 , subTier :: SubscriptionTier
                                                                 , subPlanName :: String
                                                                 , recipient :: UserInfo
                                                                 , months :: Integer
                                                                 }
             | WhisperMessage { messageId :: String
                              , Message -> String
threadId :: String
                              , time :: Maybe Time.UTCTime
                              , Message -> String
messageBody :: String
                              , Message -> [EmoteSpec]
messageEmotes :: [EmoteSpec]
                              , userInfo :: UserInfo
                              , Message -> String
userColor :: String
                              , recipient :: UserInfo
                              }
             | SuccessMessage { Message -> Maybe String
nonce :: Maybe String }
             | ErrorMessage { nonce :: Maybe String
                            , Message -> String
errorString :: String
                            } deriving ( Message -> Message -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Message -> Message -> Bool
$c/= :: Message -> Message -> Bool
== :: Message -> Message -> Bool
$c== :: Message -> Message -> Bool
Eq, Int -> Message -> ShowS
[Message] -> ShowS
Message -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Message] -> ShowS
$cshowList :: [Message] -> ShowS
show :: Message -> String
$cshow :: Message -> String
showsPrec :: Int -> Message -> ShowS
$cshowsPrec :: Int -> Message -> ShowS
Show, forall x. Rep Message x -> Message
forall x. Message -> Rep Message x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Message x -> Message
$cfrom :: forall x. Message -> Rep Message x
Generic )

instance JSON.ToJSON EmoteSpec
instance JSON.ToJSON SubscriptionMessage
instance JSON.ToJSON SubscriptionTier
instance JSON.ToJSON RewardStatus
instance JSON.ToJSON RewardImages
instance JSON.ToJSON UserInfo
instance JSON.ToJSON BadgeUnlock
instance JSON.ToJSON Message

type MessageParser = Object -> JSON.Types.Parser Message

parseChannelSubscribeEvent :: MessageParser
parseChannelSubscribeEvent :: MessageParser
parseChannelSubscribeEvent Object
o = do
    String
uid :: String <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"user_id"
    String
messageUserName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"user_name"
    Maybe String
displayName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"display_name"
    let messageUser :: Integer
messageUser = forall a. Read a => String -> a
read String
uid :: Integer
        userInfo :: UserInfo
userInfo = Integer -> String -> Maybe String -> UserInfo
UserInfo Integer
messageUser String
messageUserName Maybe String
displayName

    String
channelName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"channel_name"
    String
channel <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"channel_id"
    let channelId :: Integer
channelId = forall a. Read a => String -> a
read String
channel :: Integer

    String
t :: String <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"time"
    let time :: Maybe UTCTime
time = ZonedTime -> UTCTime
Time.zonedTimeToUTC forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall t. TextualMonoid t => t -> Maybe ZonedTime
Time.parseTimeRFC3339 String
t

    SubscriptionTier
subTier <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"sub_plan"
    String
subPlanName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"sub_plan_name"
    SubscriptionMessage
subMessage <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"sub_message"

    forall (m :: * -> *) a. Monad m => a -> m a
return ChannelSubscriptionMessage{Integer
String
Maybe UTCTime
SubscriptionMessage
SubscriptionTier
UserInfo
subMessage :: SubscriptionMessage
subPlanName :: String
subTier :: SubscriptionTier
time :: Maybe UTCTime
channelId :: Integer
channelName :: String
userInfo :: UserInfo
subMessage :: SubscriptionMessage
subPlanName :: String
subTier :: SubscriptionTier
userInfo :: UserInfo
channelName :: String
time :: Maybe UTCTime
channelId :: Integer
..}

parseChannelResubscribeEvent :: MessageParser
parseChannelResubscribeEvent :: MessageParser
parseChannelResubscribeEvent Object
o = do
    String
uid :: String <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"user_id"
    String
messageUserName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"user_name"
    Maybe String
displayName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"display_name"
    let messageUser :: Integer
messageUser = forall a. Read a => String -> a
read String
uid :: Integer
        userInfo :: UserInfo
userInfo = Integer -> String -> Maybe String -> UserInfo
UserInfo Integer
messageUser String
messageUserName Maybe String
displayName

    String
channelName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"channel_name"
    String
channel <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"channel_id"
    let channelId :: Integer
channelId = forall a. Read a => String -> a
read String
channel :: Integer

    String
t :: String <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"time"
    let time :: Maybe UTCTime
time = ZonedTime -> UTCTime
Time.zonedTimeToUTC forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall t. TextualMonoid t => t -> Maybe ZonedTime
Time.parseTimeRFC3339 String
t

    SubscriptionTier
subTier <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"sub_plan"
    String
subPlanName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"sub_plan_name"
    Integer
totalMonths <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"cumulative_months"
    Maybe Integer
streakMonths <- Object
o forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"streak_months"
    SubscriptionMessage
subMessage <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"sub_message"

    forall (m :: * -> *) a. Monad m => a -> m a
return ChannelResubscriptionMessage{Integer
String
Maybe Integer
Maybe UTCTime
SubscriptionMessage
SubscriptionTier
UserInfo
subMessage :: SubscriptionMessage
streakMonths :: Maybe Integer
totalMonths :: Integer
subPlanName :: String
subTier :: SubscriptionTier
time :: Maybe UTCTime
channelId :: Integer
channelName :: String
userInfo :: UserInfo
streakMonths :: Maybe Integer
totalMonths :: Integer
subMessage :: SubscriptionMessage
subPlanName :: String
subTier :: SubscriptionTier
userInfo :: UserInfo
channelName :: String
time :: Maybe UTCTime
channelId :: Integer
..}

parseChannelExtendSubEvent :: MessageParser
parseChannelExtendSubEvent :: MessageParser
parseChannelExtendSubEvent Object
o = do
    String
uid :: String <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"user_id"
    String
messageUserName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"user_name"
    Maybe String
displayName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"display_name"
    let messageUser :: Integer
messageUser = forall a. Read a => String -> a
read String
uid :: Integer
        userInfo :: UserInfo
userInfo = Integer -> String -> Maybe String -> UserInfo
UserInfo Integer
messageUser String
messageUserName Maybe String
displayName

    String
channelName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"channel_name"
    String
channel <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"channel_id"
    let channelId :: Integer
channelId = forall a. Read a => String -> a
read String
channel :: Integer

    String
t :: String <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"time"
    let time :: Maybe UTCTime
time = ZonedTime -> UTCTime
Time.zonedTimeToUTC forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall t. TextualMonoid t => t -> Maybe ZonedTime
Time.parseTimeRFC3339 String
t

    SubscriptionTier
subTier <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"sub_plan"
    String
subPlanName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"sub_plan_name"
    Integer
totalMonths <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"cumulative_months"
    Integer
endMonth <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"benefit_end_month"
    Maybe Integer
streakMonths <- Object
o forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"streak_months"
    SubscriptionMessage
subMessage <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"sub_message"

    forall (m :: * -> *) a. Monad m => a -> m a
return ChannelExtendSubscriptionMessage{Integer
String
Maybe Integer
Maybe UTCTime
SubscriptionMessage
SubscriptionTier
UserInfo
subMessage :: SubscriptionMessage
streakMonths :: Maybe Integer
endMonth :: Integer
totalMonths :: Integer
subPlanName :: String
subTier :: SubscriptionTier
time :: Maybe UTCTime
channelId :: Integer
channelName :: String
userInfo :: UserInfo
endMonth :: Integer
streakMonths :: Maybe Integer
totalMonths :: Integer
subMessage :: SubscriptionMessage
subPlanName :: String
subTier :: SubscriptionTier
userInfo :: UserInfo
channelName :: String
time :: Maybe UTCTime
channelId :: Integer
..}

parseChannelSubGiftEvent :: MessageParser
parseChannelSubGiftEvent :: MessageParser
parseChannelSubGiftEvent Object
o = do
    String
uid :: String <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"user_id"
    String
messageUserName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"user_name"
    Maybe String
displayName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"display_name"
    let messageUser :: Integer
messageUser = forall a. Read a => String -> a
read String
uid :: Integer
        userInfo :: UserInfo
userInfo = Integer -> String -> Maybe String -> UserInfo
UserInfo Integer
messageUser String
messageUserName Maybe String
displayName

    String
rid :: String <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"recipient_id"
    String
rUserName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"recipient_user_name"
    Maybe String
rDisplayName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"recipient_display_name"
    let rUserId :: Integer
rUserId = forall a. Read a => String -> a
read String
rid :: Integer
        recipient :: UserInfo
recipient = Integer -> String -> Maybe String -> UserInfo
UserInfo Integer
rUserId String
rUserName Maybe String
rDisplayName

    String
channelName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"channel_name"
    String
channel <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"channel_id"
    let channelId :: Integer
channelId = forall a. Read a => String -> a
read String
channel :: Integer

    String
t :: String <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"time"
    let time :: Maybe UTCTime
time = ZonedTime -> UTCTime
Time.zonedTimeToUTC forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall t. TextualMonoid t => t -> Maybe ZonedTime
Time.parseTimeRFC3339 String
t

    SubscriptionTier
subTier <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"sub_plan"
    String
subPlanName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"sub_plan_name"

    Maybe Integer
duration :: Maybe Integer <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"multi_month_duration"
    case Maybe Integer
duration of
        Maybe Integer
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ChannelSubscriptionGiftMessage{Integer
String
Maybe UTCTime
SubscriptionTier
UserInfo
subPlanName :: String
subTier :: SubscriptionTier
time :: Maybe UTCTime
channelId :: Integer
channelName :: String
recipient :: UserInfo
userInfo :: UserInfo
recipient :: UserInfo
subPlanName :: String
subTier :: SubscriptionTier
userInfo :: UserInfo
channelName :: String
time :: Maybe UTCTime
channelId :: Integer
..}
        Just Integer
1 -> forall (m :: * -> *) a. Monad m => a -> m a
return ChannelSubscriptionGiftMessage{Integer
String
Maybe UTCTime
SubscriptionTier
UserInfo
subPlanName :: String
subTier :: SubscriptionTier
time :: Maybe UTCTime
channelId :: Integer
channelName :: String
recipient :: UserInfo
userInfo :: UserInfo
recipient :: UserInfo
subPlanName :: String
subTier :: SubscriptionTier
userInfo :: UserInfo
channelName :: String
time :: Maybe UTCTime
channelId :: Integer
..}
        Just Integer
months -> forall (m :: * -> *) a. Monad m => a -> m a
return ChannelMultiMonthSubscriptionGiftMessage{Integer
String
Maybe UTCTime
SubscriptionTier
UserInfo
months :: Integer
subPlanName :: String
subTier :: SubscriptionTier
time :: Maybe UTCTime
channelId :: Integer
channelName :: String
recipient :: UserInfo
userInfo :: UserInfo
months :: Integer
recipient :: UserInfo
subPlanName :: String
subTier :: SubscriptionTier
userInfo :: UserInfo
channelName :: String
time :: Maybe UTCTime
channelId :: Integer
..}

parseChannelAnonSubGiftEvent :: MessageParser
parseChannelAnonSubGiftEvent :: MessageParser
parseChannelAnonSubGiftEvent Object
o = do
    String
rid :: String <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"recipient_id"
    String
rUserName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"recipient_user_name"
    Maybe String
rDisplayName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"recipient_display_name"
    let rUserId :: Integer
rUserId = forall a. Read a => String -> a
read String
rid :: Integer
        recipient :: UserInfo
recipient = Integer -> String -> Maybe String -> UserInfo
UserInfo Integer
rUserId String
rUserName Maybe String
rDisplayName

    String
channelName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"channel_name"
    String
channel <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"channel_id"
    let channelId :: Integer
channelId = forall a. Read a => String -> a
read String
channel :: Integer

    String
t :: String <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"time"
    let time :: Maybe UTCTime
time = ZonedTime -> UTCTime
Time.zonedTimeToUTC forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall t. TextualMonoid t => t -> Maybe ZonedTime
Time.parseTimeRFC3339 String
t

    SubscriptionTier
subTier <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"sub_plan"
    String
subPlanName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"sub_plan_name"

    Maybe Integer
duration :: Maybe Integer <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"multi_month_duration"
    case Maybe Integer
duration of
        Maybe Integer
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ChannelAnonymousSubscriptionGiftMessage{Integer
String
Maybe UTCTime
SubscriptionTier
UserInfo
subPlanName :: String
subTier :: SubscriptionTier
time :: Maybe UTCTime
channelId :: Integer
channelName :: String
recipient :: UserInfo
recipient :: UserInfo
subPlanName :: String
subTier :: SubscriptionTier
channelName :: String
time :: Maybe UTCTime
channelId :: Integer
..}
        Just Integer
1 -> forall (m :: * -> *) a. Monad m => a -> m a
return ChannelAnonymousSubscriptionGiftMessage{Integer
String
Maybe UTCTime
SubscriptionTier
UserInfo
subPlanName :: String
subTier :: SubscriptionTier
time :: Maybe UTCTime
channelId :: Integer
channelName :: String
recipient :: UserInfo
recipient :: UserInfo
subPlanName :: String
subTier :: SubscriptionTier
channelName :: String
time :: Maybe UTCTime
channelId :: Integer
..}
        Just Integer
months -> forall (m :: * -> *) a. Monad m => a -> m a
return ChannelAnonymousMultiMonthSubscriptionGiftMessage{Integer
String
Maybe UTCTime
SubscriptionTier
UserInfo
months :: Integer
subPlanName :: String
subTier :: SubscriptionTier
time :: Maybe UTCTime
channelId :: Integer
channelName :: String
recipient :: UserInfo
months :: Integer
recipient :: UserInfo
subPlanName :: String
subTier :: SubscriptionTier
channelName :: String
time :: Maybe UTCTime
channelId :: Integer
..}

parseChannelSubscribeMessage :: MessageParser
parseChannelSubscribeMessage :: MessageParser
parseChannelSubscribeMessage Object
o = do
    String
context :: String <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"context"
    case String
context of
      String
"sub" -> MessageParser
parseChannelSubscribeEvent Object
o
      String
"resub" -> MessageParser
parseChannelResubscribeEvent Object
o
      String
"extendsub" -> MessageParser
parseChannelExtendSubEvent Object
o
      String
"subgift" -> MessageParser
parseChannelSubGiftEvent Object
o
      String
"resubgift" -> MessageParser
parseChannelSubGiftEvent Object
o
      String
"anonsubgift" -> MessageParser
parseChannelAnonSubGiftEvent Object
o
      String
"anonresubgift" -> MessageParser
parseChannelAnonSubGiftEvent Object
o
      String
_ -> forall (m :: * -> *) a. MonadPlus m => m a
mzero

parseBitsV2Message :: MessageParser
parseBitsV2Message :: MessageParser
parseBitsV2Message Object
o = do
    Object
dat <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"data"
    Maybe Bool
anonymous :: Maybe Bool <- Object
o forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"is_anonymous"
    case Maybe Bool
anonymous of
      Maybe Bool
Nothing      -> Object -> MessageParser
parseBitsV2 Object
o Object
dat
      (Just Bool
False) -> Object -> MessageParser
parseBitsV2 Object
o Object
dat
      (Just Bool
True)  -> Object -> MessageParser
parseBitsV2Anonymous Object
o Object
dat


parseBitsV2 :: Object -> MessageParser
parseBitsV2 :: Object -> MessageParser
parseBitsV2 Object
o Object
dat = do
    Maybe BadgeUnlock
badge <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"badge_entitlement"
    Integer
bits <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"bits_used"
    Maybe String
chatMessage <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"chat_message"
    String
context <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"context"
    String
messageId <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"message_id"
    String
messageType <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"message_type" -- Always bits_event?  No other examples given in API docs
    Integer
userTotal <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"total_bits_used"
    Maybe String
messageUserName <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"user_name"
    String
version <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"version"

    String
channel :: String <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"channel_id"
    let channelId :: Integer
channelId = forall a. Read a => String -> a
read String
channel :: Integer

    Maybe String
uid :: Maybe String <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"user_id"
    let messageUser :: Maybe Integer
messageUser = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. Read a => String -> a
read :: String -> Integer) Maybe String
uid

    String
t :: String <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"time"
    let time :: Maybe UTCTime
time = ZonedTime -> UTCTime
Time.zonedTimeToUTC forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall t. TextualMonoid t => t -> Maybe ZonedTime
Time.parseTimeRFC3339 String
t

    forall (m :: * -> *) a. Monad m => a -> m a
return BitsV2Message{Integer
String
Maybe Integer
Maybe String
Maybe UTCTime
Maybe BadgeUnlock
time :: Maybe UTCTime
messageUser :: Maybe Integer
channelId :: Integer
version :: String
messageUserName :: Maybe String
userTotal :: Integer
messageType :: String
messageId :: String
context :: String
chatMessage :: Maybe String
bits :: Integer
badge :: Maybe BadgeUnlock
version :: String
messageUserName :: Maybe String
messageUser :: Maybe Integer
userTotal :: Integer
time :: Maybe UTCTime
messageType :: String
messageId :: String
context :: String
chatMessage :: Maybe String
channelId :: Integer
bits :: Integer
badge :: Maybe BadgeUnlock
..}

parseBitsV2Anonymous :: Object -> MessageParser
parseBitsV2Anonymous :: Object -> MessageParser
parseBitsV2Anonymous Object
o Object
dat = do
    Integer
bits <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"bits_used"
    Maybe String
chatMessage <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"chat_message"
    String
context <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"context"
    String
messageId <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"message_id"
    String
messageType <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"message_type" -- Always bits_event?  No other examples given in API docs
    String
version <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"version"

    String
channel :: String <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"channel_id"
    let channelId :: Integer
channelId = forall a. Read a => String -> a
read String
channel :: Integer

    String
t :: String <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"time"
    let time :: Maybe UTCTime
time = ZonedTime -> UTCTime
Time.zonedTimeToUTC forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall t. TextualMonoid t => t -> Maybe ZonedTime
Time.parseTimeRFC3339 String
t

    forall (m :: * -> *) a. Monad m => a -> m a
return BitsV2AnonymousMessage{Integer
String
Maybe String
Maybe UTCTime
time :: Maybe UTCTime
channelId :: Integer
version :: String
messageType :: String
messageId :: String
context :: String
chatMessage :: Maybe String
bits :: Integer
version :: String
time :: Maybe UTCTime
messageType :: String
messageId :: String
context :: String
chatMessage :: Maybe String
channelId :: Integer
bits :: Integer
..}

parseBitsV1Message :: MessageParser
parseBitsV1Message :: MessageParser
parseBitsV1Message Object
o = do
    Object
dat <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"data"
    Maybe BadgeUnlock
badge <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"badge_entitlement"
    Integer
bits <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"bits_used"
    String
channelName <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"channel_name"
    Maybe String
chatMessage <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"chat_message"
    String
context <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"context"
    String
messageId <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"message_id"
    String
messageType <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"message_type" -- Always bits_event?  No other examples given in API docs
    Integer
userTotal <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"total_bits_used"
    Maybe String
messageUserName <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"user_name"
    String
version <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"version"

    Maybe String
uid :: Maybe String <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"user_id"
    let messageUser :: Maybe Integer
messageUser = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. Read a => String -> a
read :: String -> Integer) Maybe String
uid

    String
channel :: String <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"channel_id"
    let channelId :: Integer
channelId = forall a. Read a => String -> a
read String
channel :: Integer

    String
t :: String <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"time"
    let time :: Maybe UTCTime
time = ZonedTime -> UTCTime
Time.zonedTimeToUTC forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall t. TextualMonoid t => t -> Maybe ZonedTime
Time.parseTimeRFC3339 String
t

    forall (m :: * -> *) a. Monad m => a -> m a
return BitsV1Message{Integer
String
Maybe Integer
Maybe String
Maybe UTCTime
Maybe BadgeUnlock
time :: Maybe UTCTime
channelId :: Integer
messageUser :: Maybe Integer
version :: String
messageUserName :: Maybe String
userTotal :: Integer
messageType :: String
messageId :: String
context :: String
chatMessage :: Maybe String
channelName :: String
bits :: Integer
badge :: Maybe BadgeUnlock
channelName :: String
version :: String
messageUserName :: Maybe String
messageUser :: Maybe Integer
userTotal :: Integer
time :: Maybe UTCTime
messageType :: String
messageId :: String
context :: String
chatMessage :: Maybe String
channelId :: Integer
bits :: Integer
badge :: Maybe BadgeUnlock
..}

parseBitsBadgeMessage :: MessageParser
parseBitsBadgeMessage :: MessageParser
parseBitsBadgeMessage Object
o = do
    Maybe Integer
messageUser <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"user_id"
    Maybe String
messageUserName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"user_name"
    String
channelName <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"channel_name"
    Integer
bitsTier <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"badge_tier"
    Maybe String
chatMessage <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"chat_message"

    String
channel :: String <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"channel_id"
    String
t :: String <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"time"
    let time :: Maybe UTCTime
time = ZonedTime -> UTCTime
Time.zonedTimeToUTC forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall t. TextualMonoid t => t -> Maybe ZonedTime
Time.parseTimeRFC3339 String
t
        channelId :: Integer
channelId = forall a. Read a => String -> a
read String
channel :: Integer
    forall (m :: * -> *) a. Monad m => a -> m a
return BitsBadgeMessage{Integer
String
Maybe Integer
Maybe String
Maybe UTCTime
channelId :: Integer
time :: Maybe UTCTime
chatMessage :: Maybe String
bitsTier :: Integer
channelName :: String
messageUserName :: Maybe String
messageUser :: Maybe Integer
bitsTier :: Integer
channelName :: String
messageUserName :: Maybe String
messageUser :: Maybe Integer
time :: Maybe UTCTime
chatMessage :: Maybe String
channelId :: Integer
..}

parseRewardMessage :: MessageParser
parseRewardMessage :: MessageParser
parseRewardMessage Object
o = do
    Object
dat <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"data"
    Object
redemption <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"redemption"
    Object
reward <- Object
redemption forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"reward"
    UserInfo
userInfo <- Object
redemption forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"user"
    String
rewardId <- Object
reward forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"id"
    String
title <- Object
reward forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"title"
    Maybe String
prompt <- Object
reward forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"prompt"
    Integer
cost <- Object
reward forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"cost"
    Bool
subOnly <- Object
reward forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"is_sub_only"
    Maybe RewardImages
image <- Object
reward forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"image"
    RewardImages
defaultImage <- Object
reward forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"default_image"
    String
backgroundColor <- Object
reward forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"background_color"
    Bool
enabled <- Object
reward forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"is_enabled"
    Bool
paused <- Object
reward forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"is_paused"
    Bool
inStock <- Object
reward forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"is_in_stock"
    Bool
autoFulfilled <- Object
reward forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"should_redemptions_skip_request_queue"

    String
channel :: String <- Object
redemption forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"channel_id"
    let channelId :: Integer
channelId = forall a. Read a => String -> a
read String
channel :: Integer

    String
sTime :: String <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"timestamp"
    String
rTime :: String <- Object
redemption forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"redeemed_at"
    let serverTime :: Maybe UTCTime
serverTime = ZonedTime -> UTCTime
Time.zonedTimeToUTC forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall t. TextualMonoid t => t -> Maybe ZonedTime
Time.parseTimeRFC3339 String
sTime
        redeemedTime :: Maybe UTCTime
redeemedTime = ZonedTime -> UTCTime
Time.zonedTimeToUTC forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall t. TextualMonoid t => t -> Maybe ZonedTime
Time.parseTimeRFC3339 String
rTime

    Maybe String
promptAnswer <- Object
redemption forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"user_input"
    Bool
promptEnabled :: Bool <- Object
reward forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"is_user_input_required"
    let userInput :: Maybe String
userInput = if Bool
promptEnabled then Maybe String
promptAnswer else forall a. Maybe a
Nothing

    Object
maxObject <- Object
reward forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"max_per_stream"
    Bool
maxEnabled :: Bool <- Object
maxObject forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"is_enabled"
    Integer
maxCount <- Object
maxObject forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"max_per_stream"
    let maxPerStream :: Maybe Integer
maxPerStream = if Bool
maxEnabled then forall a. a -> Maybe a
Just Integer
maxCount else forall a. Maybe a
Nothing

    String
status' <- Object
redemption forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"status"
    let status :: RewardStatus
status = forall a. Read a => String -> a
read String
status' :: RewardStatus

    forall (m :: * -> *) a. Monad m => a -> m a
return ChannelPointsMessage{Bool
Integer
String
Maybe Integer
Maybe String
Maybe UTCTime
Maybe RewardImages
RewardStatus
UserInfo
RewardImages
status :: RewardStatus
maxPerStream :: Maybe Integer
userInput :: Maybe String
redeemedTime :: Maybe UTCTime
serverTime :: Maybe UTCTime
channelId :: Integer
autoFulfilled :: Bool
inStock :: Bool
paused :: Bool
enabled :: Bool
backgroundColor :: String
defaultImage :: RewardImages
image :: Maybe RewardImages
subOnly :: Bool
cost :: Integer
prompt :: Maybe String
title :: String
rewardId :: String
userInfo :: UserInfo
status :: RewardStatus
autoFulfilled :: Bool
maxPerStream :: Maybe Integer
inStock :: Bool
paused :: Bool
enabled :: Bool
backgroundColor :: String
defaultImage :: RewardImages
image :: Maybe RewardImages
subOnly :: Bool
userInput :: Maybe String
cost :: Integer
prompt :: Maybe String
title :: String
rewardId :: String
userInfo :: UserInfo
redeemedTime :: Maybe UTCTime
serverTime :: Maybe UTCTime
channelId :: Integer
..}

parseWhisperMessage :: MessageParser
parseWhisperMessage :: MessageParser
parseWhisperMessage Object
o = do
    Object
dat <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"data_object"
    String
messageId <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"message_id"
    String
threadId <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"thread_id"
    String
messageBody <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"body"
    Object
tags <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"tags"
    [EmoteSpec]
messageEmotes <- Object
tags forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"emotes"
    String
userColor <- Object
tags forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"color"

    Integer
messageUser <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"from_id"
    String
messageUserName <- Object
tags forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"login"
    Maybe String
displayName <- Object
tags forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"display_name"
    let userInfo :: UserInfo
userInfo = Integer -> String -> Maybe String -> UserInfo
UserInfo Integer
messageUser String
messageUserName Maybe String
displayName

    Object
recipientData <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"recipient"
    Integer
rUserId <- Object
recipientData forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"id"
    String
rUserName <- Object
recipientData forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"username"
    Maybe String
rDisplayName <- Object
recipientData forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"display_name"
    let recipient :: UserInfo
recipient = Integer -> String -> Maybe String -> UserInfo
UserInfo Integer
rUserId String
rUserName Maybe String
rDisplayName

    Integer
timestamp :: Integer <- Object
dat forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"sent_ts"
    let time :: Maybe UTCTime
time = forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. POSIXTime -> UTCTime
Time.posixSecondsToUTCTime forall a b. (a -> b) -> a -> b
$ forall a b. (Real a, Fractional b) => a -> b
realToFrac Integer
timestamp

    forall (m :: * -> *) a. Monad m => a -> m a
return WhisperMessage{String
[EmoteSpec]
Maybe UTCTime
UserInfo
time :: Maybe UTCTime
recipient :: UserInfo
userInfo :: UserInfo
userColor :: String
messageEmotes :: [EmoteSpec]
messageBody :: String
threadId :: String
messageId :: String
userColor :: String
messageEmotes :: [EmoteSpec]
messageBody :: String
threadId :: String
recipient :: UserInfo
userInfo :: UserInfo
time :: Maybe UTCTime
messageId :: String
..}

parseServerResponse :: MessageParser
parseServerResponse :: MessageParser
parseServerResponse Object
o = do
    String
errorString <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"error"
    Maybe String
nonce <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"nonce"
    if forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
errorString
       then forall (m :: * -> *) a. Monad m => a -> m a
return SuccessMessage{Maybe String
nonce :: Maybe String
nonce :: Maybe String
..}
       else forall (m :: * -> *) a. Monad m => a -> m a
return ErrorMessage{String
Maybe String
nonce :: Maybe String
errorString :: String
errorString :: String
nonce :: Maybe String
..}

instance FromJSON Message where
    parseJSON :: Value -> Parser Message
parseJSON = forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"Received" forall a b. (a -> b) -> a -> b
$ \Object
o -> do
        Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"type" forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \(String
reportedType :: String) -> case String
reportedType of
            String
"RESPONSE" -> MessageParser
parseServerResponse Object
o
            String
"MESSAGE" -> do
                Object
d <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"data"
                Text
m <- Object
d forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"message"
                Object
m' <- forall a. String -> (Value -> Parser a) -> Value -> Parser a
withEmbeddedJSON String
"Message" forall a. FromJSON a => Value -> Parser a
parseJSON (Text -> Value
JSON.String Text
m)
                Object
m' forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"type" forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \(Maybe String
message :: Maybe String) ->
                    case Maybe String
message of
                        Just String
"reward-redeemed" -> MessageParser
parseRewardMessage Object
m'
                        Maybe String
_ -> Object
d forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"topic" forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \(String
topic :: String) -> case forall a. (a -> Bool) -> [a] -> [a]
takeWhile (forall a. Eq a => a -> a -> Bool
/= Char
'.') String
topic of
                            String
"channel-bits-badge-unlocks" -> MessageParser
parseBitsBadgeMessage Object
m'
                            String
"channel-bits-events-v1" -> MessageParser
parseBitsV1Message Object
m'
                            String
"channel-bits-events-v2" -> MessageParser
parseBitsV2Message Object
m'
                            String
"channel-subscribe-events-v1" -> MessageParser
parseChannelSubscribeMessage Object
m'
                            String
"whispers" -> MessageParser
parseWhisperMessage Object
m'
                            String
_ -> forall (m :: * -> *) a. MonadPlus m => m a
mzero
            String
_ -> forall (m :: * -> *) a. MonadPlus m => m a
mzero

--data ChatModeratorActionsMessage
--data WhispersMessage