packages feed

twitchapi 0.0.3 → 0.0.4

raw patch · 3 files changed

+75/−73 lines, 3 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Web.TwitchAPI.PubSub: [$sel:authToken:Request] :: Request -> String
- Web.TwitchAPI.PubSub: [$sel:autoFulfilled:BitsV2Message] :: Message -> Bool
- Web.TwitchAPI.PubSub: [$sel:backgroundColor:BitsV2Message] :: Message -> String
- Web.TwitchAPI.PubSub: [$sel:badge:BitsV2Message] :: Message -> Maybe BadgeUnlock
- Web.TwitchAPI.PubSub: [$sel:bits:BitsV2Message] :: Message -> Integer
- Web.TwitchAPI.PubSub: [$sel:bitsTier:BitsV2Message] :: Message -> Integer
- Web.TwitchAPI.PubSub: [$sel:channelId:BitsV1] :: Topic -> Integer
- Web.TwitchAPI.PubSub: [$sel:channelId:BitsV2Message] :: Message -> Integer
- Web.TwitchAPI.PubSub: [$sel:channelName:BitsV2Message] :: Message -> String
- Web.TwitchAPI.PubSub: [$sel:chatMessage:BitsV2Message] :: Message -> Maybe String
- Web.TwitchAPI.PubSub: [$sel:context:BitsV2Message] :: Message -> String
- Web.TwitchAPI.PubSub: [$sel:cost:BitsV2Message] :: Message -> Integer
- Web.TwitchAPI.PubSub: [$sel:defaultImage:BitsV2Message] :: Message -> RewardImages
- Web.TwitchAPI.PubSub: [$sel:displayName:UserInfo] :: UserInfo -> Maybe String
- Web.TwitchAPI.PubSub: [$sel:emoteId:EmoteSpec] :: EmoteSpec -> Integer
- Web.TwitchAPI.PubSub: [$sel:emoteLength:EmoteSpec] :: EmoteSpec -> Integer
- Web.TwitchAPI.PubSub: [$sel:emoteStart:EmoteSpec] :: EmoteSpec -> Integer
- Web.TwitchAPI.PubSub: [$sel:emotes:BitsV2Message] :: Message -> [EmoteSpec]
- Web.TwitchAPI.PubSub: [$sel:emotes:SubscriptionMessage] :: SubscriptionMessage -> [EmoteSpec]
- Web.TwitchAPI.PubSub: [$sel:enabled:BitsV2Message] :: Message -> Bool
- Web.TwitchAPI.PubSub: [$sel:endMonth:BitsV2Message] :: Message -> Integer
- Web.TwitchAPI.PubSub: [$sel:errorReported:Response] :: Response -> RequestError
- Web.TwitchAPI.PubSub: [$sel:errorString:BitsV2Message] :: Message -> String
- Web.TwitchAPI.PubSub: [$sel:huge:RewardImages] :: RewardImages -> Maybe String
- Web.TwitchAPI.PubSub: [$sel:image:BitsV2Message] :: Message -> Maybe RewardImages
- Web.TwitchAPI.PubSub: [$sel:inStock:BitsV2Message] :: Message -> Bool
- Web.TwitchAPI.PubSub: [$sel:large:RewardImages] :: RewardImages -> Maybe String
- Web.TwitchAPI.PubSub: [$sel:maxPerStream:BitsV2Message] :: Message -> Maybe Integer
- Web.TwitchAPI.PubSub: [$sel:messageBody:BitsV2Message] :: Message -> String
- Web.TwitchAPI.PubSub: [$sel:messageBody:SubscriptionMessage] :: SubscriptionMessage -> String
- Web.TwitchAPI.PubSub: [$sel:messageId:BitsV2Message] :: Message -> String
- Web.TwitchAPI.PubSub: [$sel:messageType:BitsV2Message] :: Message -> String
- Web.TwitchAPI.PubSub: [$sel:months:BitsV2Message] :: Message -> Integer
- Web.TwitchAPI.PubSub: [$sel:newVersion:BadgeUnlock] :: BadgeUnlock -> Integer
- Web.TwitchAPI.PubSub: [$sel:nonce:BitsV2Message] :: Message -> Maybe String
- Web.TwitchAPI.PubSub: [$sel:nonce:Request] :: Request -> Maybe String
- Web.TwitchAPI.PubSub: [$sel:nonce:Response] :: Response -> Maybe String
- Web.TwitchAPI.PubSub: [$sel:paused:BitsV2Message] :: Message -> Bool
- Web.TwitchAPI.PubSub: [$sel:previousVersion:BadgeUnlock] :: BadgeUnlock -> Integer
- Web.TwitchAPI.PubSub: [$sel:prompt:BitsV2Message] :: Message -> Maybe String
- Web.TwitchAPI.PubSub: [$sel:recipient:BitsV2Message] :: Message -> UserInfo
- Web.TwitchAPI.PubSub: [$sel:redeemedTime:BitsV2Message] :: Message -> Maybe UTCTime
- Web.TwitchAPI.PubSub: [$sel:requestType:Request] :: Request -> RequestType
- Web.TwitchAPI.PubSub: [$sel:rewardId:BitsV2Message] :: Message -> String
- Web.TwitchAPI.PubSub: [$sel:serverTime:BitsV2Message] :: Message -> Maybe UTCTime
- Web.TwitchAPI.PubSub: [$sel:status:BitsV2Message] :: Message -> RewardStatus
- Web.TwitchAPI.PubSub: [$sel:streakMonths:BitsV2Message] :: Message -> Maybe Integer
- Web.TwitchAPI.PubSub: [$sel:subMessage:BitsV2Message] :: Message -> SubscriptionMessage
- Web.TwitchAPI.PubSub: [$sel:subOnly:BitsV2Message] :: Message -> Bool
- Web.TwitchAPI.PubSub: [$sel:subPlanName:BitsV2Message] :: Message -> String
- Web.TwitchAPI.PubSub: [$sel:subTier:BitsV2Message] :: Message -> SubscriptionTier
- Web.TwitchAPI.PubSub: [$sel:threadId:BitsV2Message] :: Message -> String
- Web.TwitchAPI.PubSub: [$sel:time:BitsV2Message] :: Message -> Maybe UTCTime
- Web.TwitchAPI.PubSub: [$sel:tiny:RewardImages] :: RewardImages -> Maybe String
- Web.TwitchAPI.PubSub: [$sel:title:BitsV2Message] :: Message -> String
- Web.TwitchAPI.PubSub: [$sel:topics:Request] :: Request -> [Topic]
- Web.TwitchAPI.PubSub: [$sel:totalMonths:BitsV2Message] :: Message -> Integer
- Web.TwitchAPI.PubSub: [$sel:user:BitsV2Message] :: Message -> UserInfo
- Web.TwitchAPI.PubSub: [$sel:userColor:BitsV2Message] :: Message -> String
- Web.TwitchAPI.PubSub: [$sel:userId:BitsV1] :: Topic -> Integer
- Web.TwitchAPI.PubSub: [$sel:userId:BitsV2Message] :: Message -> Maybe Integer
- Web.TwitchAPI.PubSub: [$sel:userId:UserInfo] :: UserInfo -> Integer
- Web.TwitchAPI.PubSub: [$sel:userInput:BitsV2Message] :: Message -> Maybe String
- Web.TwitchAPI.PubSub: [$sel:userName:BitsV2Message] :: Message -> Maybe String
- Web.TwitchAPI.PubSub: [$sel:userName:UserInfo] :: UserInfo -> String
- Web.TwitchAPI.PubSub: [$sel:userTotal:BitsV2Message] :: Message -> Integer
- Web.TwitchAPI.PubSub: [$sel:version:BitsV2Message] :: Message -> String
+ Web.TwitchAPI.PubSub: [authToken] :: Request -> String
+ Web.TwitchAPI.PubSub: [autoFulfilled] :: Message -> Bool
+ Web.TwitchAPI.PubSub: [backgroundColor] :: Message -> String
+ Web.TwitchAPI.PubSub: [badge] :: Message -> Maybe BadgeUnlock
+ Web.TwitchAPI.PubSub: [bitsTier] :: Message -> Integer
+ Web.TwitchAPI.PubSub: [bits] :: Message -> Integer
+ Web.TwitchAPI.PubSub: [channelId] :: Message -> Integer
+ Web.TwitchAPI.PubSub: [channelName] :: Message -> String
+ Web.TwitchAPI.PubSub: [channel] :: Topic -> Integer
+ Web.TwitchAPI.PubSub: [chatMessage] :: Message -> Maybe String
+ Web.TwitchAPI.PubSub: [context] :: Message -> String
+ Web.TwitchAPI.PubSub: [cost] :: Message -> Integer
+ Web.TwitchAPI.PubSub: [defaultImage] :: Message -> RewardImages
+ Web.TwitchAPI.PubSub: [displayName] :: UserInfo -> Maybe String
+ Web.TwitchAPI.PubSub: [emoteId] :: EmoteSpec -> Integer
+ Web.TwitchAPI.PubSub: [emoteLength] :: EmoteSpec -> Integer
+ Web.TwitchAPI.PubSub: [emoteStart] :: EmoteSpec -> Integer
+ Web.TwitchAPI.PubSub: [enabled] :: Message -> Bool
+ Web.TwitchAPI.PubSub: [endMonth] :: Message -> Integer
+ Web.TwitchAPI.PubSub: [errorReported] :: Response -> RequestError
+ Web.TwitchAPI.PubSub: [errorString] :: Message -> String
+ Web.TwitchAPI.PubSub: [huge] :: RewardImages -> Maybe String
+ Web.TwitchAPI.PubSub: [image] :: Message -> Maybe RewardImages
+ Web.TwitchAPI.PubSub: [inStock] :: Message -> Bool
+ Web.TwitchAPI.PubSub: [large] :: RewardImages -> Maybe String
+ Web.TwitchAPI.PubSub: [maxPerStream] :: Message -> Maybe Integer
+ Web.TwitchAPI.PubSub: [messageBody] :: Message -> String
+ Web.TwitchAPI.PubSub: [messageEmotes] :: Message -> [EmoteSpec]
+ Web.TwitchAPI.PubSub: [messageId] :: Message -> String
+ Web.TwitchAPI.PubSub: [messageType] :: Message -> String
+ Web.TwitchAPI.PubSub: [messageUserName] :: Message -> Maybe String
+ Web.TwitchAPI.PubSub: [messageUser] :: Message -> Maybe Integer
+ Web.TwitchAPI.PubSub: [months] :: Message -> Integer
+ Web.TwitchAPI.PubSub: [newVersion] :: BadgeUnlock -> Integer
+ Web.TwitchAPI.PubSub: [nonce] :: Message -> Maybe String
+ Web.TwitchAPI.PubSub: [paused] :: Message -> Bool
+ Web.TwitchAPI.PubSub: [previousVersion] :: BadgeUnlock -> Integer
+ Web.TwitchAPI.PubSub: [prompt] :: Message -> Maybe String
+ Web.TwitchAPI.PubSub: [recipient] :: Message -> UserInfo
+ Web.TwitchAPI.PubSub: [redeemedTime] :: Message -> Maybe UTCTime
+ Web.TwitchAPI.PubSub: [requestNonce] :: Request -> Maybe String
+ Web.TwitchAPI.PubSub: [requestType] :: Request -> RequestType
+ Web.TwitchAPI.PubSub: [responseNonce] :: Response -> Maybe String
+ Web.TwitchAPI.PubSub: [rewardId] :: Message -> String
+ Web.TwitchAPI.PubSub: [serverTime] :: Message -> Maybe UTCTime
+ Web.TwitchAPI.PubSub: [status] :: Message -> RewardStatus
+ Web.TwitchAPI.PubSub: [streakMonths] :: Message -> Maybe Integer
+ Web.TwitchAPI.PubSub: [subMessage] :: Message -> SubscriptionMessage
+ Web.TwitchAPI.PubSub: [subOnly] :: Message -> Bool
+ Web.TwitchAPI.PubSub: [subPlanName] :: Message -> String
+ Web.TwitchAPI.PubSub: [subTier] :: Message -> SubscriptionTier
+ Web.TwitchAPI.PubSub: [subscriptionEmotes] :: SubscriptionMessage -> [EmoteSpec]
+ Web.TwitchAPI.PubSub: [subscriptionMessage] :: SubscriptionMessage -> String
+ Web.TwitchAPI.PubSub: [threadId] :: Message -> String
+ Web.TwitchAPI.PubSub: [time] :: Message -> Maybe UTCTime
+ Web.TwitchAPI.PubSub: [tiny] :: RewardImages -> Maybe String
+ Web.TwitchAPI.PubSub: [title] :: Message -> String
+ Web.TwitchAPI.PubSub: [topics] :: Request -> [Topic]
+ Web.TwitchAPI.PubSub: [totalMonths] :: Message -> Integer
+ Web.TwitchAPI.PubSub: [userColor] :: Message -> String
+ Web.TwitchAPI.PubSub: [userId] :: UserInfo -> Integer
+ Web.TwitchAPI.PubSub: [userInfo] :: Message -> UserInfo
+ Web.TwitchAPI.PubSub: [userInput] :: Message -> Maybe String
+ Web.TwitchAPI.PubSub: [userName] :: UserInfo -> String
+ Web.TwitchAPI.PubSub: [userTotal] :: Message -> Integer
+ Web.TwitchAPI.PubSub: [user] :: Topic -> Integer
+ Web.TwitchAPI.PubSub: [version] :: Message -> String

