module Network.API.Telegram.Bot.Property.Persistable (Persistable (..)) where import "aeson" Data.Aeson (FromJSON, Object, Value (Object), decode) import "base" Control.Exception (try) import "base" Control.Monad (join, (>>=)) import "base" Data.Function (flip, (.), ($)) import "base" Data.Functor (fmap, (<$>)) import "base" Data.Maybe (fromJust) import "base" Data.Semigroup ((<>)) import "base" Data.String (String) import "base" Data.Tuple (snd) import "http-client" Network.HTTP.Client (Response (responseBody)) import "text" Data.Text (unpack) import "transformers" Control.Monad.Trans.Class (lift) import "transformers" Control.Monad.Trans.Except (ExceptT (ExceptT)) import "transformers" Control.Monad.Trans.Reader (ask) import "wreq" Network.Wreq.Session (post) import Network.API.Telegram.Bot.Core (Telegram, Token (Token), Ok, result) class Persistable action where {-# MINIMAL payload, endpoint #-} type Payload action = payload | payload -> action payload :: Payload action -> Object endpoint :: Payload action -> String persist :: FromJSON r => Payload action -> Telegram e r persist x = request (endpoint x) (Object $ payload x) where request :: forall a e . FromJSON a => String -> Value -> Telegram e a request e p = snd <$> ask >>= \(session, Token token) -> lift . ExceptT . try . fmap (fromJust . join . fmap result . decode @(Ok a) . responseBody) . flip (post session) p $ "https://api.telegram.org/" <> unpack token <> "/" <> e persist_ :: Payload action -> Telegram e () persist_ x = persist @_ @() x where