summaryrefslogtreecommitdiff
path: root/deps/discord-haskell/examples/ping-pong.hs
diff options
context:
space:
mode:
authorLLLL Colonq <llll@colonq>2023-11-16 19:06:43 -0500
committerLLLL Colonq <llll@colonq>2023-11-16 19:06:43 -0500
commitdcef0b65069fb38fd0f6c4382353167f603ebff1 (patch)
tree45954ffe308c3dd056e6af4f734e6d2af89e5856 /deps/discord-haskell/examples/ping-pong.hs
Initial commit
Diffstat (limited to 'deps/discord-haskell/examples/ping-pong.hs')
-rw-r--r--deps/discord-haskell/examples/ping-pong.hs97
1 files changed, 97 insertions, 0 deletions
diff --git a/deps/discord-haskell/examples/ping-pong.hs b/deps/discord-haskell/examples/ping-pong.hs
new file mode 100644
index 0000000..87ec08b
--- /dev/null
+++ b/deps/discord-haskell/examples/ping-pong.hs
@@ -0,0 +1,97 @@
+{-# LANGUAGE OverloadedStrings #-} -- allows "strings" to be Data.Text
+
+import Control.Monad (when, void)
+import qualified Data.Text as T
+import qualified Data.Text.IO as TIO
+
+import UnliftIO (liftIO)
+import UnliftIO.Concurrent
+
+import Discord
+import Discord.Types
+import qualified Discord.Requests as R
+
+import ExampleUtils (getToken, getGuildId, actionWithChannelId)
+
+-- Allows this code to be an executable. See discord-haskell.cabal
+main :: IO ()
+main = pingpongExample
+
+-- | Replies "pong" to every message that starts with "ping"
+pingpongExample :: IO ()
+pingpongExample = do
+ tok <- getToken
+ testserverid <- getGuildId
+
+ -- open ghci and run [[ :info RunDiscordOpts ]] to see available fields
+ err <- runDiscord $ def { discordToken = tok
+ , discordOnStart = startHandler testserverid
+ , discordOnEnd = liftIO $ threadDelay (round (0.4 * 10^6)) >> putStrLn "Ended"
+ , discordOnEvent = eventHandler
+ , discordOnLog = \s -> TIO.putStrLn s >> TIO.putStrLn ""
+ , discordGatewayIntent = def {gatewayIntentMembers = True, gatewayIntentPresences =True}
+ }
+
+ -- only reached on an unrecoverable error
+ -- put normal 'cleanup' code in discordOnEnd
+ TIO.putStrLn err
+
+-- If the start handler throws an exception, discord-haskell will gracefully shutdown
+-- Use place to execute commands you know you want to complete
+startHandler :: GuildId -> DiscordHandler ()
+startHandler testserverid = do
+ liftIO $ putStrLn "Started ping-pong bot"
+
+ let activity = def { activityName = "ping-pong"
+ , activityType = ActivityTypeGame
+ }
+ let opts = UpdateStatusOpts { updateStatusOptsSince = Nothing
+ , updateStatusOptsGame = Just activity
+ , updateStatusOptsNewStatus = UpdateStatusOnline
+ , updateStatusOptsAFK = False
+ }
+ sendCommand (UpdateStatus opts)
+
+ actionWithChannelId testserverid $ \cid ->
+ void $
+ restCall $
+ R.CreateMessage
+ cid
+ "Hello! I will reply to pings with pongs"
+
+
+-- If an event handler throws an exception, discord-haskell will continue to run
+eventHandler :: Event -> DiscordHandler ()
+eventHandler event = case event of
+ MessageCreate m -> when (not (fromBot m) && isPing m) $ do
+ void $ restCall (R.CreateReaction (messageChannelId m, messageId m) "eyes")
+ threadDelay (2 * 10 ^ (6 :: Int))
+
+ -- A very simple message.
+ Right m' <- restCall (R.CreateMessage (messageChannelId m) "Pong")
+ void $ restCall (R.EditMessage (messageChannelId m, messageId m') (def {R.messageDetailedContent=messageContent m' <> "!"}))
+
+ latency <- getGatewayLatency
+ mLatency <- measureLatency
+
+ -- A more complex message. Text-to-speech, does not mention everyone nor
+ -- the user, and uses Discord native replies.
+ -- Use ":info" in ghci to explore the type
+ let opts :: R.MessageDetailedOpts
+ opts = def { R.messageDetailedContent = "Here's a more complex message, but doesn't ping @everyone!. Here's the current gateway latency: " <> (T.pack . show) ([latency, mLatency])
+ , R.messageDetailedTTS = True
+ , R.messageDetailedAllowedMentions = Just $
+ def { R.mentionEveryone = False
+ , R.mentionRepliedUser = False
+ }
+ , R.messageDetailedReference = Just $
+ def { referenceMessageId = Just $ messageId m }
+ }
+ void $ restCall (R.CreateMessageDetailed (messageChannelId m) opts)
+ _ -> return ()
+
+fromBot :: Message -> Bool
+fromBot = userIsBot . messageAuthor
+
+isPing :: Message -> Bool
+isPing = ("ping" `T.isPrefixOf`) . T.toLower . messageContent