werewolf-slack-0.2.0.0: app/Werewolf/Slack/Application.hs
{-|
Module : Werewolf.Slack.Application
Copyright : (c) Henry J. Wylde, 2016
License : BSD3
Maintainer : public@hjwylde.com
-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
module Werewolf.Slack.Application (
-- * Application
runApplication,
) where
import Control.Concurrent
import Control.Monad.Extra
import Control.Monad.Reader
import Control.Monad.State
import qualified Data.ByteString.Char8 as BSC
import qualified Data.ByteString.Lazy.Char8 as BSLC
import Data.Maybe
import Network.HTTP.Client hiding (queryString)
import Network.HTTP.Client.TLS
import Network.HTTP.Types
import Network.Wai hiding (Response, requestBody, responseStatus)
import Network.Wai.Handler.Warp
import Werewolf.Slack.Options
import Werewolf.Slack.Werewolf
runApplication :: (MonadIO m, MonadReader Options m) => m ()
runApplication = do
options <- ask
manager <- liftIO $ newManager tlsManagerSettings
liftIO $ run (optPort options) (application options manager)
application :: Options -> Manager -> Application
application options manager request respond
| isNothing mToken = debugRequest >> badRequest
| fromJust mToken /= optValidationToken options = debugRequest >> unauthorized
| isNothing mUser || isNothing mUserCommand = debugRequest >> badRequest
| otherwise = debugRequest >> forkIO (evalStateT (runReaderT action options) manager) >> accepted
where
debugRequest = when (optDebug options) $ print request
accepted = respond $ responseLBS status202 [] (BSLC.pack $ unwords [":wolf:", fromJust mUserCommand, ":moon:"])
badRequest = respond $ responseLBS status400 [] "bad request"
unauthorized = respond $ responseLBS status401 [] "unauthorized"
param name = join . lookup name $ queryString request
mToken = BSC.unpack <$> param "token"
mUser = BSC.unpack <$> param "user_name"
mUserCommand = BSC.unpack <$> param "text"
action = fromJust $ execute <$> mUser <*> mUserCommand