{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
module Web.Twitter.Conduit.Stream
(
Userstream
, userstream
, StatusesFilter
, FilterParameter (..)
, statusesFilter
, statusesFilterByFollow
, statusesFilterByTrack
, stream
, stream'
) where
import Web.Twitter.Conduit.Types
import Web.Twitter.Conduit.Base
import Web.Twitter.Types
import Web.Twitter.Conduit.Request
import Web.Twitter.Conduit.Request.Internal
import Web.Twitter.Conduit.Response
import Control.Monad.Catch
import Control.Monad.IO.Class
import Control.Monad.Trans.Resource (MonadResource)
import Data.Aeson
import qualified Data.ByteString.Char8 as S8
import Data.Char
import qualified Data.Conduit as C
import qualified Data.Conduit.List as CL
import qualified Data.List as L
import qualified Data.Text as T
import qualified Network.HTTP.Conduit as HTTP
stream ::
( MonadResource m
, FromJSON responseType
, MonadThrow m
)
=> TWInfo
-> HTTP.Manager
-> APIRequest apiName responseType
-> m (C.ConduitM () responseType m ())
stream = stream'
stream' ::
( MonadResource m
, FromJSON value
, MonadThrow m
)
=> TWInfo
-> HTTP.Manager
-> APIRequest apiName responseType
-> m (C.ConduitM () value m ())
stream' info mgr req = do
rsrc <- getResponse info mgr =<< liftIO (makeRequest req)
return $ responseBody rsrc C..| CL.sequence sinkFromJSONIgnoreSpaces
where
sinkFromJSONIgnoreSpaces = CL.filter (not . S8.all isSpace) C..| sinkFromJSON
userstream :: APIRequest Userstream StreamingAPI
userstream = APIRequest "GET" "https://userstream.twitter.com/1.1/user.json" []
type Userstream = '[
"language" ':= T.Text
, "filter_level" ':= T.Text
, "stall_warnings" ':= Bool
, "replies" ':= T.Text
]
data FilterParameter = Follow [UserId]
| Track [T.Text]
statusesFilter :: [FilterParameter] -> APIRequest StatusesFilter StreamingAPI
statusesFilter fs = APIRequest "POST" statusesFilterEndpoint (L.map paramToQueryItem fs)
paramToQueryItem :: FilterParameter -> APIQueryItem
paramToQueryItem (Follow userIds) = ("follow", PVIntegerArray userIds)
paramToQueryItem (Track texts) = ("track", PVStringArray texts)
statusesFilterEndpoint :: String
statusesFilterEndpoint = "https://stream.twitter.com/1.1/statuses/filter.json"
statusesFilterByFollow :: [UserId] -> APIRequest StatusesFilter StreamingAPI
statusesFilterByFollow userIds = statusesFilter [Follow userIds]
statusesFilterByTrack :: T.Text
-> APIRequest StatusesFilter StreamingAPI
statusesFilterByTrack keyword = statusesFilter [Track [keyword]]
type StatusesFilter = '[
"language" ':= T.Text
, "filter_level" ':= T.Text
, "stall_warnings" ':= Bool
]