telega 0.1.4 → 0.1.5
raw patch · 19 files changed
+165/−183 lines, 19 files
Files
- CHANGELOG.md +9/−0
- Network/Telegram/API/Bot.hs +0/−2
- Network/Telegram/API/Bot/Access.hs +0/−6
- Network/Telegram/API/Bot/Endpoint.hs +0/−22
- Network/Telegram/API/Bot/Internal.hs +0/−25
- Network/Telegram/API/Bot/Object/Callback.hs +1/−12
- Network/Telegram/API/Bot/Object/Chat.hs +0/−11
- Network/Telegram/API/Bot/Object/From.hs +0/−9
- Network/Telegram/API/Bot/Object/Keyboard.hs +1/−10
- Network/Telegram/API/Bot/Object/Member.hs +2/−2
- Network/Telegram/API/Bot/Object/Message.hs +5/−40
- Network/Telegram/API/Bot/Object/Moving.hs +0/−5
- Network/Telegram/API/Bot/Object/Notification.hs +1/−13
- Network/Telegram/API/Bot/Object/Update.hs +0/−16
- Network/Telegram/API/Bot/Property.hs +2/−0
- Network/Telegram/API/Bot/Property/Accessible.hs +41/−0
- Network/Telegram/API/Bot/Property/Identifiable.hs +35/−3
- Network/Telegram/API/Bot/Property/Persistable.hs +63/−0
- telega.cabal +5/−7
CHANGELOG.md view
@@ -26,3 +26,12 @@ * Define `Endpoint` typeclass to replace `Capacity` * Remove `Capacity` classes and theirs instances * Define `Object` type family++# 0.1.5+* Remove `Internal` module, move its content to `Endpoint`+* Remove `Drop` phantom datatype, replace it with `Post`+* Use promoted constructors of `Capacity` instead of separated datatypes+* Use `MultiParamTypeClasses` instead of `FlexibleIntances` for `Endpoint`+* Use `UndecidableInstances` and `UndecidableSuperClasses` to use `Object` type family+* Replace `Access` module with `Accessible` `Property`+* Replace `Endpoint` module with `Persistable` `Property`
Network/Telegram/API/Bot.hs view
@@ -2,6 +2,4 @@ import Network.Telegram.API.Bot.Property as Exports import Network.Telegram.API.Bot.Object as Exports-import Network.Telegram.API.Bot.Endpoint as Exports-import Network.Telegram.API.Bot.Access as Exports import Network.Telegram.API.Bot.Core as Exports
− Network/Telegram/API/Bot/Access.hs
@@ -1,6 +0,0 @@-module Network.Telegram.API.Bot.Access (Access (..)) where--import "lens" Control.Lens (Lens')--class Access target source where- access :: Lens' source target
− Network/Telegram/API/Bot/Endpoint.hs
@@ -1,22 +0,0 @@-module Network.Telegram.API.Bot.Endpoint- (Endpoint (..), Payload, Drop, Edit, Post, Purge) where--import "aeson" Data.Aeson (FromJSON, Value)-import "base" Data.String (String)--import Network.Telegram.API.Bot.Core (Telegram)-import Network.Telegram.API.Bot.Internal (telegram_request)--type family Payload a = r | r -> a--data Drop a-data Edit a-data Post a-data Purge a--class Endpoint a where- {-# MINIMAL payload, endpoint #-}- payload :: Payload a -> Value- endpoint :: Payload a -> String- request :: FromJSON r => Payload a -> Telegram e r- request x = telegram_request (endpoint x) (payload x)
− Network/Telegram/API/Bot/Internal.hs
@@ -1,25 +0,0 @@-module Network.Telegram.API.Bot.Internal (telegram_request) 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 qualified "wreq" Network.Wreq.Session as Wreq (post)--import Network.Telegram.API.Bot.Core (Telegram, Token (Token), Ok, result)--telegram_request :: forall a e . FromJSON a => String -> Value -> Telegram e a-telegram_request endpoint payload = snd <$> ask >>= \(session, Token token) -> lift . ExceptT . try- . fmap (fromJust . join . fmap result . decode @(Ok a) . responseBody)- . flip (Wreq.post session) payload $ "https://api.telegram.org/" <> unpack token <> "/" <> endpoint
Network/Telegram/API/Bot/Object/Callback.hs view
@@ -2,14 +2,11 @@ import "aeson" Data.Aeson (FromJSON (parseJSON), withObject, (.:)) import "base" Control.Applicative (Applicative ((<*>)))-import "base" Data.Function (flip, ($))+import "base" Data.Function (($)) import "base" Data.Functor ((<$>)) import "base" Text.Show (Show) import "text" Data.Text (Text) -import Network.Telegram.API.Bot.Access (Access (access))-import Network.Telegram.API.Bot.Object.Chat (Chat)-import Network.Telegram.API.Bot.Object.From (From) import Network.Telegram.API.Bot.Object.Message (Message) data Callback = Datatext Text Message Text deriving Show@@ -17,11 +14,3 @@ instance FromJSON Callback where parseJSON = withObject "Callback" $ \v -> Datatext <$> v .: "id" <*> v .: "message" <*> v .: "data"--instance Access Chat Callback where- access f (Datatext cq_id msg dttxt) = flip- (Datatext cq_id) dttxt <$> access f msg--instance Access From Callback where- access f (Datatext cq_id msg dttxt) = flip- (Datatext cq_id) dttxt <$> access f msg
Network/Telegram/API/Bot/Object/Chat.hs view
@@ -9,23 +9,12 @@ import "base" Text.Show (Show) import "text" Data.Text (Text) -import Network.Telegram.API.Bot.Property.Identifiable- (Identifiable (identificator), Identificator)- data Chat = Private Int64 | Group Int64 Text | Supergroup Int64 Text | Channel Int64 Text deriving Show--type instance Identificator Chat = Int64--instance Identifiable Chat where- identificator (Private i) = i- identificator (Group i _) = i- identificator (Supergroup i _) = i- identificator (Channel i _) = i instance FromJSON Chat where parseJSON = withObject "Chat" $ \v -> v .: "type" >>= \case
Network/Telegram/API/Bot/Object/From.hs view
@@ -15,19 +15,10 @@ import "lens" Control.Lens (Lens') import "text" Data.Text (Text) -import Network.Telegram.API.Bot.Property.Identifiable- (Identifiable (identificator), Identificator)- data From = Bot Int (Maybe Text) Text (Maybe Text) (Maybe Text) | User Int (Maybe Text) Text (Maybe Text) (Maybe Text) deriving Show--type instance Identificator From = Int--instance Identifiable From where- identificator (Bot i _ _ _ _) = i- identificator (User i _ _ _ _) = i instance Eq From where Bot i _ _ _ _ == Bot i' _ _ _ _ = i == i'
Network/Telegram/API/Bot/Object/Keyboard.hs view
@@ -1,12 +1,10 @@-module Network.Telegram.API.Bot.Object.Keyboard (Keyboard (..), Payload) where+module Network.Telegram.API.Bot.Object.Keyboard (Keyboard (..)) where import "aeson" Data.Aeson (FromJSON (parseJSON), ToJSON (toJSON), object, withObject, (.:), (.=)) import "base" Data.Function (($)) import "base" Data.Functor ((<$>))-import "base" Data.Int (Int, Int64) import "base" Text.Show (Show) -import Network.Telegram.API.Bot.Endpoint (Endpoint (payload, endpoint), Payload, Edit) import Network.Telegram.API.Bot.Object.Button (Button) data Keyboard = Inline [[Button]] deriving Show@@ -18,10 +16,3 @@ instance ToJSON Keyboard where toJSON (Inline buttons) = object ["inline_keyboard" .= buttons]--type instance Payload (Edit Keyboard) = (Int64, Int, Keyboard)--instance Endpoint (Edit Keyboard) where- payload (chat_id, message_id, reply_markup) = object- ["chat_id" .= chat_id, "message_id" .= message_id, "reply_markup" .= reply_markup]- endpoint _ = "editMessageReplyMarkup"
Network/Telegram/API/Bot/Object/Member.hs view
@@ -16,7 +16,7 @@ | Administrator From | Member From | Restricted From POSIXTime- -- | Left From+ | Left From | Kicked From POSIXTime deriving Show @@ -26,6 +26,6 @@ ("administrator" :: Text) -> Administrator <$> v .: "user" ("member" :: Text) -> Member <$> v .: "user" ("restricted" :: Text) -> Restricted <$> v .: "user" <*> v .: "until_date"- -- ("left" :: Text) -> Left <$> v .: "user"+ ("left" :: Text) -> Left <$> v .: "user" ("kicked" :: Text) -> Kicked <$> v .: "user" <*> v.: "until_date" _ -> fail "Status of chat member is not defined"
Network/Telegram/API/Bot/Object/Message.hs view
@@ -1,40 +1,25 @@-module Network.Telegram.API.Bot.Object.Message- (Message (..), Payload) where+module Network.Telegram.API.Bot.Object.Message (Message (..)) where -import "aeson" Data.Aeson (FromJSON (parseJSON), object, withArray, withObject, (.:), (.=))+import "aeson" Data.Aeson (FromJSON (parseJSON), withArray, withObject, (.:)) import "aeson" Data.Aeson.Types (Object, Parser, Value) import "base" Control.Applicative (Applicative ((<*>)), Alternative (empty, (<|>))) import "base" Control.Monad (Monad ((>>=)), fail) import "base" Data.Function ((.), ($)) import "base" Data.Functor ((<$>)) import "base" Data.Foldable (Foldable (foldr))-import "base" Data.Int (Int, Int64)-import "base" Data.Maybe (Maybe (Just, Nothing))+import "base" Data.Int (Int) import "base" Text.Show (Show) import "base" Prelude ((+))-import "text" Data.Text (Text)--import qualified "text" Data.Text as T (drop, take)+import "text" Data.Text (Text, drop, take) -import Network.Telegram.API.Bot.Access (Access (access))-import Network.Telegram.API.Bot.Endpoint (Endpoint (payload, endpoint), Payload, Post, Purge) import Network.Telegram.API.Bot.Object.Chat (Chat) import Network.Telegram.API.Bot.Object.From (From)-import Network.Telegram.API.Bot.Object.Keyboard (Keyboard)-import Network.Telegram.API.Bot.Property.Identifiable- (Identifiable (identificator), Identificator) data Message = Textual Int Chat From Text | Command Int Chat From Text deriving Show -type instance Identificator Message = Int--instance Identifiable Message where- identificator (Textual i _ _ _) = i- identificator (Command i _ _ _) = i- instance FromJSON Message where parseJSON = withObject "Message" $ \v -> command v <|> textual v where @@ -56,24 +41,4 @@ _ -> fail "It's not a bot command" extract_command :: Object -> (Int, Int) -> Parser Text- extract_command v (ofs, len) = (T.take len . T.drop (ofs + 1)) <$> v .: "text"--instance Access Chat Message where- access f (Textual msg_id chat from txt) = (\chat' -> Textual msg_id chat' from txt) <$> f chat- access f (Command msg_id chat from cmd) = (\chat' -> Command msg_id chat' from cmd) <$> f chat--instance Access From Message where- access f (Textual msg_id chat from txt) = (\from' -> Textual msg_id chat from' txt) <$> f from- access f (Command msg_id chat from cmd) = (\from' -> Command msg_id chat from' cmd) <$> f from--type instance Payload (Post Message) = (Int64, Text, Maybe Keyboard)-type instance Payload (Purge Message) = (Int64, Int)--instance Endpoint (Post Message) where- payload (chat_id, text, Nothing) = object ["chat_id" .= chat_id, "text" .= text]- payload (chat_id, text, Just kb) = object ["chat_id" .= chat_id, "text" .= text, "reply_markup" .= kb]- endpoint _ = "sendMessage"--instance Endpoint (Purge Message) where- payload (chat_id, message_id) = object ["chat_id" .= chat_id, "message_id" .= message_id]- endpoint _ = "deleteMessage"+ extract_command v (ofs, len) = (take len . drop (ofs + 1)) <$> v .: "text"
Network/Telegram/API/Bot/Object/Moving.hs view
@@ -7,7 +7,6 @@ import "base" Data.Functor ((<$>)) import "base" Text.Show (Show) -import Network.Telegram.API.Bot.Access (Access (access)) import Network.Telegram.API.Bot.Object.Chat (Chat) import Network.Telegram.API.Bot.Object.From (From) @@ -21,7 +20,3 @@ joined :: Object -> Parser Moving joined v = Joined <$> v .: "chat" <*> v .: "new_chat_members"--instance Access Chat Moving where- access f (Gone chat from) = (\chat' -> Gone chat' from) <$> f chat- access f (Joined chat froms) = (\chat' -> Joined chat' froms) <$> f chat
Network/Telegram/API/Bot/Object/Notification.hs view
@@ -1,15 +1,3 @@-module Network.Telegram.API.Bot.Object.Notification (Notification, Payload) where--import "aeson" Data.Aeson (object, (.=))-import "text" Data.Text (Text)--import Network.Telegram.API.Bot.Endpoint (Endpoint (payload, endpoint), Payload, Drop)+module Network.Telegram.API.Bot.Object.Notification (Notification) where data Notification--type instance Payload (Drop Notification) = (Text, Text)--instance Endpoint (Drop Notification) where- payload (cbq_id, text) = object- ["callback_query_id" .= cbq_id, "text" .= text]- endpoint _ = "answerCallbackQuery"
Network/Telegram/API/Bot/Object/Update.hs view
@@ -8,13 +8,9 @@ import "base" Data.Int (Int) import "base" Text.Show (Show) -import Network.Telegram.API.Bot.Access (Access (access)) import Network.Telegram.API.Bot.Object.Callback (Callback)-import Network.Telegram.API.Bot.Object.Chat (Chat) import Network.Telegram.API.Bot.Object.Moving (Moving) import Network.Telegram.API.Bot.Object.Message (Message)-import Network.Telegram.API.Bot.Property.Identifiable- (Identifiable (identificator), Identificator) data Update = Query Int Callback@@ -22,13 +18,6 @@ | Incoming Int Message deriving Show -type instance Identificator Update = Int--instance Identifiable Update where- identificator (Query i _) = i- identificator (Membership i _) = i- identificator (Incoming i _) = i- instance FromJSON Update where parseJSON = withObject "Update" $ \v -> query v <|> membership v <|> incoming v where@@ -41,8 +30,3 @@ incoming :: Object -> Parser Update incoming v = Incoming <$> v .: "update_id" <*> v .: "message"--instance Access Chat Update where- access f (Incoming upd_id msg) = Incoming upd_id <$> access f msg- access f (Query upd_id cb) = Query upd_id <$> access f cb- access f (Membership upd_id mmb) = Membership upd_id <$> access f mmb
Network/Telegram/API/Bot/Property.hs view
@@ -1,3 +1,5 @@ module Network.Telegram.API.Bot.Property (module Exports) where +import Network.Telegram.API.Bot.Property.Persistable as Exports import Network.Telegram.API.Bot.Property.Identifiable as Exports+import Network.Telegram.API.Bot.Property.Accessible as Exports
+ Network/Telegram/API/Bot/Property/Accessible.hs view
@@ -0,0 +1,41 @@+module Network.Telegram.API.Bot.Property.Accessible (Accessible (..)) where++import "base" Data.Function (flip)+import "base" Data.Functor ((<$>))+import "lens" Control.Lens (Lens')++import Network.Telegram.API.Bot.Object (Object)+import Network.Telegram.API.Bot.Object.Callback (Callback (Datatext))+import Network.Telegram.API.Bot.Object.Chat (Chat)+import Network.Telegram.API.Bot.Object.From (From)+import Network.Telegram.API.Bot.Object.Message (Message (Textual, Command))+import Network.Telegram.API.Bot.Object.Moving (Moving (Gone, Joined))+import Network.Telegram.API.Bot.Object.Update (Update (Query, Membership, Incoming))++class Object source => Accessible target source where+ access :: Lens' source target++instance Accessible Chat Callback where+ access f (Datatext cq_id msg dttxt) = flip+ (Datatext cq_id) dttxt <$> access f msg++instance Accessible Chat Message where+ access f (Textual msg_id chat from txt) = (\chat' -> Textual msg_id chat' from txt) <$> f chat+ access f (Command msg_id chat from cmd) = (\chat' -> Command msg_id chat' from cmd) <$> f chat++instance Accessible Chat Moving where+ access f (Gone chat from) = (\chat' -> Gone chat' from) <$> f chat+ access f (Joined chat froms) = (\chat' -> Joined chat' froms) <$> f chat++instance Accessible Chat Update where+ access f (Incoming upd_id msg) = Incoming upd_id <$> access f msg+ access f (Query upd_id cb) = Query upd_id <$> access f cb+ access f (Membership upd_id mmb) = Membership upd_id <$> access f mmb++instance Accessible From Callback where+ access f (Datatext cq_id msg dttxt) = flip+ (Datatext cq_id) dttxt <$> access f msg++instance Accessible From Message where+ access f (Textual msg_id chat from txt) = (\from' -> Textual msg_id chat from' txt) <$> f from+ access f (Command msg_id chat from cmd) = (\from' -> Command msg_id chat from' cmd) <$> f from
Network/Telegram/API/Bot/Property/Identifiable.hs view
@@ -1,7 +1,39 @@ module Network.Telegram.API.Bot.Property.Identifiable (Identifiable (..), Identificator) where -type family Identificator a = r+import "base" Data.Int (Int, Int64) -class Identifiable a where+import Network.Telegram.API.Bot.Object (Object)+import Network.Telegram.API.Bot.Object.Chat (Chat (Private, Group, Supergroup, Channel))+import Network.Telegram.API.Bot.Object.From (From (Bot, User))+import Network.Telegram.API.Bot.Object.Message (Message (Textual, Command))+import Network.Telegram.API.Bot.Object.Update (Update (Query, Membership, Incoming))++type family Identificator o = i++class Object o => Identifiable o where {-# MINIMAL identificator #-}- identificator :: a -> Identificator a+ identificator :: o -> Identificator o++type instance Identificator Chat = Int64+type instance Identificator From = Int+type instance Identificator Message = Int+type instance Identificator Update = Int++instance Identifiable Chat where+ identificator (Private i) = i+ identificator (Group i _) = i+ identificator (Supergroup i _) = i+ identificator (Channel i _) = i++instance Identifiable From where+ identificator (Bot i _ _ _ _) = i+ identificator (User i _ _ _ _) = i++instance Identifiable Message where+ identificator (Textual i _ _ _) = i+ identificator (Command i _ _ _) = i++instance Identifiable Update where+ identificator (Query i _) = i+ identificator (Membership i _) = i+ identificator (Incoming i _) = i
+ Network/Telegram/API/Bot/Property/Persistable.hs view
@@ -0,0 +1,63 @@+module Network.Telegram.API.Bot.Property.Persistable (Persistable (..), Payload, Capacity (..)) 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 (Just, Nothing), 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)+import Network.Telegram.API.Bot.Object.Keyboard (Keyboard)+import Network.Telegram.API.Bot.Object.Message (Message)+import Network.Telegram.API.Bot.Object.Notification (Notification)++data Capacity = Post | Edit | Purge++type family Payload (c :: Capacity) o = r | r -> c o++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++type instance Payload 'Edit Keyboard = (Int64, Int, Keyboard)+type instance Payload 'Post Message = (Int64, Text, Maybe Keyboard)+type instance Payload 'Purge Message = (Int64, Int)+type instance Payload 'Post Notification = (Text, Text)++instance Persistable 'Edit Keyboard where+ payload (chat_id, message_id, reply_markup) = object+ ["chat_id" .= chat_id, "message_id" .= message_id, "reply_markup" .= reply_markup]+ endpoint _ = "editMessageReplyMarkup"++instance Persistable 'Post Message where+ payload (chat_id, text, Nothing) = object ["chat_id" .= chat_id, "text" .= text]+ payload (chat_id, text, Just kb) = object ["chat_id" .= chat_id, "text" .= text, "reply_markup" .= kb]+ endpoint _ = "sendMessage"++instance Persistable 'Purge Message where+ payload (chat_id, message_id) = object ["chat_id" .= chat_id, "message_id" .= message_id]+ endpoint _ = "deleteMessage"++instance Persistable 'Post Notification where+ payload (cbq_id, text) = object ["callback_query_id" .= cbq_id, "text" .= text]+ endpoint _ = "answerCallbackQuery"
telega.cabal view
@@ -1,5 +1,5 @@ name: telega-version: 0.1.4+version: 0.1.5 synopsis: Telegram Bot API binding description: High-level bindings, typed entities, inline mode only homepage: https://github.com/iokasimov/telega@@ -21,8 +21,6 @@ exposed-modules: Network.Telegram.API.Bot Network.Telegram.API.Bot.Core- Network.Telegram.API.Bot.Access- Network.Telegram.API.Bot.Endpoint Network.Telegram.API.Bot.Object Network.Telegram.API.Bot.Object.Chat Network.Telegram.API.Bot.Object.From@@ -35,12 +33,12 @@ Network.Telegram.API.Bot.Object.Notification Network.Telegram.API.Bot.Object.Update Network.Telegram.API.Bot.Property+ Network.Telegram.API.Bot.Property.Accessible Network.Telegram.API.Bot.Property.Identifiable- other-modules:- Network.Telegram.API.Bot.Internal+ Network.Telegram.API.Bot.Property.Persistable build-depends: base == 4.*, transformers, lens, aeson, text, time, http-client, wreq- default-extensions: DataKinds, LambdaCase, OverloadedStrings, NoImplicitPrelude,- FlexibleInstances, MultiParamTypeClasses, PackageImports, ScopedTypeVariables,+ default-extensions: DataKinds, LambdaCase, OverloadedStrings, NoImplicitPrelude, PackageImports,+ AllowAmbiguousTypes, MultiParamTypeClasses, ScopedTypeVariables, UndecidableInstances, UndecidableSuperClasses, TypeApplications, TypeFamilies, TypeFamilyDependencies, TypeOperators default-language: Haskell2010 ghc-options: -Wall -fno-warn-tabs