packages feed

telega-0.2.3: Network/API/Telegram/Bot/Property/Persistable.hs

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