lendingclub-0.1.0.0: src/LendingClub/Internal/JSON.hs
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-unused-binds #-}
module LendingClub.Internal.JSON
( jsonGet
-- , csvGet
-- , csvGetStream
, investRequest
) where
import Blaze.ByteString.Builder (fromLazyByteString)
import Network.Http.Client
import OpenSSL
import System.IO.Streams (InputStream, write)
import Control.Monad.Reader (liftIO)
import Data.Aeson (FromJSON, ToJSON, encode)
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as C
import Data.Monoid ((<>))
import GHC.Generics
import LendingClub.Authorization
import LendingClub.Invest
import LendingClub.Money
-- | Make a GET request to LendingClub's JSON api, return the parsed JSON data
jsonGet
:: FromJSON a
=> Authorization -- ^ The authorization for the lending club user
-> ByteString -- ^ The name of the API service, relative to the API url
-> IO a -- ^ JSON response
jsonGet auth url = issueRequest auth url GET "application/json" jsonHandler (Nothing :: Maybe ())
{- TODO Redo for LendingClub
-- | Make a GET request to Prosper's CSV api, return the raw CSV data
csvGet
:: UserInfo -- ^ The user name and password for the prosper user
-> ByteString -- ^ The name of the API service, relative to the API url
-> Prosper ByteString -- ^ Raw CSV response
csvGet userInfo url = issueRequest userInfo url GET "text/csv" concatHandler []
-- | Make a GET request to Prosper's CSV api, return the raw CSV data
csvGetStream
:: UserInfo -- ^ The user name and password for the prosper user
-> ByteString -- ^ The name of the API service, relative to the API url
-> (InputStream ByteString -> IO a)
-> Prosper a -- ^ Raw CSV response
csvGetStream userInfo url handler =
issueRequest userInfo url GET "text/csv" (\_ is -> handler is) []
-}
data InvestRequest = InvestRequest
{ aid :: !Int
, orders :: ![Order]
} deriving (Generic, Show)
data Order = Order
{ loanId :: !Int
, requestedAmount :: !Money
-- , portfolioId :: !Int -- ^ Implement later
} deriving (Generic, Show)
instance ToJSON Order where
instance ToJSON InvestRequest where
investRequest
:: Authorization
-> InvestorId
-> Int -- ^ The listing id
-> Money -- ^ Amount
-> IO InvestResponse -- ^ JSON response from LendingClub
investRequest auth (InvestorId invId) listingId amount =
issueRequest auth ("accounts/" <> C.pack (show invId) <> "/orders") POST "application/json" jsonHandler $
Just InvestRequest
{ aid = invId
, orders = [Order listingId amount]
}
apiUrl :: ByteString
apiUrl = "api.lendingclub.com"
issueRequest
:: (FromJSON a, ToJSON b)
=> Authorization
-> ByteString
-> Method
-> ContentType
-> (Response -> InputStream ByteString -> IO a)
-> Maybe b
-> IO a
issueRequest (Authorization auth) url method ct handler mBody = withOpenSSL $ do
ctx <- baselineContextSSL
con <- openConnectionSSL ctx apiUrl 443
req <- buildRequest $ do
http method $ "/api/investor/v1/" <> url
setHeader "Authorization" auth
setContentType ct
sendRequest con req (setBody mBody)
resp <- receiveResponse con handler
closeConnection con
return resp
where
setBody Nothing = emptyBody
setBody (Just body) = write (Just (buildJSON body))
buildJSON = fromLazyByteString . encode