telega 0.2.8 → 0.2.9
raw patch · 14 files changed
+226/−139 lines, 14 filesdep +reqdep −wreq
Dependencies added: req
Dependencies removed: wreq
Files
- CHANGELOG.md +10/−0
- Network/API/Telegram/Bot/Core.hs +3/−4
- Network/API/Telegram/Bot/Object/Chat.hs +27/−10
- Network/API/Telegram/Bot/Object/Chat/Channel.hs +3/−9
- Network/API/Telegram/Bot/Object/Chat/Conversation.hs +0/−22
- Network/API/Telegram/Bot/Object/Chat/Group.hs +4/−9
- Network/API/Telegram/Bot/Object/Sender.hs +17/−7
- Network/API/Telegram/Bot/Object/Update.hs +17/−8
- Network/API/Telegram/Bot/Object/Update/Callback.hs +14/−6
- Network/API/Telegram/Bot/Object/Update/Message.hs +73/−19
- Network/API/Telegram/Bot/Object/Update/Message/Origin.hs +24/−16
- Network/API/Telegram/Bot/Object/Update/Moving.hs +17/−12
- Network/API/Telegram/Bot/Property/Persistable.hs +15/−14
- telega.cabal +2/−3
CHANGELOG.md view
@@ -153,3 +153,13 @@ * Move all modules from `Special`s up one level into `Field` submodule (add `Title` newtype) * Create `Chat` submodule that contains `Conversation`, `Channel` and `Group` object * Define `ID` data family to use its instances for `Accessible` instances++# 0.2.9+* Replace `Int64` in `Send`, `Forward`, `Edit`, `Delete`, `Stop` message's `Persistable` methods on `ID Chat`+* Replace `Int` in `Forward`, `Edit`, `Delete`, `Stop` message's `Persistable` methods on `ID Message`+* Replace identifiers in `Callback`, `Message`, `Sender`, `Update` on specified `ID` data family instances+* Move chat identifiers from `Channel` and `Group` to `Origin` and `Moving`, delete `Conversation` module+* Define `Persistable` instances for pinning and unpinning messages in `Group`, `Supergroup` or `Channel` chats+* Define `Persistable` instances for leaving `Group`, `Supergroup` or `Channel` chats+* Change type of `Persistable`'s `endpoint` method to `Text`+* Replace `wreq` on `req` as HTTP library
Network/API/Telegram/Bot/Core.hs view
@@ -15,14 +15,13 @@ import "text" Data.Text (Text) import "transformers" Control.Monad.Trans.Reader (ReaderT (runReaderT), ask) import "transformers" Control.Monad.Trans.Except (ExceptT, runExceptT)-import "wreq" Network.Wreq.Session (Session) newtype Token = Token Text deriving Eq -type Telegram e a = ReaderT (e, (Session, Token)) (ExceptT SomeException IO) a+type Telegram e a = ReaderT (e, Token) (ExceptT SomeException IO) a -telegram :: Session -> Token -> e -> Telegram e a -> IO (Either SomeException a)-telegram session token env = runExceptT . flip runReaderT (env, (session, token))+telegram :: Token -> e -> Telegram e a -> IO (Either SomeException a)+telegram token env = runExceptT . flip runReaderT (env, token) ask' :: Telegram e e ask' = fst <$> ask
Network/API/Telegram/Bot/Object/Chat.hs view
@@ -1,24 +1,41 @@-module Network.API.Telegram.Bot.Object.Chat (module Exports, Chat, ID (..)) where+module Network.API.Telegram.Bot.Object.Chat (module Exports, Chat, Leave (..), ID (CHAT)) where import Network.API.Telegram.Bot.Object.Chat.Group as Exports-import Network.API.Telegram.Bot.Object.Chat.Conversation as Exports import Network.API.Telegram.Bot.Object.Chat.Channel as Exports +import "aeson" Data.Aeson (FromJSON (parseJSON), ToJSON (toJSON))+import "base" Data.Eq (Eq) import "base" Data.Functor ((<$>)) import "base" Data.Int (Int64)+import "base" Text.Show (Show) -import Network.API.Telegram.Bot.Property (Accessible (access), ID)+import Network.API.Telegram.Bot.Property+ (Persistable (Payload, Returning, payload, endpoint), ID)+import Network.API.Telegram.Bot.Utils (field) data Chat +data Leave a = Leave (ID Chat)++instance Persistable (Leave Group) where+ type Payload (Leave Group) = Leave Group+ type Returning (Leave Group) = ()+ payload (Leave chat_id) = field "chat_id" chat_id+ endpoint _ = "leaveChat"++instance Persistable (Leave Channel) where+ type Payload (Leave Channel) = Leave Channel+ type Returning (Leave Channel) = ()+ payload (Leave chat_id) = field "chat_id" chat_id+ endpoint _ = "leaveChat"+ data instance ID Chat = CHAT Int64 -instance Accessible (ID Chat) Channel where- access f (Channel i title) = (\(CHAT i') -> Channel i' title) <$> f (CHAT i)+deriving instance Eq (ID Chat)+deriving instance Show (ID Chat) -instance Accessible (ID Chat) Conversation where- access f (Conversation i) = (\(CHAT i') -> Conversation i') <$> f (CHAT i)+instance FromJSON (ID Chat) where+ parseJSON o = CHAT <$> parseJSON o -instance Accessible (ID Chat) Group where- access f (Basic i title) = (\(CHAT i') -> Basic i' title) <$> f (CHAT i)- access f (Super i title description) = (\(CHAT i') -> Super i' title description) <$> f (CHAT i)+instance ToJSON (ID Chat) where+ toJSON (CHAT i) = toJSON i
Network/API/Telegram/Bot/Object/Chat/Channel.hs view
@@ -10,15 +10,9 @@ import "text" Data.Text (Text) import Network.API.Telegram.Bot.Field (Title)-import Network.API.Telegram.Bot.Property.Identifiable (Identifiable (Identificator, ident)) -data Channel = Channel Int64 Title deriving Show--instance Identifiable Channel where- type Identificator Channel = Int64- ident (Channel i _) = i+data Channel = Channel Title deriving Show instance FromJSON Channel where- parseJSON = withObject "Channel" $ \chat -> chat .: "type" >>= \case- ("channel" :: Text) -> Channel <$> chat .: "id" <*> chat .: "title"- _ -> fail "Not a channel chat!"+ parseJSON = withObject "Channel" $+ \chat -> Channel <$> chat .: "title"
− Network/API/Telegram/Bot/Object/Chat/Conversation.hs
@@ -1,22 +0,0 @@-module Network.API.Telegram.Bot.Object.Chat.Conversation (Conversation (..)) where--import "aeson" Data.Aeson (FromJSON (parseJSON), withObject, (.:))-import "base" Control.Monad ((>>=), fail)-import "base" Data.Function (($))-import "base" Data.Functor ((<$>))-import "base" Data.Int (Int64)-import "base" Text.Show (Show)-import "text" Data.Text (Text)--import Network.API.Telegram.Bot.Property.Identifiable (Identifiable (Identificator, ident))--data Conversation = Conversation Int64 deriving Show--instance Identifiable Conversation where- type Identificator Conversation = Int64- ident (Conversation i) = i--instance FromJSON Conversation where- parseJSON = withObject "Conversation" $ \chat -> chat .: "type" >>= \case- ("private" :: Text) -> Conversation <$> chat .: "id"- _ -> fail "Not a private chat!"
Network/API/Telegram/Bot/Object/Chat/Group.hs view
@@ -14,17 +14,12 @@ import Network.API.Telegram.Bot.Property.Identifiable (Identifiable (Identificator, ident)) data Group- = Basic Int64 Title- | Super Int64 Title (Maybe Text)+ = Basic Title+ | Super Title (Maybe Text) deriving Show -instance Identifiable Group where- type Identificator Group = Int64- ident (Basic i _ ) = i- ident (Super i _ _) = i- instance FromJSON Group where parseJSON = withObject "Group" $ \chat -> chat .: "type" >>= \case- ("group" :: Text) -> Basic <$> chat .: "id" <*> chat .: "title"- ("supergroup" :: Text) -> Super <$> chat .: "id" <*> chat .: "title" <*> chat .:? "description"+ ("supergroup" :: Text) -> Super <$> chat .: "title" <*> chat .:? "description"+ ("group" :: Text) -> Basic <$> chat .: "title" _ -> fail "Neither group nor supergroup!"
Network/API/Telegram/Bot/Object/Sender.hs view
@@ -1,6 +1,7 @@-module Network.API.Telegram.Bot.Object.Sender (Sender (..)) where+module Network.API.Telegram.Bot.Object.Sender (Sender (..), ID (SNDR)) where -import "aeson" Data.Aeson (FromJSON (parseJSON), Object, withObject, (.:), (.:?))+import "aeson" Data.Aeson (FromJSON (parseJSON), ToJSON (toJSON)+ , Object, withObject, (.:), (.:?)) import "aeson" Data.Aeson.Types (Parser) import "base" Control.Applicative (Applicative ((<*>))) import "base" Control.Monad (Monad ((>>=)))@@ -13,11 +14,11 @@ import "base" Text.Show (Show) import Network.API.Telegram.Bot.Field (Language, Name, First, Last, Nick)-import Network.API.Telegram.Bot.Property (Accessible (access), Identifiable (Identificator, ident))+import Network.API.Telegram.Bot.Property (Accessible (access), Identifiable (Identificator, ident), ID) data Sender- = Bot Int (Maybe (Nick Name)) (First Name) (Maybe (Last Name)) (Maybe Language)- | Human Int (Maybe (Nick Name)) (First Name) (Maybe (Last Name)) (Maybe Language)+ = Bot (ID Sender) (Maybe (Nick Name)) (First Name) (Maybe (Last Name)) (Maybe Language)+ | Human (ID Sender) (Maybe (Nick Name)) (First Name) (Maybe (Last Name)) (Maybe Language) deriving Show instance Eq Sender where@@ -26,7 +27,7 @@ _ == _ = False instance Identifiable Sender where- type Identificator Sender = Int+ type Identificator Sender = ID Sender ident (Bot i _ _ _ _) = i ident (Human i _ _ _ _) = i @@ -46,7 +47,8 @@ access f (Bot uid nn fn ln lng) = (\lng' -> Bot uid nn fn ln lng') <$> f lng access f (Human uid nn fn ln lng) = (\lng' -> Human uid nn fn ln lng') <$> f lng -type Whom = Int -> Maybe (Nick Name) -> First Name -> Maybe (Last Name) -> Maybe Language -> Sender+type Whom = ID Sender -> Maybe (Nick Name) -> First Name+ -> Maybe (Last Name) -> Maybe Language -> Sender instance FromJSON Sender where parseJSON = withObject "Sender" $ \v -> v .: "is_bot"@@ -56,3 +58,11 @@ sender v f = f <$> v .: "id" <*> v .:? "username" <*> v .: "first_name" <*> v .:? "last_name" <*> v .:? "language_code"++data instance ID Sender = SNDR Int++deriving instance Eq (ID Sender)+deriving instance Show (ID Sender)++instance FromJSON (ID Sender) where parseJSON o = SNDR <$> parseJSON o+instance ToJSON (ID Sender) where toJSON (SNDR i) = toJSON i
Network/API/Telegram/Bot/Object/Update.hs view
@@ -1,23 +1,24 @@-module Network.API.Telegram.Bot.Object.Update (module Exports, Update (..)) where+module Network.API.Telegram.Bot.Object.Update (module Exports, Update (..), ID (UPD)) where import Network.API.Telegram.Bot.Object.Update.Callback as Exports import Network.API.Telegram.Bot.Object.Update.Message as Exports import Network.API.Telegram.Bot.Object.Update.Moving as Exports -import "aeson" Data.Aeson (FromJSON (parseJSON), withObject, (.:))+import "aeson" Data.Aeson (FromJSON (parseJSON), ToJSON (toJSON), withObject, (.:)) import "base" Control.Applicative ((<*>), (<|>))+import "base" Data.Eq (Eq) import "base" Data.Function (($)) import "base" Data.Functor ((<$>)) import "base" Data.Int (Int) import "base" Text.Show (Show) -import Network.API.Telegram.Bot.Object.Chat (Chat)-import Network.API.Telegram.Bot.Property (Accessible (access), Identifiable (Identificator, ident), ID)+import Network.API.Telegram.Bot.Object.Chat (Chat, ID)+import Network.API.Telegram.Bot.Property (Accessible (access), Identifiable (Identificator, ident)) data Update- = Query Int Callback- | Membership Int Moving- | Incoming Int Message+ = Query (ID Update) Callback+ | Membership (ID Update) Moving+ | Incoming (ID Update) Message deriving Show instance Accessible (ID Chat) Update where@@ -26,7 +27,7 @@ access f (Incoming i message) = Incoming i <$> access f message instance Identifiable Update where- type Identificator Update = Int+ type Identificator Update = ID Update ident (Query i _) = i ident (Membership i _) = i ident (Incoming i _) = i@@ -36,3 +37,11 @@ (Query <$> v .: "update_id" <*> v .: "callback_query") <|> (Membership <$> v .: "update_id" <*> v .: "message") <|> (Incoming <$> v .: "update_id" <*> v .: "message")++data instance ID Update = UPD Int++deriving instance Eq (ID Update)+deriving instance Show (ID Update)++instance FromJSON (ID Update) where parseJSON o = UPD <$> parseJSON o+instance ToJSON (ID Update) where toJSON (UPD i) = toJSON i
Network/API/Telegram/Bot/Object/Update/Callback.hs view
@@ -1,9 +1,9 @@ module Network.API.Telegram.Bot.Object.Update.Callback- (module Exports, Callback (..), Trigger (..)) where+ (module Exports, Callback (..), Trigger (..), ID (CB)) where import Network.API.Telegram.Bot.Object.Update.Callback.Notification as Exports -import "aeson" Data.Aeson (FromJSON (parseJSON), withObject, (.:))+import "aeson" Data.Aeson (FromJSON (parseJSON), ToJSON (toJSON), withObject, (.:)) import "base" Control.Applicative (Applicative ((<*>))) import "base" Data.Eq (Eq ((==))) import "base" Data.Function (flip, ($))@@ -19,7 +19,7 @@ import Network.API.Telegram.Bot.Property.Persistable (Persistable (Payload, Returning, payload, endpoint)) import Network.API.Telegram.Bot.Utils (field) -data Callback = Datatext Text Sender Message Text deriving Show+data Callback = Datatext (ID Callback) Sender Message Text deriving Show instance Eq Callback where c == c' = ident c == ident c'@@ -42,13 +42,21 @@ <*> v .: "message" <*> v .: "data" instance Identifiable Callback where- type Identificator Callback = Text+ type Identificator Callback = ID Callback ident (Datatext i _ _ _) = i -data Trigger a = Trigger Text Text+data Trigger a = Trigger (ID Callback) Text instance Persistable (Trigger Notification) where type Payload (Trigger Notification) = Trigger Notification type Returning (Trigger Notification) = ()- payload (Trigger cbq_id text) = field "text" text <> field "callback_query_id" cbq_id+ payload (Trigger cbq_id text) = field "callback_query_id" cbq_id <> field "text" text endpoint _ = "answerCallbackQuery"++data instance ID Callback = CB Text++deriving instance Eq (ID Callback)+deriving instance Show (ID Callback)++instance FromJSON (ID Callback) where parseJSON o = CB <$> parseJSON o+instance ToJSON (ID Callback) where toJSON (CB i) = toJSON i
Network/API/Telegram/Bot/Object/Update/Message.hs view
@@ -1,11 +1,12 @@-module Network.API.Telegram.Bot.Object.Update.Message (module Exports, Message (..)- , Send (..), Reply (..), Forward (..), Edit (..), Delete (..), Silently (..)) where+module Network.API.Telegram.Bot.Object.Update.Message (module Exports+ , Message (..), ID (MSG), Send (..), Reply (..), Forward (..)+ , Edit (..), Delete (..), Pin (..), Unpin (..), Silently (..)) where import Network.API.Telegram.Bot.Object.Update.Message.Content as Exports import Network.API.Telegram.Bot.Object.Update.Message.Keyboard as Exports import Network.API.Telegram.Bot.Object.Update.Message.Origin as Exports -import "aeson" Data.Aeson (FromJSON (parseJSON), Value (Object), withObject, (.:))+import "aeson" Data.Aeson (FromJSON (parseJSON), ToJSON (toJSON), Value (Object), withObject, (.:)) import "aeson" Data.Aeson.Types (Object, Parser) import "base" Control.Applicative ((<*>), (<|>)) import "base" Control.Monad (Monad ((>>=)), fail)@@ -13,23 +14,23 @@ import "base" Data.Eq (Eq ((==))) import "base" Data.Function (flip, ($)) import "base" Data.Functor ((<$>))-import "base" Data.Int (Int, Int64)+import "base" Data.Int (Int) import "base" Data.Semigroup ((<>)) import "base" Text.Show (Show) import "text" Data.Text (Text) import "with" Data.With (type (:&:)((:&:))) import Network.API.Telegram.Bot.Field (Caption, URI)-import Network.API.Telegram.Bot.Object.Chat (Chat, ID)+import Network.API.Telegram.Bot.Object.Chat (Chat, Group, Channel, ID) import Network.API.Telegram.Bot.Property.Accessible (Accessible (access)) import Network.API.Telegram.Bot.Property.Identifiable (Identifiable (Identificator, ident)) import Network.API.Telegram.Bot.Property.Persistable (Persistable (Payload, Returning, payload, endpoint)) import Network.API.Telegram.Bot.Utils (field) data Message- = Direct Int Origin Content- | Forwarded Int Origin Content- | Replied Int Origin Content Message+ = Direct (ID Message) Origin Content+ | Forwarded (ID Message) Origin Content+ | Replied (ID Message) Origin Content Message deriving Show instance Eq Message where@@ -51,7 +52,7 @@ access f (Replied msg_id origin content msg) = Replied msg_id origin content <$> access f msg instance Identifiable Message where- type Identificator Message = Int+ type Identificator Message = ID Message ident (Direct i _ _) = i ident (Forwarded i _ _) = i ident (Replied i _ _ _) = i@@ -65,7 +66,8 @@ <*> (v .: "forward_from_chat" >>= channel) <*> parseJSON (Object v) where channel :: Value -> Parser Origin- channel = withObject "Channel" $ \c -> Blog <$> c .: "id"+ channel = withObject "Channel" $ \c -> Blog+ <$> c .: "id" <*> parseJSON (Object c) forward_chat :: Object -> Parser Message forward_chat v = Forwarded <$> v .: "message_id"@@ -74,8 +76,8 @@ chat :: Value -> Parser Origin chat = withObject "Origin" $ \c -> c .: "type" >>= \case ("private" :: Text) -> Private <$> c .: "id" <*> v .: "forward_from"- ("group" :: Text) -> Group <$> parseJSON (Object c) <*> v .: "forward_from"- ("supergroup" :: Text) -> Group <$> parseJSON (Object c) <*> v .: "forward_from"+ ("group" :: Text) -> Group <$> c .: "id" <*> parseJSON (Object c) <*> v .: "forward_from"+ ("supergroup" :: Text) -> Group <$> c .: "id" <*> parseJSON (Object c) <*> v .: "forward_from" _ -> fail "Type of chat is not defined" reply :: Object -> Parser Message@@ -86,7 +88,7 @@ direct v = Direct <$> v .: "message_id" <*> parseJSON (Object v) <*> parseJSON (Object v) -data Forward a = Forward Int Int64 Int64+data Forward a = Forward (ID Message) (ID Chat) (ID Chat) instance Persistable (Forward Message) where type Payload (Forward Message) = Forward Message@@ -95,7 +97,7 @@ <> field "from_chat_id" from_chat_id <> field "chat_id" to_chat_id endpoint _ = "forwardMessage" -data Send a = Send Int64 a+data Send a = Send (ID Chat) a instance Persistable (Send Text) where type Payload (Send Text) = Send Text@@ -201,7 +203,7 @@ <> field "question" question <> field "options" options endpoint _ = "sendPoll" -data Reply a = Reply Int a+data Reply a = Reply (ID Message) a instance Persistable (Send a) => Persistable (Reply a) where type Payload (Reply a) = Reply (Payload (Send a))@@ -210,7 +212,7 @@ "reply_to_message_id" reply_to_message_id endpoint (Reply _ x) = endpoint x -data Edit b = Edit Int64 Int b+data Edit b = Edit (ID Chat) (ID Message) b instance Persistable (Edit Text) where type Payload (Edit Text) = Edit Text@@ -234,7 +236,7 @@ <> field "latitude" latitude <> field "longitude" longitude endpoint _ = "editMessageLiveLocation" -data Delete a = Delete Int64 Int+data Delete a = Delete (ID Chat) (ID Message) instance Persistable (Delete Message) where type Payload (Delete Message) = Delete Message@@ -243,7 +245,7 @@ <> field "message_id" message_id endpoint _ = "deleteMessage" -data Stop a = Stop Int64 Int+data Stop a = Stop (ID Chat) (ID Message) instance Persistable (Stop (Live Location)) where type Payload (Stop (Live Location)) = Stop (Live Location)@@ -253,12 +255,44 @@ endpoint _ = "stopMessageLiveLocation" instance Persistable (Stop Poll) where- type Payload (Stop Poll) = Stop (Stop Poll)+ type Payload (Stop Poll) = Stop Poll type Returning (Stop Poll) = Poll payload (Stop chat_id message_id) = field "chat_id" chat_id <> field "message_id" message_id endpoint _ = "stopPoll" +data Pin chat msg where+ Pin :: ID Message -> ID Chat -> Pin b Message++instance Persistable (Pin Group Message) where+ type Payload (Pin Group Message) = Pin Group Message+ type Returning (Pin Group Message) = ()+ payload (Pin chat_id message_id) = field "chat_id" chat_id+ <> field "message_id" message_id+ endpoint _ = "pinChatMessage"++instance Persistable (Pin Channel Message) where+ type Payload (Pin Channel Message) = Pin Channel Message+ type Returning (Pin Channel Message) = ()+ payload (Pin chat_id message_id) = field "chat_id" chat_id+ <> field "message_id" message_id+ endpoint _ = "pinChatMessage"++data Unpin chat msg where+ Unpin :: ID Chat -> Unpin b Message++instance Persistable (Unpin Group Message) where+ type Payload (Unpin Group Message) = Unpin Group Message+ type Returning (Unpin Group Message) = ()+ payload (Unpin chat_id) = field "chat_id" chat_id+ endpoint _ = "unpinChatMessage"++instance Persistable (Unpin Channel Message) where+ type Payload (Unpin Channel Message) = Unpin Channel Message+ type Returning (Unpin Channel Message) = ()+ payload (Unpin chat_id) = field "chat_id" chat_id+ endpoint _ = "unpinChatMessage"+ data Silently (todo :: * -> *) a = Silently a instance Persistable (Forward obj) => Persistable (Silently Forward obj) where@@ -278,3 +312,23 @@ type Returning (Silently Reply obj) = Message payload (Silently x) = payload x <> field "disable_notification" True endpoint (Silently x) = endpoint x++instance Persistable (Pin chat Message) => Persistable (Silently (Pin chat) Message) where+ type Payload (Silently (Pin chat) Message) = Silently (Pin chat) (Payload (Pin chat Message))+ type Returning (Silently (Pin chat) Message) = ()+ payload (Silently x) = payload x <> field "disable_notification" True+ endpoint (Silently x) = endpoint x++instance Persistable (Unpin chat Message) => Persistable (Silently (Unpin chat) Message) where+ type Payload (Silently (Unpin chat) Message) = Silently (Unpin chat) (Payload (Unpin chat Message))+ type Returning (Silently (Unpin chat) Message) = ()+ payload (Silently x) = payload x <> field "disable_notification" True+ endpoint (Silently x) = endpoint x++data instance ID Message = MSG Int++deriving instance Eq (ID Message)+deriving instance Show (ID Message)++instance FromJSON (ID Message) where parseJSON o = MSG <$> parseJSON o+instance ToJSON (ID Message) where toJSON (MSG i) = toJSON i
Network/API/Telegram/Bot/Object/Update/Message/Origin.hs view
@@ -1,32 +1,40 @@ module Network.API.Telegram.Bot.Object.Update.Message.Origin (Origin (..)) where import "aeson" Data.Aeson (FromJSON (parseJSON), withObject, (.:))-import "base" Control.Applicative ((<*>), (<|>))+import "aeson" Data.Aeson.Types (Object, Parser, Value (Object))+import "base" Control.Applicative ((<*>)) import "base" Control.Monad (Monad ((>>=)))-import "base" Data.Function (flip, ($))+import "base" Data.Function (($)) import "base" Data.Functor ((<$>))-import "base" Data.Int (Int64) import "base" Text.Show (Show)+import "text" Data.Text (Text) -import Network.API.Telegram.Bot.Object.Chat (Chat, ID, Channel, Conversation, Group)+import Network.API.Telegram.Bot.Object.Chat (Chat, ID,Channel, Group) import Network.API.Telegram.Bot.Object.Sender (Sender) import Network.API.Telegram.Bot.Property (Accessible (access), Identifiable (Identificator, ident)) -data Origin = Private Conversation Sender | Group Group Sender | Blog Channel deriving Show+data Origin+ = Private (ID Chat) Sender+ | Group (ID Chat) Group Sender+ | Blog (ID Chat) Channel+ deriving Show instance Accessible (ID Chat) Origin where- access f (Private conversation sender) = flip Private sender <$> access f conversation- access f (Group group sender) = flip Group sender <$> access f group- access f (Blog channel) = Blog <$> access f channel+ access f (Private i sender) = (\i' -> Private i' sender) <$> f i+ access f (Group i group sender) = (\i' -> Group i' group sender) <$> f i+ access f (Blog i channel) = (\i' -> Blog i' channel) <$> f i instance Identifiable Origin where- type Identificator Origin = Int64- ident (Private c _) = ident c- ident (Group g _) = ident g- ident (Blog c) = ident c+ type Identificator Origin = ID Chat+ ident (Private i _) = i+ ident (Group i _ _) = i+ ident (Blog i _) = i instance FromJSON Origin where- parseJSON = withObject "Message" $ \msg -> msg .: "chat" >>= \chat ->- (Group <$> parseJSON chat <*> msg .: "from") <|>- (Private <$> parseJSON chat <*> msg .: "from") <|>- (Blog <$> parseJSON chat)+ parseJSON = withObject "Message" $ \msg -> msg .: "chat" >>= chat msg where++ chat :: Object -> Value -> Parser Origin+ chat msg = withObject "Chat" $ \ch -> ch .: "type" >>= \case+ ("private" :: Text) -> Private <$> ch .: "id" <*> msg .: "from"+ ("channel" :: Text) -> Blog <$> ch .: "id" <*> parseJSON (Object ch)+ _ -> Group <$> ch .: "id" <*> parseJSON (Object ch) <*> msg .: "from"
Network/API/Telegram/Bot/Object/Update/Moving.hs view
@@ -1,30 +1,35 @@ module Network.API.Telegram.Bot.Object.Update.Moving (Moving (..)) where import "aeson" Data.Aeson (FromJSON (parseJSON), withObject, (.:))+import "aeson" Data.Aeson.Types (Object, Parser, Value (Object)) import "base" Control.Applicative ((<*>), (<|>))-import "base" Data.Function (($))+import "base" Control.Monad ((>>=))+import "base" Data.Function (flip, ($)) import "base" Data.Functor ((<$>)) import "base" Text.Show (Show) -import Network.API.Telegram.Bot.Object.Chat (Chat)+import Network.API.Telegram.Bot.Object.Chat (Chat, ID) import Network.API.Telegram.Bot.Object.Chat.Group (Group) import Network.API.Telegram.Bot.Object.Sender (Sender)-import Network.API.Telegram.Bot.Property (Accessible (access), ID)+import Network.API.Telegram.Bot.Property (Accessible (access)) data Moving- = Gone Sender Group- | Joined [Sender] Group+ = Gone Sender (ID Chat) Group+ | Joined [Sender] (ID Chat) Group deriving Show instance Accessible Group Moving where- access f (Gone sender group) = (\group' -> Gone sender group') <$> f group- access f (Joined senders group) = (\group' -> Joined senders group') <$> f group+ access f (Gone sender i group) = Gone sender i <$> f group+ access f (Joined senders i group) = Joined senders i <$> f group instance Accessible (ID Chat) Moving where- access f (Gone sender group) = Gone sender <$> access f group- access f (Joined senders group) = Joined senders <$> access f group+ access f (Gone sender i group) = flip (Gone sender) group <$> f i+ access f (Joined senders i group) = flip (Joined senders) group <$> f i instance FromJSON Moving where- parseJSON = withObject "Moving" $ \v ->- (Gone <$> v .: "left_chat_member" <*> v .: "chat") <|>- (Joined <$> v .: "new_chat_members" <*> v .: "chat")+ parseJSON = withObject "Moving" $ \msg -> msg .: "chat" >>= chat msg where++ chat :: Object -> Value -> Parser Moving+ chat msg = withObject "Group" $ \g ->+ (Gone <$> msg .: "left_chat_member" <*> g .: "id" <*> parseJSON (Object g)) <|>+ (Joined <$> msg .: "new_chat_members" <*> g .: "id" <*> parseJSON (Object g))
Network/API/Telegram/Bot/Property/Persistable.hs view
@@ -1,20 +1,20 @@ module Network.API.Telegram.Bot.Property.Persistable (Persistable (..)) where -import "aeson" Data.Aeson (FromJSON, Object, Value (Object), decode)+import "aeson" Data.Aeson (FromJSON, Object, Value (Object)) import "base" Control.Exception (try)-import "base" Control.Monad (join, (>>=))-import "base" Data.Function (flip, (.), ($))-import "base" Data.Functor (fmap, (<$>))+import "base" Control.Monad ((>>=))+import "base" Data.Function ((.), ($))+import "base" Data.Functor ((<$>)) import "base" Data.Maybe (fromJust)-import "base" Data.Semigroup ((<>))-import "base" Data.String (String)+import "base" Data.Monoid (mempty) import "base" Data.Tuple (snd)-import "http-client" Network.HTTP.Client (Response (responseBody))-import "text" Data.Text (unpack)+import "data-default" Data.Default (def)+import "text" Data.Text (Text) 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 "req" Network.HTTP.Req (POST (POST), ReqBodyJson (ReqBodyJson)+ , https, jsonResponse, req, responseBody, runReq, (/:)) import Network.API.Telegram.Bot.Core (Telegram, Token (Token), Ok, result) @@ -23,7 +23,7 @@ type Payload action = payload | payload -> action type Returning action :: * payload :: Payload action -> Object- endpoint :: Payload action -> String+ endpoint :: Payload action -> Text persist :: FromJSON (Returning action) => Payload action -> Telegram e (Returning action) persist x = request (endpoint x) (Object $ payload x)@@ -31,7 +31,8 @@ persist_ :: Payload action -> Telegram e () persist_ x = request @() @_ (endpoint x) (Object $ payload x) -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+request :: forall a e . FromJSON a => Text -> Value -> Telegram e a+request e p = snd <$> ask >>= \(Token token) -> lift . ExceptT . try .+ (<$>) (fromJust . result . responseBody) . runReq def $+ req POST (https "api.telegram.org" /: token /: e)+ (ReqBodyJson p) (jsonResponse @(Ok a)) mempty
telega.cabal view
@@ -1,5 +1,5 @@ name: telega-version: 0.2.8+version: 0.2.9 synopsis: Telegram Bot API binding description: High-level bindings, typed entities, inline mode only homepage: https://github.com/iokasimov/telega@@ -35,7 +35,6 @@ Network.API.Telegram.Bot.Object Network.API.Telegram.Bot.Object.Chat Network.API.Telegram.Bot.Object.Chat.Channel- Network.API.Telegram.Bot.Object.Chat.Conversation Network.API.Telegram.Bot.Object.Chat.Group Network.API.Telegram.Bot.Object.Member Network.API.Telegram.Bot.Object.Member.Powers@@ -67,7 +66,7 @@ Network.API.Telegram.Bot.Property.Identifiable Network.API.Telegram.Bot.Property.Persistable Network.API.Telegram.Bot.Utils- build-depends: base == 4.*, data-default, transformers, with, lens, aeson, text, unordered-containers, http-client, wreq+ build-depends: base == 4.*, data-default, transformers, with, lens, aeson, text, unordered-containers, http-client, req default-extensions: DataKinds, LambdaCase, OverloadedStrings, NoImplicitPrelude, PackageImports, GADTs, FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, UndecidableInstances, StandaloneDeriving TypeApplications, TypeFamilies, TypeFamilyDependencies, TypeOperators, ScopedTypeVariables