{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE TemplateHaskell #-} {-| Shared type declarations. -} module DMCC.Types where import DMCC.Prelude import Data.Aeson as A import Data.Aeson.TH import Data.ByteString (ByteString) import Data.CaseInsensitive import Data.Data import Data.Text as T -- | Device ID used in DMCC requests. -- -- This is based on text as stated in DMCC specification. newtype DeviceId = DeviceId (CI Text) deriving (Eq, Ord, Show) instance FromJSON DeviceId where parseJSON v = DeviceId . mk <$> parseJSON v instance ToJSON DeviceId where toJSON (DeviceId t) = toJSON $ original t newtype CallId = CallId Text deriving (Eq, Ord, Show, FromJSON, ToJSON) -- | Globally unique call ID. newtype UCID = UCID Text deriving (Eq, Ord, Show, FromJSON, ToJSON) newtype Extension = Extension Text deriving (Eq, Ord, Show, Data, Typeable, ToJSON) instance FromJSON Extension where parseJSON (A.String s) | T.length s > 30 = fail "Maximum extension length is 30 digits" | (\c -> c `elem` (['0'..'9'] <> ['*', '#'])) `T.all` s = pure $ Extension s | otherwise = fail "Extension must contain the digits 0-9, * or #" parseJSON _ = fail "Could not parse extension" newtype SwitchName = SwitchName Text deriving (Eq, Ord, Show, Data, Typeable, FromJSON, ToJSON) newtype AgentId = AgentId (SwitchName, Extension) deriving (Data, Typeable, Eq, Ord, Show, FromJSON, ToJSON) data CallDirection = In { vdn :: DeviceId } | Out deriving (Eq, Show) $(deriveJSON defaultOptions{sumEncoding = defaultTaggedObject{tagFieldName="dir"}} ''CallDirection) data Call = Call { direction :: CallDirection , ucid :: UCID , start :: UTCTime -- ^ When did call came into existence? , interlocutors :: [DeviceId] , answered :: Maybe UTCTime -- ^ When did another party answer this call? , held :: Bool , failed :: Bool } deriving Show $(deriveJSON defaultOptions ''Call) data SettableAgentState = Ready | AfterCall | NotReady | Logout deriving (Eq, Show) $(deriveJSON defaultOptions ''SettableAgentState) data AgentState = Busy | Settable SettableAgentState deriving (Eq, Show) instance ToJSON AgentState where toJSON Busy = String "Busy" toJSON (Settable s) = toJSON s instance FromJSON AgentState where parseJSON (String "Busy") = pure Busy parseJSON s@(String _) = Settable <$> parseJSON s parseJSON _ = fail "Could not parse AgentState" data ParticipationType = Active | Silent deriving (Eq, Show) $(deriveJSON defaultOptions ''ParticipationType) -- TODO This should be removed newtype LoggingOptions = LoggingOptions { syslogIdent :: ByteString } data SessionOptions = SessionOptions { statePollingDelay :: Int -- ^ How often to poll every agent for state changes (in seconds). , sessionDuration :: Int -- ^ Serves both as session duration and session cleanup delay (in -- seconds). , connectionRetryAttempts :: Int , connectionRetryDelay :: Int -- ^ In seconds. }