diff --git a/haboli-infobot/app/Main.hs b/haboli-infobot/app/Main.hs index c51dbe5..9c5f4f4 100644 --- a/haboli-infobot/app/Main.hs +++ b/haboli-infobot/app/Main.hs @@ -1,4 +1,9 @@ module Main where +import Control.Monad + +import Haboli.Bots.InfoBot +import Haboli.Euphoria + main :: IO () -main = putStrLn "Nothing to see here!" +main = void $ runClient defaultConfig $ infoBot Nothing diff --git a/haboli-infobot/haboli-infobot.cabal b/haboli-infobot/haboli-infobot.cabal index 71ace72..54ed892 100644 --- a/haboli-infobot/haboli-infobot.cabal +++ b/haboli-infobot/haboli-infobot.cabal @@ -4,7 +4,7 @@ cabal-version: 1.12 -- -- see: https://github.com/sol/hpack -- --- hash: cbb37543f441c735429df4c7e5caec2cf786ed7d2e27cd612cb81c71f5c1be0b +-- hash: 7c1fd2d5312d7a2c2d70aed2270863ae9ee89af790c2eeb279d800f89d110ba1 name: haboli-infobot version: 0.1.0.0 @@ -25,13 +25,19 @@ source-repository head location: https://github.com/Garmelon/haboli-bot-collection library + exposed-modules: + Haboli.Bots.InfoBot other-modules: Paths_haboli_infobot hs-source-dirs: src build-depends: base >=4.7 && <5 + , containers , haboli + , microlens-platform + , text + , time default-language: Haskell2010 executable haboli-infobot @@ -43,6 +49,10 @@ executable haboli-infobot ghc-options: -threaded -rtsopts -with-rtsopts=-N build-depends: base >=4.7 && <5 + , containers , haboli , haboli-infobot + , microlens-platform + , text + , time default-language: Haskell2010 diff --git a/haboli-infobot/package.yaml b/haboli-infobot/package.yaml index 4162f20..1f016e7 100644 --- a/haboli-infobot/package.yaml +++ b/haboli-infobot/package.yaml @@ -13,7 +13,11 @@ extra-source-files: dependencies: - base >= 4.7 && < 5 + - containers - haboli + - microlens-platform + - text + - time library: source-dirs: src diff --git a/haboli-infobot/src/Haboli/Bots/InfoBot.hs b/haboli-infobot/src/Haboli/Bots/InfoBot.hs new file mode 100644 index 0000000..d1a987f --- /dev/null +++ b/haboli-infobot/src/Haboli/Bots/InfoBot.hs @@ -0,0 +1,80 @@ +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TemplateHaskell #-} + +module Haboli.Bots.InfoBot + ( infoBot + ) where + +import Control.Concurrent +import Control.Monad +import Control.Monad.IO.Class +import Data.List +import qualified Data.Map.Strict as Map +import qualified Data.Text as T +import Data.Time +import Lens.Micro.Platform + +import Haboli.Euphoria +import Haboli.Euphoria.Botrulez + +data BotState = BotState + { _botStartTime :: UTCTime + , _botListing :: Listing + } deriving (Show) + +makeLenses ''BotState + +-- | A small example bot. Takes a room password as its first argument. You can +-- run this bot in [&test](https://euphoria.io/room/test) like this: +-- +-- > runClient defaultConfig $ exampleBot Nothing +infoBot :: Maybe T.Text -> Client T.Text () +infoBot mPasswd = do + startTime <- liftIO getCurrentTime + initialEvents <- untilConnected $ + respondingToBounce mPasswd $ + respondingToPing nextEvent + let initialState = BotState startTime $ newListing initialEvents + stateVar <- liftIO $ newMVar initialState + preferNickVia botListing stateVar "InfoBot" + botMain stateVar + +botMain :: MVar BotState -> Client T.Text () +botMain stateVar = forever $ do + event <- respondingToCommands (getCommands stateVar) $ + respondingToPing nextEvent + updateFromEventVia botListing stateVar event + +getCommands :: MVar BotState -> Client e [Command T.Text] +getCommands stateVar = do + state <- liftIO $ readMVar stateVar + let name = state ^. botListing . lsSelfL . svNickL + pure + [ botrulezPingGeneral + , botrulezPingSpecific name + , botrulezHelpSpecific name + "I am an example bot for https://github.com/Garmelon/haboli/." + , botrulezUptimeSpecific name $ state ^. botStartTime + , botrulezKillSpecific name + , cmdSpecific "hug" name $ \msg -> void $ reply msg "/me hugs back" + , cmdHello + , cmdNick stateVar name + , cmdWho stateVar + ] + +cmdHello :: Command e +cmdHello = cmdGeneral "hello" $ \msg -> do + let mention = nickMention $ svNick $ msgSender msg + void $ reply msg $ "Hi there, @" <> mention <> "!" + +cmdNick :: MVar BotState -> T.Text -> Command e +cmdNick stateVar name = cmdSpecificArgs "nick" name $ \msg args -> do + preferNickVia botListing stateVar args + void $ reply msg "Is this better?" + +cmdWho :: MVar BotState -> Command e +cmdWho stateVar = cmdGeneral "who" $ \msg -> do + state <- liftIO $ readMVar stateVar + let people = state ^. botListing . lsOthersL + nicks = sort $ map svNick $ Map.elems people + void $ reply msg $ T.intercalate "\n" nicks diff --git a/stack.yaml b/stack.yaml index 8dc14ca..44f8a19 100644 --- a/stack.yaml +++ b/stack.yaml @@ -5,4 +5,4 @@ packages: extra-deps: - github: Garmelon/haboli - commit: ad393a67f67a97c4e74ce038b773c5bcead5ff10 + commit: 86b6134c00d23b0e2e80208079a1975ac0c91f9a diff --git a/stack.yaml.lock b/stack.yaml.lock index fb46f52..29aa7cf 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -5,19 +5,19 @@ packages: - completed: - size: 14086 - url: https://github.com/Garmelon/haboli/archive/ad393a67f67a97c4e74ce038b773c5bcead5ff10.tar.gz + size: 19510 + url: https://github.com/Garmelon/haboli/archive/86b6134c00d23b0e2e80208079a1975ac0c91f9a.tar.gz cabal-file: - size: 1263 - sha256: b47acf31bb12e802de480983637998761ee56d5e4a2ac0cc251c02f4388cb814 + size: 1576 + sha256: d3dea9408d036abe5aa663343b63ffd39cb5fbf14d80773248dab42c607b69b6 name: haboli version: 0.3.1.0 - sha256: eb0ca0f08fc3c3caaf730c72aaaae31f582cef8dd30b8fc461b11e8e16115166 + sha256: c137c08d5ccb6c55c6cd3f03b6d50cc073cb885050e4f5815242b11fb2da2307 pantry-tree: - size: 677 - sha256: fd8200eeae76d312f0bb5799873235c410f7274018903c936f73942441f0ac73 + size: 1193 + sha256: 7d7f3fe4fdd753fd6022c1c5f56b30333318130e40b53e0c202f3ea897ff6e79 original: - url: https://github.com/Garmelon/haboli/archive/ad393a67f67a97c4e74ce038b773c5bcead5ff10.tar.gz + url: https://github.com/Garmelon/haboli/archive/86b6134c00d23b0e2e80208079a1975ac0c91f9a.tar.gz snapshots: - completed: size: 491389