{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE TypeOperators #-}

----------------------------------------------------------------------
-- |
-- Module: Web.Slack
-- Description: Provides Slack's Web API functions.
-- *Since 0.4.0.0*: The API functions is now more intuitive for newbies
-- than before. If you need compatiblity with the previous version, use
-- 'Web.Slack.Classy' instead.
--
----------------------------------------------------------------------

module Web.Slack
  ( SlackConfig(..)
  , mkSlackConfig
  , apiTest
  , authTest
  , chatPostMessage
  , conversationsList
  , conversationsHistory
  , conversationsHistoryAll
  , conversationsReplies
  , repliesFetchAll
  , getUserDesc
  , usersList
  , userLookupByEmail
  , authenticateReq
  , Response
  , LoadPage
  )
  where

-- aeson
import Data.Aeson

-- base
import Control.Arrow ((&&&))
import Data.Maybe
import Data.Proxy (Proxy(..))

-- containers
import qualified Data.Map as Map

-- http-client
import Network.HTTP.Client (Manager, newManager)

-- http-client-tls
import Network.HTTP.Client.TLS (tlsManagerSettings)

-- mtl
import Control.Monad.Reader

-- servant
import Servant.API hiding (addHeader)

-- servant-client
import Servant.Client hiding (Response, baseUrl)

#if MIN_VERSION_servant(0,16,0)
import Servant.Client.Core (AuthClientData, AuthenticatedRequest, Request, mkAuthenticatedRequest, addHeader)
#else
import Servant.Client.Core.Internal.Auth
import Servant.Client.Core (Request, addHeader)
#endif

-- slack-web
import qualified Web.Slack.Api as Api
import qualified Web.Slack.Auth as Auth
import qualified Web.Slack.Conversation as Conversation
import qualified Web.Slack.Chat as Chat
import qualified Web.Slack.Common as Common
import qualified Web.Slack.User as User
import           Web.Slack.Pager

-- text
import Data.Text (Text)

#if !MIN_VERSION_servant(0,13,0)
mkClientEnv :: Manager -> BaseUrl -> ClientEnv
mkClientEnv = ClientEnv
#endif


data SlackConfig
  = SlackConfig
  { SlackConfig -> Manager
slackConfigManager :: Manager
  , SlackConfig -> Text
slackConfigToken :: Text
  }


-- contains errors that can be returned by the slack API.
-- constrast with 'SlackClientError' which additionally
-- contains errors which occured during the network communication.
data ResponseSlackError = ResponseSlackError Text
  deriving (ResponseSlackError -> ResponseSlackError -> Bool
(ResponseSlackError -> ResponseSlackError -> Bool)
-> (ResponseSlackError -> ResponseSlackError -> Bool)
-> Eq ResponseSlackError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ResponseSlackError -> ResponseSlackError -> Bool
$c/= :: ResponseSlackError -> ResponseSlackError -> Bool
== :: ResponseSlackError -> ResponseSlackError -> Bool
$c== :: ResponseSlackError -> ResponseSlackError -> Bool
Eq, Int -> ResponseSlackError -> ShowS
[ResponseSlackError] -> ShowS
ResponseSlackError -> String
(Int -> ResponseSlackError -> ShowS)
-> (ResponseSlackError -> String)
-> ([ResponseSlackError] -> ShowS)
-> Show ResponseSlackError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ResponseSlackError] -> ShowS
$cshowList :: [ResponseSlackError] -> ShowS
show :: ResponseSlackError -> String
$cshow :: ResponseSlackError -> String
showsPrec :: Int -> ResponseSlackError -> ShowS
$cshowsPrec :: Int -> ResponseSlackError -> ShowS
Show)


-- |
-- Internal type!
--
newtype ResponseJSON a = ResponseJSON (Either ResponseSlackError a)

instance FromJSON a => FromJSON (ResponseJSON a) where
    parseJSON :: Value -> Parser (ResponseJSON a)
parseJSON = String
-> (Object -> Parser (ResponseJSON a))
-> Value
-> Parser (ResponseJSON a)
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"Response" ((Object -> Parser (ResponseJSON a))
 -> Value -> Parser (ResponseJSON a))