Files

CHANGELOG.md view
@@ -1,5 +1,9 @@ # Revision history for twitchapi +## 0.0.4 -- 2022-11-14++* Restructured PubSub API to remove DuplicateRecordFields dependency+ ## 0.0.3 -- 2022-11-09  * Restructured Helix API to remove DuplicateRecordFields dependency
src/Web/TwitchAPI/PubSub.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE DeriveGeneric         #-}-{-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE LambdaCase            #-} {-# LANGUAGE RecordWildCards       #-} {-# LANGUAGE OverloadedStrings     #-} {-# LANGUAGE ScopedTypeVariables   #-}@@ -20,6 +20,9 @@  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 )@@ -29,30 +32,28 @@                   , Object                   ) -import qualified Data.Aeson as JSON- import Control.Monad ( mzero ) import GHC.Generics  ( Generic )  import qualified Data.Aeson.Types as JSON.Types -data Topic = BitsV1 { channelId :: Integer }-           | BitsV2 { channelId :: Integer }-           | BitsBadge { channelId :: Integer }-           | ChannelPoints { channelId :: Integer }-           | ChannelSubscriptions { channelId :: Integer }-           | ChatModeratorActions { channelId :: Integer, userId :: Integer }-           | Whispers { userId :: Integer }+data Topic = BitsV1 { channel :: Integer }+           | BitsV2 { channel :: Integer }+           | BitsBadge { channel :: Integer }+           | ChannelPoints { channel :: Integer }+           | ChannelSubscriptions { channel :: Integer }+           | ChatModeratorActions { channel :: Integer, user :: Integer }+           | Whispers { user :: Integer }            deriving ( Eq, Show )  toRequest :: Topic -> String-toRequest BitsV1{..} = ("channel-bits-events-v1." ++) $ show channelId-toRequest BitsV2{..} = ("channel-bits-events-v2." ++) $ show channelId-toRequest BitsBadge{..} = ("channel-bits-badge-unlocks." ++) $ show channelId-toRequest ChannelPoints{..} = ("channel-points-channel-v1." ++) $ show channelId-toRequest ChannelSubscriptions{..} = ("channel-subscribe-events-v1." ++) $ show channelId-toRequest ChatModeratorActions{..} = "chat_moderator_actions." ++ (show userId) ++ "." ++ (show channelId)-toRequest Whispers{..} = ("whispers." ++) $ show userId+toRequest BitsV1{..} = ("channel-bits-events-v1." ++) $ show channel+toRequest BitsV2{..} = ("channel-bits-events-v2." ++) $ show channel+toRequest BitsBadge{..} = ("channel-bits-badge-unlocks." ++) $ show channel+toRequest ChannelPoints{..} = ("channel-points-channel-v1." ++) $ show channel+toRequest ChannelSubscriptions{..} = ("channel-subscribe-events-v1." ++) $ show channel+toRequest ChatModeratorActions{..} = "chat_moderator_actions." ++ show user ++ "." ++ show channel+toRequest Whispers{..} = ("whispers." ++) $ show user  scope :: Topic -> String scope BitsV1{} = "bits:read"@@ -70,15 +71,15 @@     show Unlisten = "UNLISTEN"  data Request = Request { requestType :: RequestType-                       , nonce :: Maybe String+                       , requestNonce :: Maybe String                        , topics :: [Topic]                        , authToken :: String                        } deriving ( Eq, Show )  instance ToJSON Request where     toJSON Request{..} =-        object [ "type" .= (show requestType)-               , "nonce" .= nonce+        object [ "type" .= show requestType+               , "nonce" .= requestNonce                , "data" .= object [ "topics" .= (toRequest <$> topics)                                   , "auth_token" .= authToken                                   ]@@ -93,7 +94,7 @@     readsPrec _ "ERR_BADTOPIC"   = [(BadTopic, "")]     readsPrec _ _                = [(None, "")] -data Response = Response { nonce :: Maybe String+data Response = Response { responseNonce :: Maybe String                          , errorReported :: RequestError                          } deriving ( Show, Eq ) @@ -102,7 +103,7 @@         o .: "type" >>= \(reportedType :: String) ->         -- This value is required per Twitch or else any response is invalid         if reportedType == "RESPONSE" then do-            nonce <- o .: "nonce"+            responseNonce <- o .: "nonce"             err <- o .: "error"             let errorReported = read err :: RequestError             return Response{..}@@ -154,13 +155,12 @@ data SubscriptionTier = Prime | Tier1 | Tier2 | Tier3 deriving ( Eq, Show, Generic )  instance FromJSON SubscriptionTier where-    parseJSON = withText "SubscriptionTier" $ \o ->-        case o of-            "1000" -> return Tier1-            "2000" -> return Tier2-            "3000" -> return Tier3-            "Prime" -> return Prime-            _ -> mzero+    parseJSON = withText "SubscriptionTier" $ \case+        "1000" -> return Tier1+        "2000" -> return Tier2+        "3000" -> return Tier3+        "Prime" -> return Prime+        _ -> mzero  data EmoteSpec = EmoteSpec { emoteStart :: Integer                            , emoteLength :: Integer@@ -182,17 +182,15 @@                 let emoteId = read altEmoteId :: Integer                 return EmoteSpec{..} -data SubscriptionMessage = SubscriptionMessage { messageBody :: String-                                               , emotes :: [EmoteSpec]+data SubscriptionMessage = SubscriptionMessage { subscriptionMessage :: String+                                               , subscriptionEmotes :: [EmoteSpec]                                                } deriving ( Eq, Show, Generic )  instance FromJSON SubscriptionMessage where     parseJSON = withObject "SubscriptionMessage" $ \o -> do-        messageBody <- o .: "message"+        subscriptionMessage <- o .: "message"         emotes' <- o .:? "emotes"-        let emotes = case emotes' of-                         Nothing -> []-                         Just xs -> xs+        let subscriptionEmotes = Maybe.fromMaybe [] emotes'         return SubscriptionMessage{..}  data Message = BitsV2Message { badge :: Maybe BadgeUnlock@@ -204,8 +202,8 @@                              , messageType :: String                              , time :: Maybe Time.UTCTime                              , userTotal :: Integer-                             , userId :: Maybe Integer-                             , userName :: Maybe String+                             , messageUser :: Maybe Integer+                             , messageUserName :: Maybe String                              , version :: String                              }              | BitsV2AnonymousMessage { bits :: Integer@@ -227,12 +225,12 @@                              , messageType :: String                              , time :: Maybe Time.UTCTime                              , userTotal :: Integer-                             , userId :: Maybe Integer-                             , userName :: Maybe String+                             , messageUser :: Maybe Integer+                             , messageUserName :: Maybe String                              , version :: String                              }-             | BitsBadgeMessage { userId :: Maybe Integer-                                , userName :: Maybe String+             | BitsBadgeMessage { messageUser :: Maybe Integer+                                , messageUserName :: Maybe String                                 , channelId :: Integer                                 , channelName :: String                                 , bitsTier :: Integer@@ -241,7 +239,7 @@                                 }              | ChannelPointsMessage { serverTime :: Maybe Time.UTCTime                                     , redeemedTime :: Maybe Time.UTCTime-                                    , user :: UserInfo+                                    , userInfo :: UserInfo                                     , rewardId :: String                                     , channelId :: Integer                                     , title :: String@@ -259,7 +257,7 @@                                     , autoFulfilled :: Bool                                     , status :: RewardStatus                                     }-             | ChannelSubscriptionMessage { user :: UserInfo+             | ChannelSubscriptionMessage { userInfo :: UserInfo                                           , channelName :: String                                           , channelId :: Integer                                           , time :: Maybe Time.UTCTime@@ -267,7 +265,7 @@                                           , subPlanName :: String                                           , subMessage :: SubscriptionMessage                                           }-             | ChannelResubscriptionMessage { user :: UserInfo+             | ChannelResubscriptionMessage { userInfo :: UserInfo                                             , channelName :: String                                             , channelId :: Integer                                             , time :: Maybe Time.UTCTime@@ -277,7 +275,7 @@                                             , streakMonths :: Maybe Integer                                             , subMessage :: SubscriptionMessage                                             }-             | ChannelExtendSubscriptionMessage { user :: UserInfo+             | ChannelExtendSubscriptionMessage { userInfo :: UserInfo                                                 , channelName :: String                                                 , channelId :: Integer                                                 , time :: Maybe Time.UTCTime@@ -288,7 +286,7 @@                                                 , endMonth :: Integer                                                 , subMessage :: SubscriptionMessage                                                 }-             | ChannelSubscriptionGiftMessage { user :: UserInfo+             | ChannelSubscriptionGiftMessage { userInfo :: UserInfo                                               , channelName :: String                                               , channelId :: Integer                                               , time :: Maybe Time.UTCTime@@ -296,7 +294,7 @@                                               , subPlanName :: String                                               , recipient :: UserInfo                                               }-             | ChannelMultiMonthSubscriptionGiftMessage { user :: UserInfo+             | ChannelMultiMonthSubscriptionGiftMessage { userInfo :: UserInfo                                                         , channelName :: String                                                         , channelId :: Integer                                                         , time :: Maybe Time.UTCTime@@ -324,8 +322,8 @@                               , threadId :: String                               , time :: Maybe Time.UTCTime                               , messageBody :: String-                              , emotes :: [EmoteSpec]-                              , user :: UserInfo+                              , messageEmotes :: [EmoteSpec]+                              , userInfo :: UserInfo                               , userColor :: String                               , recipient :: UserInfo                               }@@ -348,10 +346,10 @@ parseChannelSubscribeEvent :: MessageParser parseChannelSubscribeEvent o = do     uid :: String <- o .: "user_id"-    userName <- o .: "user_name"+    messageUserName <- o .: "user_name"     displayName <- o .: "display_name"-    let userId = read uid :: Integer-        user = UserInfo userId userName displayName+    let messageUser = read uid :: Integer+        userInfo = UserInfo messageUser messageUserName displayName      channelName <- o .: "channel_name"     channel <- o .: "channel_id"@@ -369,10 +367,10 @@ parseChannelResubscribeEvent :: MessageParser parseChannelResubscribeEvent o = do     uid :: String <- o .: "user_id"-    userName <- o .: "user_name"+    messageUserName <- o .: "user_name"     displayName <- o .: "display_name"-    let userId = read uid :: Integer-        user = UserInfo userId userName displayName+    let messageUser = read uid :: Integer+        userInfo = UserInfo messageUser messageUserName displayName      channelName <- o .: "channel_name"     channel <- o .: "channel_id"@@ -392,10 +390,10 @@ parseChannelExtendSubEvent :: MessageParser parseChannelExtendSubEvent o = do     uid :: String <- o .: "user_id"-    userName <- o .: "user_name"+    messageUserName <- o .: "user_name"     displayName <- o .: "display_name"-    let userId = read uid :: Integer-        user = UserInfo userId userName displayName+    let messageUser = read uid :: Integer+        userInfo = UserInfo messageUser messageUserName displayName      channelName <- o .: "channel_name"     channel <- o .: "channel_id"@@ -416,10 +414,10 @@ parseChannelSubGiftEvent :: MessageParser parseChannelSubGiftEvent o = do     uid :: String <- o .: "user_id"-    userName <- o .: "user_name"+    messageUserName <- o .: "user_name"     displayName <- o .: "display_name"-    let userId = read uid :: Integer-        user = UserInfo userId userName displayName+    let messageUser = read uid :: Integer+        userInfo = UserInfo messageUser messageUserName displayName      rid :: String <- o .: "recipient_id"     rUserName <- o .: "recipient_user_name"@@ -499,14 +497,14 @@     messageId <- o .: "message_id"     messageType <- o .: "message_type" -- Always bits_event?  No other examples given in API docs     userTotal <- dat .: "total_bits_used"-    userName <- dat .: "user_name"+    messageUserName <- dat .: "user_name"     version <- o .: "version"      channel :: String <- dat .: "channel_id"     let channelId = read channel :: Integer      uid :: Maybe String <- dat .: "user_id"-    let userId = fmap (read :: String -> Integer) uid+    let messageUser = fmap (read :: String -> Integer) uid      t :: String <- dat .: "time"     let time = Time.zonedTimeToUTC <$> Time.parseTimeRFC3339 t@@ -541,11 +539,11 @@     messageId <- o .: "message_id"     messageType <- o .: "message_type" -- Always bits_event?  No other examples given in API docs     userTotal <- dat .: "total_bits_used"-    userName <- dat .: "user_name"+    messageUserName <- dat .: "user_name"     version <- o .: "version"      uid :: Maybe String <- dat .: "user_id"-    let userId = fmap (read :: String -> Integer) uid+    let messageUser = fmap (read :: String -> Integer) uid      channel :: String <- dat .: "channel_id"     let channelId = read channel :: Integer@@ -557,8 +555,8 @@  parseBitsBadgeMessage :: MessageParser parseBitsBadgeMessage o = do-    userId <- o .: "user_id"-    userName <- o .: "user_name"+    messageUser <- o .: "user_id"+    messageUserName <- o .: "user_name"     channelName <- o .: "channel_name"     bitsTier <- o .: "badge_tier"     chatMessage <- o .: "chat_message"@@ -574,7 +572,7 @@     dat <- o .: "data"     redemption <- dat .: "redemption"     reward <- redemption .: "reward"-    user <- redemption .: "user"+    userInfo <- redemption .: "user"     rewardId <- reward .: "id"     title <- reward .: "title"     prompt <- reward .: "prompt"@@ -617,13 +615,13 @@     threadId <- dat .: "thread_id"     messageBody <- dat .: "body"     tags <- dat .: "tags"-    emotes <- tags .: "emotes"+    messageEmotes <- tags .: "emotes"     userColor <- tags .: "color" -    userId <- dat .: "from_id"-    userName <- tags .: "login"+    messageUser <- dat .: "from_id"+    messageUserName <- tags .: "login"     displayName <- tags .: "display_name"-    let user = UserInfo userId userName displayName+    let userInfo = UserInfo messageUser messageUserName displayName      recipientData <- dat .: "recipient"     rUserId <- recipientData .: "id"
twitchapi.cabal view
@@ -1,5 +1,5 @@ name:                twitchapi-version:             0.0.3+version:             0.0.4 synopsis:            Client access to Twitch.tv API endpoints description:         Twitch.tv API client supporting Helix and PubSub homepage:            https://github.com/wuest/haskell-twitchapi