packages feed

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

module Network.API.Telegram.Bot.Property.Persistable
	(Persistable (..), Capacity (..), Inform (..), Way (..)) where

import "aeson" Data.Aeson (FromJSON, Value, decode)
import "base" Control.Exception (try)
import "base" Control.Monad (Monad ((>>=)), join)
import "base" Data.Function (flip, (.), ($))
import "base" Data.Functor (Functor (fmap), (<$>))
import "base" Data.Maybe (fromJust)
import "base" Data.Semigroup (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)

data Inform = Silently | Notify

data Way = Directly | Forwarding | Replying

data Capacity object = Send Inform Way object | Post object | Fetch object | Edit object | Purge object

class Persistable capacity object where
	{-# MINIMAL payload, endpoint #-}
	type Payload (capacity :: * -> Capacity *) object = payload | payload -> capacity object
	payload :: Payload capacity object -> Value
	endpoint :: Payload capacity object -> String
	persist :: FromJSON r => Payload capacity object -> Telegram e r
	persist x = request (endpoint x) (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