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.

226 lines
9.4 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
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. module Commands where
  4. import Commands.EDT ( getEdt )
  5. import Commands.Reminds ( Remind(..)
  6. , registerRemind
  7. , scheduleRemind
  8. )
  9. import Conf ( Config(..)
  10. , Group(..)
  11. )
  12. import Control.Event ( EventSystem
  13. , addEvent
  14. )
  15. import Control.Monad ( when )
  16. import Control.Monad.IO.Class ( liftIO )
  17. import qualified Data.Map.Strict as Map
  18. import Data.Maybe ( fromMaybe )
  19. import qualified Data.Text as T
  20. import Data.Time ( addUTCTime
  21. , getCurrentTime
  22. )
  23. import Discord ( DiscordHandler
  24. , restCall
  25. )
  26. import Discord.Interactions ( ApplicationCommandOptionValue(..)
  27. , ApplicationCommandOptions(..)
  28. , Choice(..)
  29. , CreateApplicationCommand(..)
  30. , InteractionDataApplicationCommandOptionValue(..)
  31. , InteractionDataApplicationCommandOptions(..)
  32. , InteractionResponse
  33. , MemberOrUser(..)
  34. , createApplicationCommandChatInput
  35. , interactionResponseBasic
  36. )
  37. import Discord.Requests ( ChannelRequest(..)
  38. , GuildRequest(..)
  39. )
  40. import Discord.Types ( ChannelId
  41. , GuildId
  42. , GuildMember(..)
  43. , Snowflake
  44. , UTCTime
  45. , User(..)
  46. )
  47. import UnliftIO ( withRunInIO )
  48. groupNames :: Config -> [T.Text]
  49. groupNames Config {..} = map fst $ Map.toList configGroups
  50. pingCommand :: Maybe CreateApplicationCommand
  51. pingCommand = createApplicationCommandChatInput "ping" "pong"
  52. pingResponse :: Config -> IO InteractionResponse
  53. pingResponse _ = return $ interactionResponseBasic "Pong"
  54. edtCommand :: Config -> Maybe CreateApplicationCommand
  55. edtCommand c =
  56. createApplicationCommandChatInput "edt" "Gets the planning for a group"
  57. >>= \cac -> return $ cac
  58. { createApplicationCommandOptions =
  59. Just $ ApplicationCommandOptionsValues
  60. [ ApplicationCommandOptionValueString
  61. "group"
  62. "The group for which the planning is requested"
  63. True
  64. (Right $ map (\x -> Choice x x) $ groupNames c)
  65. , ApplicationCommandOptionValueString
  66. "day"
  67. ( "The day(s) for which the planning is requested "
  68. `T.append` "(today, tomorrow, week or DD/MM/YYYY)"
  69. )
  70. False
  71. (Left False)
  72. ]
  73. }
  74. parseOpt :: InteractionDataApplicationCommandOptionValue -> (T.Text, T.Text)
  75. parseOpt InteractionDataApplicationCommandOptionValueString { interactionDataApplicationCommandOptionValueName = name, interactionDataApplicationCommandOptionValueStringValue = Right val, ..}
  76. = (name, val)
  77. parseOpt _ = ("INVALID Option", "INVALID type")
  78. edtResponse
  79. :: Config
  80. -> Maybe InteractionDataApplicationCommandOptions
  81. -> IO InteractionResponse
  82. edtResponse conf@Config {..} (Just (InteractionDataApplicationCommandOptionsValues opts))
  83. = do
  84. planning <- getEdt conf parsedOpts
  85. return $ interactionResponseBasic planning
  86. where
  87. parsedOpts :: Map.Map T.Text T.Text
  88. parsedOpts = Map.fromList $ map parseOpt opts
  89. edtResponse _ _ = return $ interactionResponseBasic
  90. "The edt command has mandatory params yet you managed not to give any, WOW"
  91. remindCommand :: Maybe CreateApplicationCommand
  92. remindCommand =
  93. createApplicationCommandChatInput "remind" "reminds you of something later on"
  94. >>= \cac -> return $ cac
  95. { createApplicationCommandOptions =
  96. Just $ ApplicationCommandOptionsValues
  97. [ ApplicationCommandOptionValueString "delay"
  98. "delay"
  99. True
  100. (Left False)
  101. , ApplicationCommandOptionValueString "message"
  102. "message"
  103. True
  104. (Left False)
  105. ]
  106. }
  107. remindResponse
  108. :: Maybe InteractionDataApplicationCommandOptions
  109. -> EventSystem
  110. -> ChannelId
  111. -> MemberOrUser
  112. -> DiscordHandler InteractionResponse
  113. remindResponse (Just (InteractionDataApplicationCommandOptionsValues opts)) evts ch mou
  114. = do
  115. let
  116. userid = case mou of
  117. MemberOrUser (Left GuildMember { memberUser = Just User { userId = uid } })
  118. -> uid
  119. MemberOrUser (Right User { userId = uid }) -> uid
  120. _ -> error "Couldnt get user id"
  121. let d = delay'
  122. now <- liftIO getCurrentTime
  123. let
  124. remindDateTime = case T.last d of
  125. 's' -> addUTCTime (fromInteger $ read $ init $ T.unpack d) now
  126. 'm' -> addUTCTime ((* 60) $ fromInteger $ read $ init $ T.unpack d) now
  127. 'h' ->
  128. addUTCTime ((* 3600) $ fromInteger $ read $ init $ T.unpack d) now
  129. 'd' ->
  130. addUTCTime ((* 86400) $ fromInteger $ read $ init $ T.unpack d) now
  131. _ -> now
  132. if remindDateTime /= now
  133. then do
  134. let rmd = Remind { rmdUser = userid
  135. , rmdChannel = ch
  136. , rmdMessage = message
  137. , rmdDatetime = remindDateTime
  138. }
  139. scheduleRemind evts rmd
  140. liftIO $ registerRemind rmd
  141. return
  142. $ interactionResponseBasic
  143. $ "Reminder registered sucessfully for "
  144. `T.append` T.pack (show remindDateTime)
  145. else return $ interactionResponseBasic "couldn't parse your delay :/"
  146. where
  147. parsedOpts = Map.fromList $ map parseOpt opts
  148. delay' =
  149. fromMaybe (error "delay must exist wtf") $ Map.lookup "delay" parsedOpts
  150. message = fromMaybe (error "message must exist, wtf")
  151. $ Map.lookup "message" parsedOpts
  152. remindResponse _ _ _ _ =
  153. return
  154. $ interactionResponseBasic
  155. "The remind command has mandatory params, yet you managed not to give any, WOW"
  156. groupCommand :: Config -> Maybe CreateApplicationCommand
  157. groupCommand c =
  158. createApplicationCommandChatInput "group" "grab your group" >>= \cac ->
  159. return $ cac
  160. { createApplicationCommandOptions = Just $ ApplicationCommandOptionsValues
  161. [ ApplicationCommandOptionValueString
  162. "group"
  163. "Your group"
  164. True
  165. (Right $ map (\x -> Choice x x) $ groupNames c)
  166. ]
  167. }
  168. groupResponse
  169. :: Config
  170. -> MemberOrUser
  171. -> GuildId
  172. -> Maybe InteractionDataApplicationCommandOptions
  173. -> DiscordHandler InteractionResponse
  174. groupResponse c mou gid (Just (InteractionDataApplicationCommandOptionsValues opts))
  175. = do
  176. let
  177. uid = case mou of
  178. MemberOrUser (Left GuildMember { memberUser = Just User { userId = uid } })
  179. -> uid
  180. MemberOrUser (Right User { userId = uid }) -> uid
  181. _ -> -1
  182. let rid =
  183. groupRole
  184. $ fromMaybe (error "group must exist")
  185. $ Map.lookup group
  186. $ configGroups c
  187. restCall $ AddGuildMemberRole gid uid rid
  188. return
  189. $ interactionResponseBasic
  190. $ "You are now part of group "
  191. `T.append` group
  192. where
  193. group =
  194. fromMaybe (error "required option")
  195. $ Map.lookup "group"
  196. $ Map.fromList
  197. $ map parseOpt opts
  198. groupResponse _ _ _ _ =
  199. return
  200. $ interactionResponseBasic
  201. "the group command has mandatory params, yet you managed not to give any, WOW"
  202. helpCommand :: Maybe CreateApplicationCommand
  203. helpCommand = createApplicationCommandChatInput "help" "help"
  204. helpResponse :: IO InteractionResponse
  205. helpResponse =
  206. return
  207. . interactionResponseBasic
  208. $ "**__Help for Bot IUT__**\n\n"
  209. `T.append` "`/help` shows this help message\n"
  210. `T.append` "`/group <group>` join a group\n"
  211. `T.append` "`/remind <time><s|m|h|d> <message>` reminds you of something in the future\n"
  212. `T.append` "`/edt <group> [week|today|tomorrow|dd/mm/yyyy]` get the planning for group `group` on `day` (`day` defaults to `week`)"