-> (Object -> Parser (ResponseJSON a))
-> Value
-> Parser (ResponseJSON a)
forall a b. (a -> b) -> a -> b
$ \Object
o -> do
        Bool
ok <- Object
o Object -> Text -> Parser Bool
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"ok"
        Either ResponseSlackError a -> ResponseJSON a
forall a. Either ResponseSlackError a -> ResponseJSON a
ResponseJSON (Either ResponseSlackError a -> ResponseJSON a)
-> Parser (Either ResponseSlackError a) -> Parser (ResponseJSON a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> if Bool
ok
           then a -> Either ResponseSlackError a
forall a b. b -> Either a b
Right (a -> Either ResponseSlackError a)
-> Parser a -> Parser (Either ResponseSlackError a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser a
forall a. FromJSON a => Value -> Parser a
parseJSON (Object -> Value
Object Object
o)
           else ResponseSlackError -> Either ResponseSlackError a
forall a b. a -> Either a b
Left (ResponseSlackError -> Either ResponseSlackError a)
-> (Text -> ResponseSlackError)
-> Text
-> Either ResponseSlackError a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ResponseSlackError
ResponseSlackError (Text -> Either ResponseSlackError a)
-> Parser Text -> Parser (Either ResponseSlackError a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"error"


-- |
--
--
type Api =
    "api.test"
      :> ReqBody '[FormUrlEncoded] Api.TestReq
      :> Post '[JSON] (ResponseJSON Api.TestRsp)
  :<|>
    "auth.test"
      :> AuthProtect "token"
      :> Post '[JSON] (ResponseJSON Auth.TestRsp)
  :<|>
    "conversations.list"
      :> AuthProtect "token"
      :> ReqBody '[FormUrlEncoded] Conversation.ListReq
      :> Post '[JSON] (ResponseJSON Conversation.ListRsp)
  :<|>
    "conversations.history"
      :> AuthProtect "token"
      :> ReqBody '[FormUrlEncoded] Conversation.HistoryReq
      :> Post '[JSON] (ResponseJSON Conversation.HistoryRsp)
  :<|>
    "conversations.replies"
      :> AuthProtect "token"
      :> ReqBody '[FormUrlEncoded] Conversation.RepliesReq
      :> Post '[JSON] (ResponseJSON Conversation.HistoryRsp)
  :<|>
    "chat.postMessage"
      :> AuthProtect "token"
      :> ReqBody '[FormUrlEncoded] Chat.PostMsgReq
      :> Post '[JSON] (ResponseJSON Chat.PostMsgRsp)
  :<|>
    "users.list"
      :> AuthProtect "token"
      :> Post '[JSON] (ResponseJSON User.ListRsp)
  :<|>
    "users.lookupByEmail"
      :> AuthProtect "token"
      :> ReqBody '[FormUrlEncoded] User.Email
      :> Post '[JSON] (ResponseJSON User.UserRsp)


-- |
--
-- Check API calling code.
--
-- <https://api.slack.com/methods/api.test>

apiTest
  :: Manager
  -> Api.TestReq
  -> IO (Response Api.TestRsp)
apiTest :: Manager -> TestReq -> IO (Response TestRsp)
apiTest Manager
mgr TestReq
req = ClientM (ResponseJSON TestRsp) -> Manager -> IO (Response TestRsp)
forall a. ClientM (ResponseJSON a) -> Manager -> IO (Response a)
run (TestReq -> ClientM (ResponseJSON TestRsp)
apiTest_ TestReq
req) Manager
mgr

apiTest_
  :: Api.TestReq
  -> ClientM (ResponseJSON Api.TestRsp)


-- |
--
-- Check authentication and identity.
--
-- <https://api.slack.com/methods/auth.test>

authTest
  :: SlackConfig
  -> IO (Response Auth.TestRsp)
authTest :: SlackConfig -> IO (Response TestRsp)
authTest = do
  AuthenticatedRequest (AuthProtect "token")
authR <- SlackConfig -> AuthenticatedRequest (AuthProtect "token")
mkSlackAuthenticateReq
  ClientM (ResponseJSON TestRsp) -> Manager -> IO (Response TestRsp)
forall a. ClientM (ResponseJSON a) -> Manager -> IO (Response a)
run (AuthenticatedRequest (AuthProtect "token")
-> ClientM (ResponseJSON TestRsp)
authTest_ AuthenticatedRequest (AuthProtect "token")
authR) (Manager -> IO (Response TestRsp))
-> (SlackConfig -> Manager) -> SlackConfig -> IO (Response TestRsp)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SlackConfig -> Manager
slackConfigManager

authTest_
  :: AuthenticatedRequest (AuthProtect "token")
  -> ClientM (ResponseJSON Auth.TestRsp)

-- |
--
-- Retrieve conversations list.
--
-- <https://api.slack.com/methods/conversations.list>

conversationsList
  :: SlackConfig
  -> Conversation.ListReq
  -> IO (Response Conversation.ListRsp)
conversationsList :: SlackConfig -> ListReq -> IO (Response ListRsp)
conversationsList = (ListReq -> SlackConfig -> IO (Response ListRsp))
-> SlackConfig -> ListReq -> IO (Response ListRsp)
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((ListReq -> SlackConfig -> IO (Response ListRsp))
 -> SlackConfig -> ListReq -> IO (Response ListRsp))
-> (ListReq -> SlackConfig -> IO (Response ListRsp))
-> SlackConfig
-> ListReq
-> IO (Response ListRsp)
forall a b. (a -> b) -> a -> b
$ \ListReq
listReq -> do
  AuthenticatedRequest (AuthProtect "token")
authR <- SlackConfig -> AuthenticatedRequest (AuthProtect "token")
mkSlackAuthenticateReq
  ClientM (ResponseJSON ListRsp) -> Manager -> IO (Response ListRsp)
forall a. ClientM (ResponseJSON a) -> Manager -> IO (Response a)
run (AuthenticatedRequest (AuthProtect "token")
-> ListReq -> ClientM (ResponseJSON ListRsp)
conversationsList_ AuthenticatedRequest (AuthProtect "token")
authR ListReq
listReq) (Manager -> IO (Response ListRsp))
-> (SlackConfig -> Manager) -> SlackConfig -> IO (Response ListRsp)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SlackConfig -> Manager
slackConfigManager

conversationsList_
  :: AuthenticatedRequest (AuthProtect "token")
  -> Conversation.ListReq
  -> ClientM (ResponseJSON Conversation.ListRsp)


-- |
--
-- Retrieve ceonversation history.
-- Consider using 'historyFetchAll' in combination with this function.
--
-- <https://api.slack.com/methods/conversations.history>

conversationsHistory
  :: SlackConfig
  -> Conversation.HistoryReq
  -> IO (Response Conversation.HistoryRsp)
conversationsHistory :: SlackConfig -> HistoryReq -> IO (Response HistoryRsp)
conversationsHistory = (HistoryReq -> SlackConfig -> IO (Response HistoryRsp))
-> SlackConfig -> HistoryReq -> IO (Response HistoryRsp)
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((HistoryReq -> SlackConfig -> IO (Response HistoryRsp))
 -> SlackConfig -> HistoryReq -> IO (Response HistoryRsp))
-> (HistoryReq -> SlackConfig -> IO (Response HistoryRsp))
-> SlackConfig
-> HistoryReq
-> IO (Response HistoryRsp)
forall a b. (a -> b) -> a -> b
$ \HistoryReq
histReq -> do
  AuthenticatedRequest (AuthProtect "token")
authR <- SlackConfig -> AuthenticatedRequest (AuthProtect "token")
mkSlackAuthenticateReq
  ClientM (ResponseJSON HistoryRsp)
-> Manager -> IO (Response HistoryRsp)
forall a. ClientM (ResponseJSON a) -> Manager -> IO (Response a)
run (AuthenticatedRequest (AuthProtect "token")
-> HistoryReq -> ClientM (ResponseJSON HistoryRsp)
conversationsHistory_ AuthenticatedRequest (AuthProtect "token")
authR HistoryReq
histReq) (Manager -> IO (Response HistoryRsp))
-> (SlackConfig -> Manager)
-> SlackConfig
-> IO (Response HistoryRsp)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SlackConfig -> Manager
slackConfigManager

conversationsHistory_
  :: AuthenticatedRequest (AuthProtect "token")
  -> Conversation.HistoryReq
  -> ClientM (ResponseJSON Conversation.HistoryRsp)


-- |
--
-- Retrieve replies of a conversation.
-- Consider using 'repliesFetchAll' if you want to get entire replies
-- of a conversation.
--
-- <https://api.slack.com/methods/conversations.replies>

conversationsReplies
  :: SlackConfig
  -> Conversation.RepliesReq
  -> IO (Response Conversation.HistoryRsp)
conversationsReplies :: SlackConfig -> RepliesReq -> IO (Response HistoryRsp)
conversationsReplies = (RepliesReq -> SlackConfig -> IO (Response HistoryRsp))
-> SlackConfig -> RepliesReq -> IO (Response HistoryRsp)
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((RepliesReq -> SlackConfig -> IO (Response HistoryRsp))
 -> SlackConfig -> RepliesReq -> IO (Response HistoryRsp))
-> (RepliesReq -> SlackConfig -> IO (Response HistoryRsp))
-> SlackConfig
-> RepliesReq
-> IO (Response HistoryRsp)
forall a b. (a -> b) -> a -> b
$ \RepliesReq
repliesReq -> do
  AuthenticatedRequest (AuthProtect "token")
authR <- SlackConfig -> AuthenticatedRequest (AuthProtect "token")
mkSlackAuthenticateReq
  ClientM (ResponseJSON HistoryRsp)
-> Manager -> IO (Response HistoryRsp)
forall a. ClientM (ResponseJSON a) -> Manager -> IO (Response a)
run (AuthenticatedRequest (AuthProtect "token")
-> RepliesReq -> ClientM (ResponseJSON HistoryRsp)
conversationsReplies_ AuthenticatedRequest (AuthProtect "token")
authR RepliesReq
repliesReq) (Manager -> IO (Response HistoryRsp))
-> (SlackConfig -> Manager)
-> SlackConfig
-> IO (Response HistoryRsp)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SlackConfig -> Manager
slackConfigManager

conversationsReplies_
  :: AuthenticatedRequest (AuthProtect "token")
  -> Conversation.RepliesReq
  -> ClientM (ResponseJSON Conversation.HistoryRsp)


-- |
--
-- Send a message to a channel.
--
-- <https://api.slack.com/methods/chat.postMessage>

chatPostMessage
  :: SlackConfig
  -> Chat.PostMsgReq
  -> IO (Response Chat.PostMsgRsp)
chatPostMessage :: SlackConfig -> PostMsgReq -> IO (Response PostMsgRsp)
chatPostMessage = (PostMsgReq -> SlackConfig -> IO (Response PostMsgRsp))
-> SlackConfig -> PostMsgReq -> IO (Response PostMsgRsp)
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((PostMsgReq -> SlackConfig -> IO (Response PostMsgRsp))
 -> SlackConfig -> PostMsgReq -> IO (Response PostMsgRsp))
-> (PostMsgReq -> SlackConfig -> IO (Response PostMsgRsp))
-> SlackConfig
-> PostMsgReq
-> IO (Response PostMsgRsp)
forall a b. (a -> b) -> a -> b
$ \PostMsgReq
postReq -> do
  AuthenticatedRequest (AuthProtect "token")
authR <- SlackConfig -> AuthenticatedRequest (AuthProtect "token")
mkSlackAuthenticateReq
  ClientM (ResponseJSON PostMsgRsp)
-> Manager -> IO (Response PostMsgRsp)
forall a. ClientM (ResponseJSON a) -> Manager -> IO (Response a)
run (AuthenticatedRequest (AuthProtect "token")
-> PostMsgReq -> ClientM (ResponseJSON PostMsgRsp)
chatPostMessage_ AuthenticatedRequest (AuthProtect "token")
authR PostMsgReq
postReq) (Manager -> IO (Response PostMsgRsp))
-> (SlackConfig -> Manager)
-> SlackConfig
-> IO (Response PostMsgRsp)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SlackConfig -> Manager
slackConfigManager

chatPostMessage_
  :: AuthenticatedRequest (AuthProtect "token")
  -> Chat.PostMsgReq
  -> ClientM (ResponseJSON Chat.PostMsgRsp)


-- |
--
-- This method returns a list of all users in the team.
-- This includes deleted/deactivated users.
--
-- <https://api.slack.com/methods/users.list>

usersList
  :: SlackConfig
  -> IO (Response User.ListRsp)
usersList :: SlackConfig -> IO (Response ListRsp)
usersList = do
  AuthenticatedRequest (AuthProtect "token")
authR <- SlackConfig -> AuthenticatedRequest (AuthProtect "token")
mkSlackAuthenticateReq
  ClientM (ResponseJSON ListRsp) -> Manager -> IO (Response ListRsp)
forall a. ClientM (ResponseJSON a) -> Manager -> IO (Response a)
run (AuthenticatedRequest (AuthProtect "token")
-> ClientM (ResponseJSON ListRsp)
usersList_ AuthenticatedRequest (AuthProtect "token")
authR) (Manager -> IO (Response ListRsp))
-> (SlackConfig -> Manager) -> SlackConfig -> IO (Response ListRsp)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SlackConfig -> Manager
slackConfigManager

usersList_
  :: AuthenticatedRequest (AuthProtect "token")
  -> ClientM (ResponseJSON User.ListRsp)

-- |
--
-- This method returns a list of all users in the team.
-- This includes deleted/deactivated users.
--
-- <https://api.slack.com/methods/users.lookupByEmail>

userLookupByEmail
  :: SlackConfig
  -> User.Email
  -> IO (Response User.UserRsp)
userLookupByEmail :: SlackConfig -> Email -> IO (Response UserRsp)
userLookupByEmail = (Email -> SlackConfig -> IO (Response UserRsp))
-> SlackConfig -> Email -> IO (Response UserRsp)
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((Email -> SlackConfig -> IO (Response UserRsp))
 -> SlackConfig -> Email -> IO (Response UserRsp))
-> (Email -> SlackConfig -> IO (Response UserRsp))
-> SlackConfig
-> Email
-> IO (Response UserRsp)
forall a b. (a -> b) -> a -> b
$ \Email
email -> do
  AuthenticatedRequest (AuthProtect "token")
authR <- SlackConfig -> AuthenticatedRequest (AuthProtect "token")
mkSlackAuthenticateReq
  ClientM (ResponseJSON UserRsp) -> Manager -> IO (Response UserRsp)
forall a. ClientM (ResponseJSON a) -> Manager -> IO (Response a)
run (AuthenticatedRequest (AuthProtect "token")
-> Email -> ClientM (ResponseJSON UserRsp)
userLookupByEmail_ AuthenticatedRequest (AuthProtect "token")
authR Email
email) (Manager -> IO (Response UserRsp))
-> (SlackConfig -> Manager) -> SlackConfig -> IO (Response UserRsp)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SlackConfig -> Manager
slackConfigManager

userLookupByEmail_
  :: AuthenticatedRequest (AuthProtect "token")
  -> User.Email
  -> ClientM (ResponseJSON User.UserRsp)


-- | Returns a function to get a username from a 'Common.UserId'.
-- Comes in handy to use 'Web.Slack.MessageParser.messageToHtml'
getUserDesc
  :: (Common.UserId -> Text)
  -- ^ A function to give a default username in case the username is unknown
  -> User.ListRsp
  -- ^ List of users as known by the slack server. See 'usersList'.
  -> (Common.UserId -> Text)
  -- ^ A function from 'Common.UserId' to username.
getUserDesc :: (UserId -> Text) -> ListRsp -> UserId -> Text
getUserDesc UserId -> Text
unknownUserFn ListRsp
users =
  let userMap :: Map UserId Text
userMap = [(UserId, Text)] -> Map UserId Text
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([(UserId, Text)] -> Map UserId Text)
-> [(UserId, Text)] -> Map UserId Text
forall a b. (a -> b) -> a -> b
$ (User -> UserId
User.userId (User -> UserId) -> (User -> Text) -> User -> (UserId, Text)
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& User -> Text
User.userName) (User -> (UserId, Text)) -> [User] -> [(UserId, Text)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ListRsp -> [User]
User.listRspMembers ListRsp
users
  in
    \UserId
userId -> Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe (UserId -> Text
unknownUserFn UserId
userId) (Maybe Text -> Text) -> Maybe Text -> Text
forall a b. (a -> b) -> a -> b
$ UserId -> Map UserId Text -> Maybe Text
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup UserId
userId Map UserId Text
userMap


-- | Returns an action to send a request to get the history of a conversation.
--
--   To fetch all messages in the conversation, run the returned 'LoadPage' action
--   repeatedly until it returns an empty list.
conversationsHistoryAll
  :: SlackConfig
  -> Conversation.HistoryReq
  -- ^ The first request to send. _NOTE_: 'Conversation.historyReqCursor' is silently ignored.
  -> IO (LoadPage IO Common.Message)
  -- ^ An action which returns a new page of messages every time called.
  --   If there are no pages anymore, it returns an empty list.
conversationsHistoryAll :: SlackConfig -> HistoryReq -> IO (LoadPage IO Message)
conversationsHistoryAll = (HistoryReq -> IO (Response HistoryRsp))
-> HistoryReq -> IO (LoadPage IO Message)
forall (m :: * -> *).
MonadIO m =>
(HistoryReq -> m (Response HistoryRsp))
-> HistoryReq -> m (LoadPage m Message)
conversationsHistoryAllBy ((HistoryReq -> IO (Response HistoryRsp))
 -> HistoryReq -> IO (LoadPage IO Message))
-> (SlackConfig -> HistoryReq -> IO (Response HistoryRsp))
-> SlackConfig
-> HistoryReq
-> IO (LoadPage IO Message)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SlackConfig -> HistoryReq -> IO (Response HistoryRsp)
conversationsHistory


-- | Returns an action to send a request to get the replies of a conversation.
--
--   To fetch all replies in the conversation, run the returned 'LoadPage' action
--   repeatedly until it returns an empty list.
--
--   *NOTE*: The conversations.replies endpoint always returns the first message
--           of the thread. So every page returned by the 'LoadPage' action includes
--           the first message of the thread. You should drop it if you want to
--           collect messages in a thread without duplicates.
repliesFetchAll
  :: SlackConfig
  ->  Conversation.RepliesReq
  -- ^ The first request to send. _NOTE_: 'Conversation.repliesReqCursor' is silently ignored.
  -> IO (LoadPage IO Common.Message)
  -- ^ An action which returns a new page of messages every time called.
  --   If there are no pages anymore, it returns an empty list.
repliesFetchAll :: SlackConfig -> RepliesReq -> IO (LoadPage IO Message)
repliesFetchAll = (RepliesReq -> IO (Response HistoryRsp))
-> RepliesReq -> IO (LoadPage IO Message)
forall (m :: * -> *).
MonadIO m =>
(RepliesReq -> m (Response HistoryRsp))
-> RepliesReq -> m (LoadPage m Message)
repliesFetchAllBy ((RepliesReq -> IO (Response HistoryRsp))
 -> RepliesReq -> IO (LoadPage IO Message))
-> (SlackConfig -> RepliesReq -> IO (Response HistoryRsp))
-> SlackConfig
-> RepliesReq
-> IO (LoadPage IO Message)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SlackConfig -> RepliesReq -> IO (Response HistoryRsp)
conversationsReplies


TestReq -> ClientM (ResponseJSON TestRsp)
apiTest_
  :<|> AuthenticatedRequest (AuthProtect "token")
-> ClientM (ResponseJSON TestRsp)
authTest_
  :<|> AuthenticatedRequest (AuthProtect "token")
-> ListReq -> ClientM (ResponseJSON ListRsp)
conversationsList_
  :<|> AuthenticatedRequest (AuthProtect "token")
-> HistoryReq -> ClientM (ResponseJSON HistoryRsp)
conversationsHistory_
  :<|> AuthenticatedRequest (AuthProtect "token")
-> RepliesReq -> ClientM (ResponseJSON HistoryRsp)
conversationsReplies_
  :<|> AuthenticatedRequest (AuthProtect "token")
-> PostMsgReq -> ClientM (ResponseJSON PostMsgRsp)
chatPostMessage_
  :<|> AuthenticatedRequest (AuthProtect "token")
-> ClientM (ResponseJSON ListRsp)
usersList_
  :<|> AuthenticatedRequest (AuthProtect "token")
-> Email -> ClientM (ResponseJSON UserRsp)
userLookupByEmail_
  =
  Proxy Api -> Client ClientM Api
forall api.
HasClient ClientM api =>
Proxy api -> Client ClientM api
client (Proxy Api
forall k (t :: k). Proxy t
Proxy :: Proxy Api)


-- |
--
--

type instance AuthClientData (AuthProtect "token") =
  Text


-- |
--
--
authenticateReq
  :: Text
  -> Request
  -> Request
authenticateReq :: Text -> Request -> Request
authenticateReq Text
token =
  HeaderName -> Text -> Request -> Request
forall a. ToHttpApiData a => HeaderName -> a -> Request -> Request
addHeader HeaderName
"Authorization" (Text -> Request -> Request) -> Text -> Request -> Request
forall a b. (a -> b) -> a -> b
$ Text
"Bearer " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
token


-- |
--
--

run
  :: ClientM (ResponseJSON a)
  -> Manager
  -> IO (Response a)
run :: ClientM (ResponseJSON a) -> Manager -> IO (Response a)
run ClientM (ResponseJSON a)
clientAction Manager
mgr = do
  let baseUrl :: BaseUrl
baseUrl = Scheme -> String -> Int -> String -> BaseUrl
BaseUrl Scheme
Https String
"slack.com" Int
443 String
"/api"
  Either ClientError (ResponseJSON a) -> Response a
forall a. Either ClientError (ResponseJSON a) -> Response a
unnestErrors (Either ClientError (ResponseJSON a) -> Response a)
-> IO (Either ClientError (ResponseJSON a)) -> IO (Response a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO (Either ClientError (ResponseJSON a))
-> IO (Either ClientError (ResponseJSON a))
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (ClientM (ResponseJSON a)
-> ClientEnv -> IO (Either ClientError (ResponseJSON a))
forall a. ClientM a -> ClientEnv -> IO (Either ClientError a)
runClientM ClientM (ResponseJSON a)
clientAction (ClientEnv -> IO (Either ClientError (ResponseJSON a)))
-> ClientEnv -> IO (Either ClientError (ResponseJSON a))
forall a b. (a -> b) -> a -> b
$ Manager -> BaseUrl -> ClientEnv
mkClientEnv Manager
mgr BaseUrl
baseUrl)


mkSlackAuthenticateReq :: SlackConfig -> AuthenticatedRequest (AuthProtect "token")
mkSlackAuthenticateReq :: SlackConfig -> AuthenticatedRequest (AuthProtect "token")
mkSlackAuthenticateReq = (AuthClientData (AuthProtect "token")
-> (AuthClientData (AuthProtect "token") -> Request -> Request)
-> AuthenticatedRequest (AuthProtect "token")
forall a.
AuthClientData a
-> (AuthClientData a -> Request -> Request)
-> AuthenticatedRequest a
`mkAuthenticatedRequest` Text -> Request -> Request
AuthClientData (AuthProtect "token") -> Request -> Request
authenticateReq) (Text -> AuthenticatedRequest (AuthProtect "token"))
-> (SlackConfig -> Text)
-> SlackConfig
-> AuthenticatedRequest (AuthProtect "token")
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SlackConfig -> Text
slackConfigToken


unnestErrors :: Either ClientError (ResponseJSON a) -> Response a
unnestErrors :: Either ClientError (ResponseJSON a) -> Response a
unnestErrors (Right (ResponseJSON (Right a
a))) = a -> Response a
forall a b. b -> Either a b
Right a
a
unnestErrors (Right (ResponseJSON (Left (ResponseSlackError Text
serv))))
    = SlackClientError -> Response a
forall a b. a -> Either a b
Left (Text -> SlackClientError
Common.SlackError Text
serv)
unnestErrors (Left ClientError
slackErr) = SlackClientError -> Response a
forall a b. a -> Either a b
Left (ClientError -> SlackClientError
Common.ServantError ClientError
slackErr)


-- | Prepare a SlackConfig from a slack token.
-- You can then call the other functions providing this in a reader context.
--
mkSlackConfig :: Text -> IO SlackConfig
mkSlackConfig :: Text -> IO SlackConfig
mkSlackConfig Text
token = Manager -> Text -> SlackConfig
SlackConfig (Manager -> Text -> SlackConfig)
-> IO Manager -> IO (Text -> SlackConfig)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ManagerSettings -> IO Manager
newManager ManagerSettings
tlsManagerSettings IO (Text -> SlackConfig) -> IO Text -> IO SlackConfig
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> IO Text
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
token