summaryrefslogtreecommitdiff
path: root/fig-monitor-twitch/src/Fig/Monitor/Twitch/LiveChecker.hs
diff options
context:
space:
mode:
Diffstat (limited to 'fig-monitor-twitch/src/Fig/Monitor/Twitch/LiveChecker.hs')
-rw-r--r--fig-monitor-twitch/src/Fig/Monitor/Twitch/LiveChecker.hs59
1 files changed, 59 insertions, 0 deletions
diff --git a/fig-monitor-twitch/src/Fig/Monitor/Twitch/LiveChecker.hs b/fig-monitor-twitch/src/Fig/Monitor/Twitch/LiveChecker.hs
new file mode 100644
index 0000000..cf0389a
--- /dev/null
+++ b/fig-monitor-twitch/src/Fig/Monitor/Twitch/LiveChecker.hs
@@ -0,0 +1,59 @@
+module Fig.Monitor.Twitch.LiveChecker
+ ( twitchChannelLiveChecker
+ ) where
+
+import Fig.Prelude
+
+import Control.Concurrent (threadDelay)
+
+import qualified Data.Text as Text
+import qualified Data.Set as Set
+
+import Data.Aeson ((.:))
+import qualified Data.Aeson as Aeson
+import qualified Data.Aeson.Types as Aeson
+
+import Fig.Bus.Binary.Client
+import Fig.Monitor.Twitch.Auth.AppToken
+import Fig.Monitor.Twitch.Utils
+
+twitchChannelLiveChecker :: Config -> (Text, Text) -> IO ()
+twitchChannelLiveChecker cfg busAddr = do
+ busClient busAddr
+ (\cmds -> do
+ let
+ loop :: IO ()
+ loop = do
+ log "Updating liveness..."
+ live <- runAuthed cfg $ usersAreLive cfg.monitor
+ if null live
+ then log "Update complete! No users live"
+ else log $ "Update complete! Live users: " <> Text.unwords (Set.toList live)
+ cmds.publish "fig monitor twitch stream online" . encodeUtf8 . Text.unwords $ Set.toList live
+ threadDelay $ 5 * 60 * 1000000 -- wait 5 minutes
+ loop
+ loop
+ )
+ (\_cmds _ev _d -> pure ())
+ (pure ())
+
+usersAreLive :: [Text] -> Authed (Set.Set Text)
+usersAreLive users = do
+ log $ "Checking liveness for: " <> Text.intercalate " " users
+ res <- authedRequestJSON @()
+ "GET"
+ ( mconcat
+ [ "https://api.twitch.tv/helix/streams?type=live"
+ , mconcat $ ("&user_login="<>) <$> users
+ ]
+ )
+ Nothing
+ let mos = flip Aeson.parseEither res \obj -> do
+ obj .: "data" >>= \case
+ Aeson.Array os -> catMaybes . toList <$> forM os \case
+ Aeson.Object o -> Just <$> o .: "user_login"
+ _else -> pure Nothing
+ _else -> mempty
+ case mos of
+ Left err -> throwM $ FigMonitorTwitchException $ "Failed to check liveness: " <> pack err <> "\nResponse was: " <> tshow res
+ Right os -> pure . Set.fromList $ filter (`elem` os) users