summaryrefslogtreecommitdiff
path: root/fig-monitor-twitch/src/Fig/Monitor/Twitch/LiveChecker.hs
blob: cf0389af65087c96b549c85983e30bbb505bb282 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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