module Instagram.RealTime (
createSubscription
,listSubscriptions
,deleteSubscriptions
,SubscriptionRequest(..)
,SubscriptionParams(..)
,DeletionParams(..)
,verifySignature
)
where
import Instagram.Monad
import Instagram.Types
import Data.Text (Text)
import Data.Typeable
import qualified Network.HTTP.Types as HT
import Data.Maybe (isJust)
import Data.Conduit
import Data.Aeson (Value(..))
import qualified Data.ByteString.Base16 as Base16
import qualified Crypto.Classes as Crypto
import qualified Crypto.HMAC as Crypto
import Crypto.Hash.CryptoAPI (SHA1)
import Control.Monad (liftM)
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BSL
createSubscription :: (MonadBaseControl IO m, MonadResource m) =>
SubscriptionParams
-> InstagramT m (Envelope Subscription)
createSubscription params=do
let url="/v1/subscriptions/"
addClientInfos params >>= getPostRequest url >>= getJSONEnvelope
listSubscriptions :: (MonadBaseControl IO m, MonadResource m) =>
InstagramT m (Envelope [Subscription])
listSubscriptions =do
let url="/v1/subscriptions/"
addClientInfos ([]::HT.Query) >>= getGetRequest url >>= getJSONEnvelope
deleteSubscriptions :: (MonadBaseControl IO m, MonadResource m) =>
DeletionParams
-> InstagramT m (Envelope Value)
deleteSubscriptions params=do
let url="/v1/subscriptions/"
addClientInfos params >>= getDeleteRequest url >>= getJSONEnvelope
data SubscriptionParams= SubscriptionParams {
spRequest :: SubscriptionRequest
,spCallback :: CallbackUrl
,spAspect :: Aspect
,spVerifyToken :: Maybe Text
}
deriving (Read,Show,Eq,Ord,Typeable)
instance HT.QueryLike SubscriptionParams where
toQuery (SubscriptionParams req cb (Aspect asp) tok)=filter (isJust .snd) $ HT.toQuery req ++
["aspect" ?+ asp
,"callback_url" ?+ cb
,"verify_token" ?+ tok]
data SubscriptionRequest
=UserRequest
| TagRequest {
trTag ::Text
}
| LocationRequest {
lrID :: Text
}
| GeographyRequest {
grLatitude :: Double
,grLongitude :: Double
,grRadius :: Integer
}
deriving (Read,Show,Eq,Ord,Typeable)
instance HT.QueryLike SubscriptionRequest where
toQuery UserRequest=[("object",Just "user")]
toQuery (TagRequest tag)=[("object",Just "tag"),"object_id" ?+ tag]
toQuery (LocationRequest i)=[("object",Just "location"),"object_id" ?+ i]
toQuery (GeographyRequest lat lng rad)=[("object",Just "geography"),"lat" ?+ lat
,"lng" ?+ lng
,"radius" ?+ rad]
data DeletionParams
=DeleteAll
| DeleteOne {
doID :: Text
}
| DeleteUsers
| DeleteTags
| DeleteLocations
| DeleteGeographies
deriving (Read,Show,Eq,Ord,Typeable)
instance HT.QueryLike DeletionParams where
toQuery DeleteAll=[("object",Just "all")]
toQuery (DeleteOne i)=["id" ?+ i]
toQuery DeleteUsers=[("object",Just "user")]
toQuery DeleteTags=[("object",Just "tag")]
toQuery DeleteLocations=[("object",Just "location")]
toQuery DeleteGeographies=[("object",Just "geography")]
verifySignature :: Monad m =>
BS.ByteString
-> BSL.ByteString
-> InstagramT m Bool
verifySignature sig content=do
csecret<-liftM clientSecretBS getCreds
let key :: Crypto.MacKey ctx SHA1
key = Crypto.MacKey csecret
hash = Crypto.hmac key content
expected = Base16.encode (Crypto.encode hash)
return $! sig `Crypto.constTimeEq` expected