telega-0.1.9: Network/Telegram/API/Bot/Property/Persistable.hs
module Network.Telegram.API.Bot.Property.Persistable
(Persistable (..), Payload, PL (..), Capacity (..), Message' (..)) where
import "aeson" Data.Aeson (FromJSON, Value, decode, object, (.=))
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.Int (Int, Int64)
import "base" Data.Maybe (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 (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.Telegram.API.Bot.Core (Telegram, Token (Token), Ok, result)
import Network.Telegram.API.Bot.Object (Object, Keyboard, Notification, Member, Sender)
import Network.Telegram.API.Bot.Object.Update.Message (Message)
import Network.Telegram.API.Bot.Object.Update.Message.Content.Info (Info)
import Network.Telegram.API.Bot.Object.Update.Message.Content.Location (Location)
data Capacity = Post' | Fetch' | Edit' | Purge'
newtype PL c o a = PL a
type family Payload (c :: k) o = r | r -> o c
type instance Payload 'Post' Keyboard = PL 'Post' Keyboard (Int64, Text, Keyboard)
type instance Payload 'Edit' Keyboard = PL 'Edit' Keyboard (Int64, Int, Keyboard)
type instance Payload 'Fetch' Member = PL 'Fetch' Member (Int64, Int)
type instance Payload 'Edit' Message = PL 'Edit' Message (Int64, Int, Text)
type instance Payload 'Purge' Message = PL 'Purge' Message (Int64, Int)
type instance Payload 'Post' Notification = PL 'Post' Notification (Text, Text)
type instance Payload 'Fetch' Sender = PL 'Fetch' Sender ()
data Message' = Direct' Capacity | Forward' Capacity | Reply' Capacity
type instance Payload ('Direct' 'Post') Message = PL ('Direct' 'Post') Message (Int64, Text)
type instance Payload ('Forward' 'Post') Message = PL ('Forward' 'Post') Message (Int64, Int64, Int)
type instance Payload ('Reply' 'Post') Message = PL ('Reply' 'Post') Message (Int64, Int, Text)
data Info' = Point' Message' | Contact' Message' | Venue' Message'
type instance Payload ('Point' ('Direct' 'Post')) Info = PL ('Point' ('Direct' 'Post')) Info (Int64, Location, Int)
type instance Payload ('Contact' ('Direct' 'Post')) Info = PL ('Contact' ('Direct' 'Post')) Info (Int64, Text, Text, Maybe Text, Maybe Text)
type instance Payload ('Venue' ('Direct' 'Post')) Info = PL ('Venue' ('Direct' 'Post')) Info (Int64, Location, Text, Text, Maybe Text, Maybe Text)
type instance Payload ('Point' ('Reply' 'Post')) Info = PL ('Point' ('Reply' 'Post')) Info (Int64, Int, Location, Int)
type instance Payload ('Contact' ('Reply' 'Post')) Info = PL ('Contact' ('Reply' 'Post')) Info (Int64, Int, Text, Text, Maybe Text, Maybe Text)
type instance Payload ('Venue' ('Reply' 'Post')) Info = PL ('Venue' ('Reply' 'Post')) Info (Int64, Int, Location, Text, Text, Maybe Text, Maybe Text)
data Member' = Kick' | Unban'
type instance Payload 'Kick' Member = PL 'Kick' Member (Int64, Int, Int)
type instance Payload 'Unban' Member = PL 'Unban' Member (Int64, Int)
class Object o => Persistable c o where
{-# MINIMAL payload, endpoint #-}
payload :: Payload c o -> Value
endpoint :: Payload c o -> String
request :: FromJSON r => Payload c o -> Telegram e r
request 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
instance Persistable 'Edit' Keyboard where
payload (PL (chat_id, message_id, reply_markup)) = object
["chat_id" .= chat_id, "message_id" .= message_id, "reply_markup" .= reply_markup]
endpoint _ = "editMessageReplyMarkup"
instance Persistable 'Post' Keyboard where
payload (PL (chat_id, text, kb)) = object
["chat_id" .= chat_id, "text" .= text, "reply_markup" .= kb]
endpoint _ = "sendMessage"
instance Persistable 'Fetch' Member where
payload (PL (chat_id, user_id)) = object ["chat_id" .= chat_id, "user_id" .= user_id]
endpoint _ = "getChatMember"
instance Persistable ('Direct' 'Post') Message where
payload (PL (chat_id, text)) = object ["chat_id" .= chat_id, "text" .= text]
endpoint _ = "sendMessage"
instance Persistable ('Forward' 'Post') Message where
payload (PL (chat_id, from_chat_id, message_id)) = object
["chat_id" .= chat_id, "from_chat_id" .= from_chat_id, "message_id" .= message_id]
endpoint _ = "forwardMessage"
instance Persistable ('Reply' 'Post') Message where
payload (PL (chat_id, reply_to_message_id, text)) = object
["chat_id" .= chat_id, "reply_to_message_id" .= reply_to_message_id, "text" .= text]
endpoint _ = "sendMessage"
instance Persistable 'Purge' Message where
payload (PL (chat_id, message_id)) = object ["chat_id" .= chat_id, "message_id" .= message_id]
endpoint _ = "deleteMessage"
instance Persistable 'Post' Notification where
payload (PL (cbq_id, text)) = object ["callback_query_id" .= cbq_id, "text" .= text]
endpoint _ = "answerCallbackQuery"
instance Persistable 'Fetch' Sender where
payload (PL ()) = object []
endpoint _ = "getMe"
instance Persistable 'Edit' Message where
payload (PL (chat_id, message_id, text)) = object
["chat_id" .= chat_id, "message_id" .= message_id, "text" .= text]
endpoint _ = "editMessageText"
instance Persistable ('Point' ('Direct' 'Post')) Info where
payload (PL (chat_id, location, live_period)) = object
["chat_id" .= chat_id, "location" .= location, "live_period" .= live_period]
endpoint _ = "sendLocation"
instance Persistable ('Contact' ('Direct' 'Post')) Info where
payload (PL (chat_id, phone_number, first_name, last_name, vcard)) =
object ["chat_id" .= chat_id, "phone_number" .= phone_number,
"first_name" .= first_name, "last_name" .= last_name, "vcard" .= vcard]
endpoint _ = "sendContact"
instance Persistable ('Venue' ('Direct' 'Post')) Info where
payload (PL (chat_id, location, title, address, foursquare_id, foursquare_type)) = object
["chat_id" .= chat_id, "location" .= location, "title" .= title, "address" .= address,
"foursquare_id" .= foursquare_id, "foursquare_type" .= foursquare_type]
endpoint _ = "sendVenue"
instance Persistable ('Point' ('Reply' 'Post')) Info where
payload (PL (chat_id, reply_to_message_id, location, live_period)) = object
["chat_id" .= chat_id, "reply_to_message_id" .= reply_to_message_id,
"location" .= location, "live_period" .= live_period]
endpoint _ = "sendLocation"
instance Persistable ('Contact' ('Reply' 'Post')) Info where
payload (PL (chat_id, reply_to_message_id, phone_number, first_name, last_name, vcard)) = object
["chat_id" .= chat_id, "reply_to_message_id" .= reply_to_message_id, "phone_number" .= phone_number,
"first_name" .= first_name, "last_name" .= last_name, "vcard" .= vcard]
endpoint _ = "sendContact"
instance Persistable ('Venue' ('Reply' 'Post')) Info where
payload (PL (chat_id, reply_to_message_id, location, title, address, foursquare_id, foursquare_type)) = object
["chat_id" .= chat_id, "reply_to_message_id" .= reply_to_message_id, "location" .= location, "title" .= title,
"address" .= address, "foursquare_id" .= foursquare_id, "foursquare_type" .= foursquare_type]
endpoint _ = "sendVenue"
instance Persistable 'Kick' Member where
payload (PL (chat_id, user_id, until_date)) = object
["chat_id" .= chat_id, "user_id" .= user_id, "until_date" .= until_date]
endpoint _ = "kickChatMember"
instance Persistable 'Unban' Member where
payload (PL (chat_id, user_id)) = object ["chat_id" .= chat_id, "user_id" .= user_id]
endpoint _ = "unbanChatMember"