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)
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
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