{-# LANGUAGE OverloadedStrings #-} module Network.Haskbot.Internal.Server (webServer) where import Control.Concurrent (forkIO) import Control.Monad.Reader (lift, liftIO, runReaderT) import qualified Data.Text.Lazy as TL import Data.Time.Clock.POSIX (getPOSIXTime) import Network.Haskbot.Internal.Environment (ActionH, ScottyH, getAppEnv) import Network.Haskbot.Internal.Incoming (sendFromQueue) import Network.Haskbot.Internal.Plugin (Plugin, isAuthorized, runPlugin, selectFrom) import Network.Haskbot.Internal.SlashCommand (SlashCom, command, fromParams) import Network.HTTP.Types.Status (badRequest400, unauthorized401) import Web.Scotty.Trans (get, post, scottyT, status, text) -- public functions webServer :: [Plugin] -> Int -> IO () webServer plugins port = do env <- getAppEnv let haskbot r = runReaderT r env forkIO $ haskbot sendFromQueue scottyT port haskbot haskbot $ routes plugins -- private functions findAndRun :: [Plugin] -> SlashCom -> ActionH () findAndRun plugins slashCom = case selectFrom plugins (command slashCom) of Just p -> if isAuthorized p slashCom then lift (runPlugin p slashCom) >> text "200 OK" else status unauthorized401 >> text "401 Unauthorized" _ -> status badRequest400 >> text "400 Bad Request" routes :: [Plugin] -> ScottyH () routes plugins = do post "/slack" $ fromParams >>= findAndRun plugins get "/ping" $ timestamp timestamp :: ActionH () timestamp = do now <- liftIO getPOSIXTime let stamp = show . truncate $ now * 1000000 text $ TL.pack stamp