module Zendesk
( runZendesk
, createUser
, getUsers
, getTickets
, getTicketFields
, ZendeskConfig(..)
, runZendeskT
) where
import Control.Applicative ((<$>), (<*>))
import Control.Exception (catches, SomeException(..), Handler(..))
import Control.Failure (Failure(..))
import Control.Monad (liftM, forM)
import Control.Monad.Reader (ReaderT (..), asks)
import Control.Monad.Error (ErrorT (..), MonadError(..), Error(..))
import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.Logger (MonadLogger(..), logDebug)
import Control.Monad.Trans (lift)
import Data.Aeson as J (eitherDecode, encode, FromJSON(..), withObject, withText, (.:), object, (.=), Value(..), Object)
import Data.ByteString.Lazy (ByteString)
import qualified Data.ByteString.Lazy as LBS (toStrict)
import Data.ByteString.Char8 as BS8 (pack, unpack)
import Data.CaseInsensitive (mk)
import Data.Default (Default(..))
import qualified Data.HashMap.Strict as M
import Data.Int (Int64)
import Data.Maybe (fromJust)
import Data.PEM (PEM(..), pemParseBS)
import Data.Text as T (pack, Text, unpack)
import Data.Text.Encoding as T (encodeUtf8)
import Data.Time.Clock (UTCTime(..))
import Data.Traversable (Traversable(..))
import Data.X509 (HashALG(..), decodeSignedCertificate)
import Data.X509.CertificateStore (CertificateStore, makeCertificateStore)
import Data.X509.Validation (ValidationChecks(..), validate, defaultHooks, defaultChecks)
import Network.Connection (TLSSettings(..))
import Network.HTTP.Client (getUri, applyBasicAuth)
import Network.HTTP.Client.TLS (mkManagerSettings)
import Network.HTTP.Conduit as HTTP ( httpLbs, parseUrl, withManagerSettings
, HttpException(..)
, Request(..), Response(..)
, responseBody, RequestBody(..), requestBody
, method, requestHeaders, checkStatus)
import Network.HTTP.Types.Status (Status(..))
import Network.TLS (Credential, Credentials(..), ClientParams(..), Shared(..), ClientHooks(..), Supported(..), defaultParamsClient, credentialLoadX509FromMemory)
import Network.TLS.Extra.Cipher (ciphersuite_strong)
import Json (deriveJSON, deriveJSON_, deriveEnumJSON)
import Data.Conduit (Source, yield)
import Zendesk.Common
import Zendesk.User
getTicketsUrl :: Monad m => ZendeskT m String
getTicketsUrl = do
baseUrl <- asks zendeskUrl
return $ baseUrl ++ "/api/v2/tickets.json"
getTicketFieldsUrl :: Monad m => ZendeskT m String
getTicketFieldsUrl = do
baseUrl <- asks zendeskUrl
return $ baseUrl ++ "/api/v2/ticket_fields.json"
data TicketField = TicketField
{ ticketFieldId :: Maybe Int
, ticketFieldUrl :: Maybe Text
, ticketFieldType :: Text
, ticketFieldTitle :: Text
, ticketFieldDescription :: Maybe Text
, ticketFieldPosition :: Maybe Int
, ticketFieldActive :: Maybe Bool
, ticketFieldRequired :: Maybe Bool
, ticketFieldCollapsedForAgents :: Maybe Bool
, ticketFieldRegexpForValidation :: Maybe Text
, ticketFieldTitleInPortal :: Maybe Text
, ticketFieldVisibleInPortal :: Maybe Bool
, ticketFieldEditableInPortal :: Maybe Bool
, ticketFieldRequiredInPortal :: Maybe Bool
, ticketFieldTag :: Maybe Text
, ticketFieldCreatedAt :: Maybe UTCTime
, ticketFieldUpdatedAt :: Maybe UTCTime
, ticketFieldRemovable :: Maybe Bool
} deriving (Show)
data TicketFieldValue = TicketFieldValue
{ ticketFieldValueId :: Int
, ticketFieldValueValue :: Maybe Text
} deriving (Show)
data Ticket = Ticket
{ ticketId :: Maybe Int
, ticketUrl :: Maybe Text
, ticketExternalId :: Maybe Text
, ticketType :: Maybe Text
, ticketSubject :: Maybe Text
, ticketDescription :: Maybe Text
, ticketPriority :: Maybe Text
, ticketStatus :: Maybe Text
, ticketRecipient :: Maybe Text
, ticketRequesterId :: Int
, ticketSubmitterId :: Maybe Int
, ticketAssigneeId :: Maybe Int
, ticketOrganizationId :: Maybe Int
, ticketGroupId :: Maybe Int
, ticketCollaboratorIds :: Maybe [Int]
, ticketForumTopicId :: Maybe Int
, ticketProblemId :: Maybe Int
, ticketHasIncidents :: Maybe Bool
, ticketDueAt :: Maybe Text
, ticketTags :: Maybe [Text]
, ticketVia :: Maybe Via
, ticketCustomFields :: Maybe [TicketFieldValue]
, ticketSatisfactionRaiting :: Maybe Object
, ticketSharingAgreementIds :: Maybe [Int]
, ticketFollowupIds :: Maybe [Int]
, ticketTicketFormId :: Maybe Int
, ticketBrandId :: Maybe Int
, ticketCreatedAt :: Maybe UTCTime
, ticketUpdatedAt :: Maybe UTCTime
} deriving (Show)
data Via = Via
{ viaChannel :: Text
, viaSource :: Maybe Object
} deriving (Show)
instance CollectionKey Ticket where
collectionKey _ = "tickets"
instance CollectionKey TicketField where
collectionKey _ = "ticket_fields"
deriveJSON ''Ticket
deriveJSON ''TicketField
deriveJSON ''TicketFieldValue
deriveJSON ''Via
getTickets :: (MonadIO m, MonadLogger m) => Source (ZendeskT m) Ticket
getTickets =
getCollection =<< (Just `liftM` (T.pack `liftM` (lift getTicketsUrl)))
getTicketFields :: (MonadIO m, MonadLogger m) => Source (ZendeskT m) TicketField
getTicketFields =
getCollection =<< (Just `liftM` (T.pack `liftM` (lift getTicketFieldsUrl)))