| 1 |
{-# LANGUAGE OverloadedStrings #-}
|
| 2 |
{-# LANGUAGE RecordWildCards #-}
|
| 3 |
|
| 4 |
module Main where
|
| 5 |
|
| 6 |
import Data.Aeson ((.:), (.=))
|
| 7 |
import qualified Data.Aeson as Aeson
|
| 8 |
import qualified Data.Text as Text
|
| 9 |
import qualified Network.HTTP.Types as HTTP
|
| 10 |
import qualified Network.Wai as Wai
|
| 11 |
import qualified Network.Wai.Handler.Warp as Warp
|
| 12 |
import qualified System.Environment as Env
|
| 13 |
import qualified Text.Read as Read
|
| 14 |
|
| 15 |
data WebhookRequest = WebhookRequest
|
| 16 |
{ wChannelId :: Text.Text
|
| 17 |
, wChannelName :: Text.Text
|
| 18 |
, wTeamDomain :: Text.Text
|
| 19 |
, wTeamId :: Text.Text
|
| 20 |
, wPostId :: Text.Text
|
| 21 |
, wText :: Text.Text
|
| 22 |
, wTimestamp :: Text.Text
|
| 23 |
, wToken :: Text.Text
|
| 24 |
, wTriggerWord :: Text.Text
|
| 25 |
, wUserId :: Text.Text
|
| 26 |
, wFileIds :: Text.Text
|
| 27 |
} deriving (Eq, Show)
|
| 28 |
|
| 29 |
instance Aeson.FromJSON WebhookRequest where
|
| 30 |
parseJSON = Aeson.withObject "request" $ \obj -> do
|
| 31 |
wChannelId <- obj .: ""
|
| 32 |
wChannelName <- obj .: ""
|
| 33 |
wTeamDomain <- obj .: ""
|
| 34 |
wTeamId <- obj .: ""
|
| 35 |
wPostId <- obj .: ""
|
| 36 |
wText <- obj .: ""
|
| 37 |
wTimestamp <- obj .: ""
|
| 38 |
wToken <- obj .: ""
|
| 39 |
wTriggerWord <- obj .: ""
|
| 40 |
wUserId <- obj .: ""
|
| 41 |
wFileIds <- obj .: ""
|
| 42 |
pure WebhookRequest { .. }
|
| 43 |
|
| 44 |
data WebhookResponse = WebhookResponse
|
| 45 |
{ rText :: Text.Text
|
| 46 |
} deriving (Eq, Show)
|
| 47 |
|
| 48 |
instance Aeson.ToJSON WebhookResponse where
|
| 49 |
toJSON WebhookResponse { .. } =
|
| 50 |
Aeson.object [ "text" .= rText ]
|
| 51 |
|
| 52 |
|
| 53 |
main :: IO ()
|
| 54 |
main = do
|
| 55 |
portVar <- Env.lookupEnv "PORT"
|
| 56 |
let port = case portVar of
|
| 57 |
Just x | Just p <- Read.readMaybe x -> p
|
| 58 |
_ -> 8080
|
| 59 |
Warp.run port $ \ r k ->
|
| 60 |
case (Wai.requestMethod r, Wai.pathInfo r) of
|
| 61 |
("POST", []) -> body r >>= k
|
| 62 |
_ -> k (Wai.responseLBS HTTP.status404 [] "not found")
|
| 63 |
|
| 64 |
body :: Wai.Request -> IO Wai.Response
|
| 65 |
body req = do
|
| 66 |
bodyMb <- Aeson.eitherDecode <$> Wai.lazyRequestBody req
|
| 67 |
case bodyMb of
|
| 68 |
Right val ->
|
| 69 |
let resp = WebhookResponse (wText val)
|
| 70 |
in pure (Wai.responseLBS HTTP.status200 [] (Aeson.encode resp))
|
| 71 |
Left _ ->
|
| 72 |
pure (Wai.responseLBS HTTP.status500 [] "unable to parse payload")
|