{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
module Network.CiscoSpark
(
Authorization (..)
, CiscoSparkRequest (..)
, Timestamp (..)
, ErrorCode (..)
, ErrorTitle (..)
, Errors (..)
, Person (..)
, PersonId (..)
, Email (..)
, DisplayName (..)
, NickName (..)
, FirstName (..)
, LastName (..)
, AvatarUrl (..)
, Timezone (..)
, PersonStatus (..)
, PersonType (..)
, PersonList (..)
, PersonFilter (..)
, CreatePerson (..)
, UpdatePerson (..)
, Room (..)
, RoomId (..)
, RoomTitle (..)
, RoomType (..)
, SipAddr (..)
, RoomList (..)
, RoomFilter (..)
, RoomFilterSortBy (..)
, CreateRoom (..)
, UpdateRoom (..)
, Membership (..)
, MembershipId (..)
, MembershipList (..)
, MembershipFilter (..)
, CreateMembership (..)
, UpdateMembership (..)
, Message (..)
, MessageId (..)
, MessageText (..)
, MessageHtml (..)
, MessageMarkdown (..)
, FileUrl (..)
, MessageList (..)
, MessageFilter (..)
, MentionedPeople (..)
, CreateMessage (..)
, TeamName (..)
, TeamId (..)
, Team (..)
, TeamList (..)
, CreateTeam (..)
, UpdateTeam (..)
, TeamMembership (..)
, TeamMembershipId (..)
, TeamMembershipList (..)
, TeamMembershipFilter (..)
, CreateTeamMembership (..)
, UpdateTeamMembership (..)
, Organization (..)
, OrganizationId (..)
, OrganizationDisplayName (..)
, OrganizationList (..)
, License (..)
, LicenseId (..)
, LicenseName (..)
, LicenseUnit (..)
, LicenseList (..)
, LicenseFilter (..)
, Role (..)
, RoleId (..)
, RoleName (..)
, RoleList (..)
, getDetail
, getDetailEither
, streamEntityWithFilter
, streamTeamList
, streamOrganizationList
, streamRoleList
, createEntity
, createEntityEither
, updateEntity
, updateEntityEither
, defaultMessageFilter
, defaultTeamMembershipFilter
, deleteRoom
, deleteMembership
, deleteMessage
, deleteTeam
, deleteTeamMembership
) where
import Conduit
import Data.Aeson (FromJSON, ToJSON)
import Data.ByteString (ByteString)
import Data.ByteString.Char8 as C8 (unpack)
import Data.Default (Default (def))
import Data.Maybe (catMaybes, maybeToList)
import Data.Monoid ((<>))
import Data.Text (Text)
import Data.Text.Encoding (encodeUtf8)
import Network.HTTP.Simple
import Network.URI (URIAuth (..))
import Network.CiscoSpark.Internal
import Network.CiscoSpark.Types
newtype Authorization = Authorization ByteString deriving (Eq, Show)
data CiscoSparkRequest = CiscoSparkRequest
{ ciscoSparkRequestRequest :: Request
, ciscoSparkRequestScheme :: String
, ciscoSparkRequestAuthority :: URIAuth
} deriving (Show)
ciscoSparkBaseRequest :: Request
ciscoSparkBaseRequest
= addRequestHeader "Content-Type" "application/json; charset=utf-8"
$ setRequestPort 443
$ setRequestHost "api.ciscospark.com"
$ setRequestSecure True
$ defaultRequest
instance Default CiscoSparkRequest where
def = CiscoSparkRequest ciscoSparkBaseRequest "https:" $ URIAuth "" "api.ciscospark.com" ""
addAuthorizationHeader :: Authorization -> Request -> Request
addAuthorizationHeader (Authorization auth) = addRequestHeader "Authorization" ("Bearer " <> auth)
makeCommonListReq
:: CiscoSparkRequest
-> ByteString
-> CiscoSparkRequest
makeCommonListReq base@CiscoSparkRequest { ciscoSparkRequestRequest = req } path
= base { ciscoSparkRequestRequest = setRequestPath ("/v1/" <> path) $ setRequestMethod "GET" req }
streamList :: (MonadIO m, SparkListItem i) => Authorization -> CiscoSparkRequest -> ConduitT () i m ()
streamList auth (CiscoSparkRequest req scheme uriAuth) = do
res <- httpJSON $ addAuthorizationHeader auth req
yieldMany . unwrap $ getResponseBody res
streamListLoop auth res scheme uriAuth
streamListLoop :: (MonadIO m, FromJSON a, SparkListItem i) => Authorization -> Response a -> String -> URIAuth -> ConduitT () i m ()
streamListLoop auth res scheme uriAuth
= case getNextUrl res >>= validateUrl scheme uriAuth >>= (\url -> parseRequest $ "GET " <> C8.unpack url) of
Nothing -> pure ()
Just nextReq -> do
nextRes <- httpJSON $ addAuthorizationHeader auth nextReq
yieldMany . unwrap $ getResponseBody nextRes
streamListLoop auth nextRes scheme uriAuth
streamEntityWithFilter :: (MonadIO m, SparkFilter filter, SparkListItem (ToResponse filter))
=> Authorization
-> CiscoSparkRequest
-> filter
-> ConduitT () (ToResponse filter) m ()
streamEntityWithFilter auth base param =
streamList auth $ setQeuryString $ makeCommonListReq base (apiPath param)
where
setQeuryString comm@CiscoSparkRequest { ciscoSparkRequestRequest = req }
= comm { ciscoSparkRequestRequest = setRequestQueryString (toFilterList param) req }
streamTeamList :: MonadIO m => Authorization -> CiscoSparkRequest -> ConduitT () Team m ()
streamTeamList auth base = streamList auth $ makeCommonListReq base teamsPath
streamOrganizationList :: MonadIO m => Authorization -> CiscoSparkRequest -> ConduitT () Organization m ()
streamOrganizationList auth base = streamList auth $ makeCommonListReq base organizationsPath
streamRoleList :: MonadIO m => Authorization -> CiscoSparkRequest -> ConduitT () Role m ()
streamRoleList auth base = streamList auth $ makeCommonListReq base rolesPath
makeCommonDetailReq
:: CiscoSparkRequest
-> Authorization
-> ByteString
-> Text
-> Request
makeCommonDetailReq (CiscoSparkRequest base _ _) auth path idStr
= setRequestPath ("/v1/" <> path <> "/" <> encodeUtf8 idStr)
$ setRequestMethod "GET"
$ addAuthorizationHeader auth
$ base
getDetail :: (MonadIO m, SparkDetail key)
=> Authorization
-> CiscoSparkRequest
-> key
-> m (Response (ToResponse key))
getDetail auth base entityId = httpJSON $ makeCommonDetailReq base auth (apiPath entityId) (toIdStr entityId)
getDetailEither :: (MonadIO m, SparkDetail key)
=> Authorization
-> CiscoSparkRequest
-> key
-> m (Response (Either JSONException (ToResponse key)))
getDetailEither auth base entityId = httpJSONEither $ makeCommonDetailReq base auth (apiPath entityId) (toIdStr entityId)
makeCommonCreateReq :: ToJSON a => CiscoSparkRequest -> Authorization -> ByteString -> a -> Request
makeCommonCreateReq (CiscoSparkRequest base _ _) auth path body
= setRequestBodyJSON body
$ setRequestPath ("/v1/" <> path)
$ setRequestMethod "POST"
$ addAuthorizationHeader auth
$ base
createEntity :: (MonadIO m, SparkCreate createParams)
=> Authorization
-> CiscoSparkRequest
-> createParams
-> m (Response (ToResponse createParams))
createEntity auth base param = httpJSON $ makeCommonCreateReq base auth (apiPath param) param
createEntityEither :: (MonadIO m, SparkCreate createParams)
=> Authorization
-> CiscoSparkRequest
-> createParams
-> m (Response (Either JSONException (ToResponse createParams)))
createEntityEither auth base param = httpJSONEither $ makeCommonCreateReq base auth (apiPath param) param
makeCommonUpdateReq :: ToJSON a => CiscoSparkRequest -> Authorization -> ByteString -> a -> Request
makeCommonUpdateReq (CiscoSparkRequest base _ _) auth path body
= setRequestBodyJSON body
$ setRequestPath ("/v1/" <> path)
$ setRequestMethod "PUT"
$ addAuthorizationHeader auth
$ base
updateEntity :: (MonadIO m, SparkUpdate updateParams)
=> Authorization
-> CiscoSparkRequest
-> updateParams
-> m (Response (ToResponse updateParams))
updateEntity auth base param = httpJSON $ makeCommonUpdateReq base auth (apiPath param) param
updateEntityEither :: (MonadIO m, SparkUpdate updateParams)
=> Authorization
-> CiscoSparkRequest
-> updateParams
-> m (Response (Either JSONException (ToResponse updateParams)))
updateEntityEither auth base param = httpJSONEither $ makeCommonUpdateReq base auth (apiPath param) param
makeCommonDeleteReq
:: Authorization
-> Request
-> ByteString
-> Text
-> Request
makeCommonDeleteReq auth base path idStr
= setRequestPath ("/v1/" <> path <> "/" <> encodeUtf8 idStr)
$ setRequestMethod "DELETE"
$ addAuthorizationHeader auth
$ base
deleteEntity :: (MonadIO m, SparkDetail key)
=> Authorization
-> CiscoSparkRequest
-> key
-> m (Response ())
deleteEntity auth (CiscoSparkRequest base _ _) entityId
= httpNoBody $ makeCommonDeleteReq auth base (apiPath entityId) (toIdStr entityId)
deleteRoom :: MonadIO m
=> Authorization
-> CiscoSparkRequest
-> RoomId
-> m (Response ())
deleteRoom = deleteEntity
deleteMembership :: MonadIO m
=> Authorization
-> CiscoSparkRequest
-> MembershipId
-> m (Response ())
deleteMembership = deleteEntity
deleteMessage :: MonadIO m
=> Authorization
-> CiscoSparkRequest
-> MessageId
-> m (Response ())
deleteMessage = deleteEntity
deleteTeam :: MonadIO m
=> Authorization
-> CiscoSparkRequest
-> TeamId
-> m (Response ())
deleteTeam = deleteEntity
deleteTeamMembership :: MonadIO m
=> Authorization
-> CiscoSparkRequest
-> TeamMembershipId
-> m (Response ())
deleteTeamMembership = deleteEntity