You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
5.5 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. {-# LANGUAGE OverloadedStrings #-}
  2. {-# LANGUAGE RecordWildCards #-}
  3. {-# LANGUAGE ScopedTypeVariables #-}
  4. module Main where
  5. import Control.Monad (when, void)
  6. import qualified Data.Text as T
  7. import qualified Data.Text.IO as TIO
  8. import Control.Monad.IO.Unlift (toIO, liftIO, withRunInIO)
  9. import Discord ( def, restCall
  10. , runDiscord, sendCommand
  11. , DiscordHandler
  12. , RunDiscordOpts(..)
  13. )
  14. import Discord.Types ( Event(..), PartialApplication(..)
  15. , GatewaySendable(..)
  16. , UpdateStatusOpts(..)
  17. , UpdateStatusType(..)
  18. , Activity(..), ActivityType(..)
  19. )
  20. import Discord.Interactions ( interactionResponseBasic
  21. , Interaction(..)
  22. , InteractionDataApplicationCommand(..)
  23. )
  24. import qualified Discord.Requests as R
  25. import Commands ( edtResponse, edtCommand
  26. , pingResponse, pingCommand
  27. , remindResponse, remindCommand, groupCommand, groupResponse
  28. )
  29. import Conf ( Config(..), Group(..), readConfig )
  30. import qualified System.Cron.Schedule as Cron
  31. import qualified Data.Map.Strict as Map
  32. import Commands.EDT (getEdt)
  33. import qualified Control.Concurrent
  34. import qualified Control.Event as E
  35. main :: IO ()
  36. main = do
  37. tok <- TIO.readFile "./auth.secret"
  38. conf <- readConfig "./conf.yaml"
  39. eventSystem <- E.initEventSystem
  40. print conf
  41. err <- runDiscord $ def { discordToken = tok
  42. , discordOnStart = onDiscordStart conf
  43. , discordOnEnd = liftIO $ putStrLn "Ended"
  44. , discordOnEvent = onDiscordEvent conf eventSystem
  45. , discordOnLog =
  46. \s -> TIO.putStrLn s >> TIO.putStrLn ""
  47. }
  48. TIO.putStrLn err
  49. onDiscordStart :: Config -> DiscordHandler ()
  50. onDiscordStart conf = do
  51. let
  52. activity :: Activity
  53. activity = def { activityName = "Doing stuff"
  54. , activityType = ActivityTypeGame
  55. , activityUrl = Nothing
  56. }
  57. opts :: UpdateStatusOpts
  58. opts = UpdateStatusOpts { updateStatusOptsSince = Nothing
  59. , updateStatusOptsGame = Just activity
  60. , updateStatusOptsNewStatus = UpdateStatusOnline
  61. , updateStatusOptsAFK = False
  62. }
  63. sendCommand (UpdateStatus opts)
  64. onDiscordEvent :: Config -> E.EventSystem -> Event -> DiscordHandler ()
  65. onDiscordEvent conf@Config{..} eventSystem (Ready _ _ _ _ _ _ (PartialApplication i _)) = do
  66. mapM_ (maybe ( return () )
  67. ( void
  68. . restCall
  69. . R.CreateGuildApplicationCommand i configServer
  70. )
  71. )
  72. [ pingCommand
  73. , edtCommand conf
  74. , remindCommand
  75. , groupCommand conf
  76. ]
  77. let glist = Map.toList configGroups
  78. withRunInIO $ \runInIO -> Cron.execSchedule $ do
  79. Cron.addJob ( runInIO
  80. $ pushgroupedt conf "tomorrow" glist
  81. ) configAutoEDTCronDay
  82. Cron.addJob ( runInIO
  83. $ pushgroupedt conf "week" glist
  84. ) configAutoEDTCronWeek
  85. liftIO $ putStrLn "Started"
  86. onDiscordEvent conf@Config{..} eventSystem
  87. ( InteractionCreate InteractionApplicationCommand
  88. { interactionDataApplicationCommand =
  89. InteractionDataApplicationCommandChatInput
  90. { interactionDataApplicationCommandName = name
  91. , interactionDataApplicationCommandOptions = opts
  92. , ..
  93. }
  94. , interactionChannelId = Just channel
  95. , interactionGuildId = Just guild
  96. , interactionUser = user
  97. , ..
  98. }
  99. ) = do
  100. response <- responseIO
  101. void $ restCall
  102. (R.CreateInteractionResponse interactionId interactionToken response)
  103. where
  104. responseIO = case name of
  105. "ping" -> liftIO $ pingResponse conf
  106. "edt" -> liftIO $ edtResponse conf opts
  107. "remind" -> remindResponse opts eventSystem channel user
  108. "group" -> groupResponse conf user guild opts
  109. _ -> return $ interactionResponseBasic $ "Unhandled Command: " `T.append` name
  110. onDiscordEvent _ _ _ = return ()
  111. pushgroupedt :: Config -> T.Text ->[(T.Text, Group)] -> DiscordHandler ()
  112. pushgroupedt conf@Config{..} day glist = do
  113. mapM_ (\(gn, Group{groupChannel = gc}) -> do
  114. edt <- liftIO $ getEdt conf $ Map.fromList [("group", gn), ("day", day )]
  115. liftIO
  116. $ TIO.putStrLn
  117. $ "Putting out time table for group "
  118. `T.append` gn
  119. `T.append` " in "
  120. `T.append` T.pack (show gc)
  121. `T.append` ":\n"
  122. `T.append` edt
  123. restCall $ R.CreateMessage gc (edt `T.append` "\nAutomatic time table")
  124. return ()
  125. ) glist