module Airtable.Query
( module Airtable.Table
, AirtableOptions
, getTable
) where
import Airtable.Table
import Network.Wreq
import Control.Lens ((^.), (.~), (&))
import Data.Aeson (FromJSON, ToJSON, eitherDecode)
import Data.Monoid
import qualified Data.ByteString.Char8 as BC
data AirtableOptions = AirtableOptions {
apiKey :: String
, appId :: String
, apiVersion :: Int
}
defaultOptions :: AirtableOptions
defaultOptions = AirtableOptions {
apiKey = ""
, appId = ""
, apiVersion = 0
}
base_url :: String
base_url = "https://api.airtable.com/"
getTable :: (FromJSON a) => AirtableOptions -> TableName -> IO (Table a)
getTable opts tname = getTableFromUrl net_otps url
where
net_otps = defaults & header "Authorization" .~ ["Bearer " <> BC.pack (apiKey opts)]
url = base_url
<> "v"
<> show (apiVersion opts)
<> "/"
<> appId opts
<> "/"
<> tname
getTableFromUrl :: (FromJSON a) => Options -> String -> IO (Table a)
getTableFromUrl opts url = do
resp <- getWith opts url
getMore (fromResp resp)
where
getMore tbl = case tableOffset tbl of
Just offset -> do
resp <- getWith (opts & param "offset" .~ [offset]) url
getMore $ fromResp resp <> tbl
Nothing ->
pure tbl
fromResp r = decoder $ r ^. responseBody
where
decoder b = case eitherDecode b of
Left e -> error $ e <> "\nSource string: " <> show b
Right r -> r