telega 0.2.2 → 0.2.3
raw patch · 14 files changed
+183/−91 lines, 14 filesdep −tagged
Dependencies removed: tagged
Files
- CHANGELOG.md +10/−0
- Network/API/Telegram/Bot/Object/Member.hs +0/−1
- Network/API/Telegram/Bot/Object/Sender.hs +0/−1
- Network/API/Telegram/Bot/Object/Update/Callback.hs +14/−2
- Network/API/Telegram/Bot/Object/Update/Message.hs +107/−5
- Network/API/Telegram/Bot/Object/Update/Message/Content/File.hs +21/−15
- Network/API/Telegram/Bot/Object/Update/Message/Content/File/Audio.hs +6/−11
- Network/API/Telegram/Bot/Object/Update/Message/Content/File/Document.hs +5/−9
- Network/API/Telegram/Bot/Object/Update/Message/Content/File/Video.hs +5/−11
- Network/API/Telegram/Bot/Object/Update/Message/Content/File/Voice.hs +5/−8
- Network/API/Telegram/Bot/Object/Update/Message/Content/Poll.hs +0/−1
- Network/API/Telegram/Bot/Object/Update/Message/Keyboard.hs +0/−1
- Network/API/Telegram/Bot/Property/Persistable.hs +8/−24
- telega.cabal +2/−2
CHANGELOG.md view
@@ -99,3 +99,13 @@ * Rename `Message` constructors to use old name as `Capacity` constructors * Define `Persistable` instance for `Reply`-ing messages * Temporary delete old `Persistable` instances++# 0.2.3+* Define `Persistable` instance for `Send (Text :&: Keyboard)`+* Move modified versions of `Capacity` and `Silently` datatypes to `Message` module+* Define `Persistable` instances for `Edit` and `Delete` messages+* Add `persist_` method in `Persistable` that not trying to decode JSON response+* Extract file ID from `File` datatypes to use these datatypes for sending as messages+* Define `Persistable` instance for dropping `Notification`s on pressing inline buttons+* Remove thumb field from `Audio`, `Document`, `Video` and `Voice` datatypes+* Define `Persistable` instances for `Audio`, `Document`, `Video` and `Voice` datatypes
Network/API/Telegram/Bot/Object/Member.hs view
@@ -11,7 +11,6 @@ import "base" Data.Function (($)) import "base" Data.Functor ((<$>)) import "base" Text.Show (Show)-import "tagged" Data.Tagged (Tagged, untag) import "text" Data.Text (Text) import "time" Data.Time.Clock.POSIX (POSIXTime)
Network/API/Telegram/Bot/Object/Sender.hs view
@@ -12,7 +12,6 @@ import "base" Data.Maybe (Maybe) import "base" Text.Show (Show) import "lens" Control.Lens (Lens')-import "tagged" Data.Tagged (Tagged) import "text" Data.Text (Text) import Network.API.Telegram.Bot.Property.Identifiable (Identifiable (Identificator, ident))
Network/API/Telegram/Bot/Object/Update/Callback.hs view
@@ -1,18 +1,22 @@-module Network.API.Telegram.Bot.Object.Update.Callback (Callback (..), module Exports) where+module Network.API.Telegram.Bot.Object.Update.Callback+ (module Exports, Callback (..), Trigger (..)) 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.Function (flip, ($)) import "base" Data.Functor ((<$>))+import "base" Data.Semigroup ((<>)) import "base" Text.Show (Show) import "text" Data.Text (Text)+import "unordered-containers" Data.HashMap.Strict (singleton) import Network.API.Telegram.Bot.Object.Update.Message (Message) import Network.API.Telegram.Bot.Object.Update.Message.Origin (Origin) 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, payload, endpoint)) data Callback = Datatext Text Message Text deriving Show @@ -27,3 +31,11 @@ instance Identifiable Callback where type instance Identificator Callback = Text ident (Datatext i _ _) = i++data Trigger a = Trigger Text Text++instance Persistable (Trigger Notification) where+ type instance Payload (Trigger Notification) = Trigger Notification+ payload (Trigger cbq_id text) = singleton "text" (toJSON text)+ <> singleton "callback_query_id" (toJSON cbq_id)+ endpoint _ = "answerCallbackQuery"
Network/API/Telegram/Bot/Object/Update/Message.hs view
@@ -1,4 +1,5 @@-module Network.API.Telegram.Bot.Object.Update.Message (Message (..), module Exports) where+module Network.API.Telegram.Bot.Object.Update.Message (module Exports, Message (..)+ , Send (..), Reply (..), Forward (..), Edit (..), Delete (..), Silently (..)) where import Network.API.Telegram.Bot.Object.Update.Message.Content as Exports import Network.API.Telegram.Bot.Object.Update.Message.Keyboard as Exports@@ -8,6 +9,7 @@ import "aeson" Data.Aeson.Types (Object, Parser) import "base" Control.Applicative (Applicative ((<*>)), Alternative ((<|>))) import "base" Control.Monad (Monad ((>>=)), fail)+import "base" Data.Bool (Bool (True)) import "base" Data.Function (($)) import "base" Data.Functor ((<$>)) import "base" Data.Int (Int, Int64)@@ -21,7 +23,7 @@ import Network.API.Telegram.Bot.Object.Update.Message.Origin (Origin (Private, Group, Supergroup, Channel)) 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, payload, endpoint), Capacity (Send))+import Network.API.Telegram.Bot.Property.Persistable (Persistable (Payload, payload, endpoint)) data Message = Direct Int Origin Content@@ -75,7 +77,107 @@ ident (Forwarded i _ _) = i ident (Replied i _ _ _) = i -instance Persistable ('Send Message) where- type instance Payload ('Send Message) = (Int64 :&: Text)- payload (chat_id :&: text) = singleton "chat_id" (toJSON chat_id) <> singleton "text" (toJSON text)+data Forward a = Forward Int Int64 Int64++instance Persistable (Forward Message) where+ type instance Payload (Forward Message) = Forward Message+ payload (Forward message_id from_chat_id to_chat_id) = singleton "message_id" (toJSON message_id)+ <> singleton "from_chat_id" (toJSON from_chat_id) <> singleton "chat_id" (toJSON to_chat_id)+ endpoint _ = "forwardMessage"++data Send a = Send Int64 a++instance Persistable (Send Text) where+ type instance Payload (Send Text) = Send Text+ payload (Send chat_id text) = singleton "chat_id" (toJSON chat_id) <> singleton "text" (toJSON text) endpoint _ = "sendMessage"++instance Persistable (Send (Text :&: Keyboard)) where+ type instance Payload (Send (Text :&: Keyboard)) = Send (Text :&: Keyboard)+ payload (Send chat_id (text :&: reply_markup)) = singleton "chat_id" (toJSON chat_id)+ <> singleton "text" (toJSON text) <> singleton "reply_markup" (toJSON reply_markup)+ endpoint _ = "sendMessage"++instance Persistable (Send Audio) where+ type instance Payload (Send Audio) = Send Audio+ payload (Send chat_id (Audio duration performer title mime_type file_size)) =+ singleton "chat_id" (toJSON chat_id) <> singleton "duration" (toJSON duration)+ <> singleton "performer" (toJSON performer) <> singleton "title" (toJSON title)+ <> singleton "mime_type" (toJSON mime_type) <> singleton "file_size" (toJSON file_size)+ endpoint _ = "sendAudio"++instance Persistable (Send Document) where+ type instance Payload (Send Document) = Send Document+ payload (Send chat_id (Document file_name mime_type file_size)) =+ singleton "chat_id" (toJSON chat_id) <> singleton "file_name" (toJSON file_name)+ <> singleton "mime_type" (toJSON mime_type) <> singleton "file_size" (toJSON file_size)+ endpoint _ = "sendDocument"++instance Persistable (Send Video) where+ type instance Payload (Send Video) = Send Video+ payload (Send chat_id (Video width height duration mime_type file_size)) =+ singleton "chat_id" (toJSON chat_id) <> singleton "duration" (toJSON duration)+ <> singleton "width" (toJSON width) <> singleton "height" (toJSON height)+ <> singleton "mime_type" (toJSON mime_type) <> singleton "file_size" (toJSON file_size)+ endpoint _ = "sendVideo"++instance Persistable (Send Voice) where+ type instance Payload (Send Voice) = Send Voice+ payload (Send chat_id (Voice duration mime_type file_size)) =+ singleton "chat_id" (toJSON chat_id) <> singleton "duration" (toJSON duration)+ <> singleton "mime_type" (toJSON mime_type) <> singleton "file_size" (toJSON file_size)+ endpoint _ = "sendVoice"++data Reply a = Reply Int a++instance Persistable (Send a) => Persistable (Reply a) where+ type Payload (Reply a) = Reply (Payload (Send a))+ payload (Reply reply_to_message_id x) = payload x <> singleton+ "reply_to_message_id" (toJSON reply_to_message_id)+ endpoint (Reply _ x) = endpoint x++data Edit b = Edit Int64 Int b++instance Persistable (Edit Text) where+ type Payload (Edit Text) = Edit Text+ payload (Edit chat_id message_id text) = singleton "chat_id" (toJSON chat_id)+ <> singleton "message_id" (toJSON message_id) <> singleton "text" (toJSON text)+ endpoint _ = "editMessageText"++instance Persistable (Edit Keyboard) where+ type Payload (Edit Keyboard) = Edit Keyboard+ payload (Edit chat_id message_id reply_markup) = singleton "chat_id" (toJSON chat_id)+ <> singleton "message_id" (toJSON message_id) <> singleton "reply_markup" (toJSON reply_markup)+ endpoint _ = "editMessageText"++instance Persistable (Edit (Text :&: Keyboard)) where+ type Payload (Edit (Text :&: Keyboard)) = Edit (Text :&: Keyboard)+ payload (Edit chat_id message_id (text :&: reply_markup)) =+ singleton "chat_id" (toJSON chat_id) <> singleton "message_id" (toJSON message_id)+ <> singleton "text" (toJSON text) <> singleton "reply_markup" (toJSON reply_markup)+ endpoint _ = "editMessageText"++data Delete a = Delete Int64 Int++instance Persistable (Delete Message) where+ type Payload (Delete Message) = Delete Message+ payload (Delete chat_id message_id) = singleton "chat_id" (toJSON chat_id)+ <> singleton "message_id" (toJSON message_id)+ endpoint _ = "deleteMessage"++data Silently (todo :: * -> *) a = Silently a++instance Persistable (Forward obj) => Persistable (Silently Forward obj) where+ type Payload (Silently Forward obj) = Silently Forward (Payload (Forward obj))+ payload (Silently x) = payload x <> singleton "disable_notification" (toJSON True)+ endpoint (Silently x) = endpoint x++instance Persistable (Send obj) => Persistable (Silently Send obj) where+ type Payload (Silently Send obj) = Silently Send (Payload (Send obj))+ payload (Silently x) = payload x <> singleton "disable_notification" (toJSON True)+ endpoint (Silently x) = endpoint x++instance Persistable (Reply obj) => Persistable (Silently Reply obj) where+ type Payload (Silently Reply obj) = Silently Reply (Payload (Reply obj))+ payload (Silently x) = payload x <> singleton "disable_notification" (toJSON True)+ endpoint (Silently x) = endpoint x
Network/API/Telegram/Bot/Object/Update/Message/Content/File.hs view
@@ -7,35 +7,41 @@ import Network.API.Telegram.Bot.Object.Update.Message.Content.File.Voice as Exports import "aeson" Data.Aeson (FromJSON (parseJSON), withObject, (.:))-import "aeson" Data.Aeson.Types (Object, Parser)-import "base" Control.Applicative ((<|>))+import "aeson" Data.Aeson.Types (Object, Parser, Value)+import "base" Control.Applicative ((<*>), (<|>))+import "base" Control.Monad ((>>=)) import "base" Data.Function (($)) import "base" Data.Functor ((<$>))+import "base" Data.String (String) import "base" Text.Show (Show)+import "text" Data.Text (Text) data File- = Audiofile Audio- | Videofile Video- | General Document- | Voicerecord Voice+ = Audiofile Text Audio+ | Videofile Text Video+ | General Text Document+ | Voicerecord Text Voice | Photo [Size] deriving Show instance FromJSON File where- parseJSON = withObject "Message" $ \v -> photo v <|> document v- <|> audio v <|> video v <|> voice v where+ parseJSON = withObject "Message" $ \v ->+ photo v <|> document v <|> audio v <|> video v <|> voice v where + photo :: Object -> Parser File+ photo v = Photo <$> v .: "photo"+ audio :: Object -> Parser File- audio v = Audiofile <$> v .: "audio"+ audio v = Audiofile <$> (v .: "audio" >>= file_id "Audio") <*> v .: "audio" document :: Object -> Parser File- document v = General <$> v .: "document"-- photo :: Object -> Parser File- photo v = Photo <$> v .: "photo"+ document v = General <$> (v .: "document" >>= file_id "Document") <*> v .: "document" video :: Object -> Parser File- video v = Videofile <$> v .: "video"+ video v = Videofile <$> (v .: "video" >>= file_id "Video") <*> v .: "video" voice :: Object -> Parser File- voice v = Voicerecord <$> v .: "voice"+ voice v = Voicerecord <$> (v .: "voice" >>= file_id "Voice") <*> v .: "voice"++ file_id :: String -> Value -> Parser Text+ file_id otype = withObject otype $ \f -> f .: "file_id"
Network/API/Telegram/Bot/Object/Update/Message/Content/File/Audio.hs view
@@ -1,23 +1,18 @@ module Network.API.Telegram.Bot.Object.Update.Message.Content.File.Audio (Audio (..)) where -import "aeson" Data.Aeson (FromJSON (parseJSON)- , object, withObject, (.:), (.:?), (.=))+import "aeson" Data.Aeson (FromJSON (parseJSON), withObject, (.:), (.:?)) import "base" Control.Applicative ((<*>))-import "base" Data.Bool (Bool (True, False))-import "base" Data.Int (Int, Int64)+import "base" Data.Int (Int) import "base" Data.Maybe (Maybe) import "base" Data.Function (($)) import "base" Data.Functor ((<$>)) import "base" Text.Show (Show)-import "tagged" Data.Tagged (Tagged, untag) import "text" Data.Text (Text) -import Network.API.Telegram.Bot.Object.Update.Message.Content.File.Size (Size)--data Audio = Audio Text Int (Maybe Text) (Maybe Text) (Maybe Text) (Maybe Int) (Maybe Size)+data Audio = Audio Int (Maybe Text) (Maybe Text) (Maybe Text) (Maybe Int) deriving Show instance FromJSON Audio where- parseJSON = withObject "Audio" $ \v -> Audio <$> v .: "file_id"- <*> v .: "duration" <*> v .:? "performer" <*> v .:? "title"- <*> v .:? "mime_type" <*> v .:? "file_size" <*> v .:? "thumb"+ parseJSON = withObject "Audio" $ \v -> Audio+ <$> v .: "duration" <*> v .:? "performer" <*> v .:? "title"+ <*> v .:? "mime_type" <*> v .:? "file_size"
Network/API/Telegram/Bot/Object/Update/Message/Content/File/Document.hs view
@@ -1,21 +1,17 @@ module Network.API.Telegram.Bot.Object.Update.Message.Content.File.Document (Document (..)) where -import "aeson" Data.Aeson (FromJSON (parseJSON), withObject, object, (.:), (.:?), (.=))+import "aeson" Data.Aeson (FromJSON (parseJSON), withObject, (.:?)) import "base" Control.Applicative ((<*>))-import "base" Data.Bool (Bool (True, False))-import "base" Data.Int (Int, Int64)+import "base" Data.Int (Int) import "base" Data.Maybe (Maybe) import "base" Data.Function (($)) import "base" Data.Functor ((<$>)) import "base" Text.Show (Show)-import "tagged" Data.Tagged (Tagged, untag) import "text" Data.Text (Text) -import Network.API.Telegram.Bot.Object.Update.Message.Content.File.Size (Size)--data Document = Document Text (Maybe Size) (Maybe Text) (Maybe Text) (Maybe Int)+data Document = Document (Maybe Text) (Maybe Text) (Maybe Int) deriving Show instance FromJSON Document where- parseJSON = withObject "Document" $ \v -> Document <$> v .: "file_id"- <*> v .:? "thumb" <*> v .:? "file_name" <*> v .:? "mime_type" <*> v .:? "file_size"+ parseJSON = withObject "Document" $ \v -> Document+ <$> v .:? "file_name" <*> v .:? "mime_type" <*> v .:? "file_size"
Network/API/Telegram/Bot/Object/Update/Message/Content/File/Video.hs view
@@ -1,23 +1,17 @@ module Network.API.Telegram.Bot.Object.Update.Message.Content.File.Video (Video (..)) where -import "aeson" Data.Aeson (FromJSON (parseJSON)- , object, withObject, (.:), (.:?), (.=))+import "aeson" Data.Aeson (FromJSON (parseJSON), withObject, (.:), (.:?)) import "base" Control.Applicative ((<*>))-import "base" Data.Bool (Bool (True, False))-import "base" Data.Int (Int, Int64)+import "base" Data.Int (Int) import "base" Data.Maybe (Maybe) import "base" Data.Function (($)) import "base" Data.Functor ((<$>)) import "base" Text.Show (Show)-import "tagged" Data.Tagged (Tagged, untag) import "text" Data.Text (Text) -import Network.API.Telegram.Bot.Object.Update.Message.Content.File.Size (Size)--data Video = Video Text Int Int Int (Maybe Size) (Maybe Text) (Maybe Int)+data Video = Video Int Int Int (Maybe Text) (Maybe Int) deriving Show instance FromJSON Video where- parseJSON = withObject "Video" $ \v -> Video <$> v .: "file_id"- <*> v .: "width" <*> v .: "height" <*> v .: "duration"- <*> v .:? "thumb" <*> v .:? "mime_type" <*> v .:? "file_size"+ parseJSON = withObject "Video" $ \v -> Video <$> v .: "width" <*> v .: "height"+ <*> v .: "duration" <*> v .:? "mime_type" <*> v .:? "file_size"
Network/API/Telegram/Bot/Object/Update/Message/Content/File/Voice.hs view
@@ -1,19 +1,16 @@ module Network.API.Telegram.Bot.Object.Update.Message.Content.File.Voice (Voice (..)) where -import "aeson" Data.Aeson (FromJSON (parseJSON)- , object, withObject, (.:), (.:?), (.=))+import "aeson" Data.Aeson (FromJSON (parseJSON), withObject, (.:), (.:?)) import "base" Control.Applicative ((<*>))-import "base" Data.Bool (Bool (True, False))-import "base" Data.Int (Int, Int64)+import "base" Data.Int (Int) import "base" Data.Maybe (Maybe) import "base" Data.Function (($)) import "base" Data.Functor ((<$>)) import "base" Text.Show (Show)-import "tagged" Data.Tagged (Tagged, untag) import "text" Data.Text (Text) -data Voice = Voice Text Int (Maybe Text) (Maybe Int) deriving Show+data Voice = Voice Int (Maybe Text) (Maybe Int) deriving Show instance FromJSON Voice where- parseJSON = withObject "Voice" $ \v -> Voice <$> v .: "file_id"- <*> v .: "duration" <*> v .:? "mime_type" <*> v .:? "file_size"+ parseJSON = withObject "Voice" $ \v -> Voice <$>+ v .: "duration" <*> v .:? "mime_type" <*> v .:? "file_size"
Network/API/Telegram/Bot/Object/Update/Message/Content/Poll.hs view
@@ -11,7 +11,6 @@ import "base" Data.Functor ((<$>)) import "base" Data.Int (Int, Int64) import "base" Text.Show (Show)-import "tagged" Data.Tagged (Tagged, untag) import "text" Data.Text (Text) data Poll
Network/API/Telegram/Bot/Object/Update/Message/Keyboard.hs view
@@ -8,7 +8,6 @@ import "base" Data.Int (Int, Int64) import "base" Data.Semigroup ((<>)) import "base" Text.Show (Show)-import "tagged" Data.Tagged (Tagged, untag) import "text" Data.Text (Text) import "unordered-containers" Data.HashMap.Strict (singleton)
Network/API/Telegram/Bot/Property/Persistable.hs view
@@ -1,15 +1,12 @@-module Network.API.Telegram.Bot.Property.Persistable- (Persistable (..), Capacity (..), Silenlty (..)) where+module Network.API.Telegram.Bot.Property.Persistable (Persistable (..)) where -import "aeson" Data.Aeson (FromJSON, ToJSON (toJSON), Value (Object), Object, decode)+import "aeson" Data.Aeson (FromJSON, Object, Value (Object), decode) import "base" Control.Exception (try)-import "base" Control.Monad (Monad ((>>=)), join)-import "base" Data.Bool (Bool (True))+import "base" Control.Monad (join, (>>=)) import "base" Data.Function (flip, (.), ($))-import "base" Data.Functor (Functor (fmap), (<$>))-import "base" Data.Int (Int)+import "base" Data.Functor (fmap, (<$>)) import "base" Data.Maybe (fromJust)-import "base" Data.Semigroup (Semigroup ((<>)))+import "base" Data.Semigroup ((<>)) import "base" Data.String (String) import "base" Data.Tuple (snd) import "http-client" Network.HTTP.Client (Response (responseBody))@@ -17,21 +14,16 @@ import "transformers" Control.Monad.Trans.Class (lift) import "transformers" Control.Monad.Trans.Except (ExceptT (ExceptT)) import "transformers" Control.Monad.Trans.Reader (ask)-import "unordered-containers" Data.HashMap.Strict (singleton)-import "with" Data.With (type (:&:)((:&:))) import "wreq" Network.Wreq.Session (post) import Network.API.Telegram.Bot.Core (Telegram, Token (Token), Ok, result) -data Capacity object = Send object | Reply object--data Silenlty (capacity :: * -> Capacity *) object = Silenlty- 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 @@ -40,13 +32,5 @@ . fmap (fromJust . join . fmap result . decode @(Ok a) . responseBody) . flip (post session) p $ "https://api.telegram.org/" <> unpack token <> "/" <> e -instance Persistable ('Send obj) => Persistable (Silenlty 'Send obj) where- type Payload (Silenlty 'Send obj) = (Silenlty 'Send obj :&: Payload ('Send obj))- payload (_ :&: x) = payload x <> singleton "disable_notification" (toJSON True)- endpoint (_ :&: x) = endpoint x--instance Persistable ('Send obj) => Persistable ('Reply obj) where- type Payload ('Reply obj) = (Int :&: Payload ('Send obj))- payload (reply_to_message_id :&: x) = payload x <> singleton- "reply_to_message_id" (toJSON reply_to_message_id)- endpoint (_ :&: x) = endpoint x+ persist_ :: Payload action -> Telegram e ()+ persist_ x = persist @_ @() x where
telega.cabal view
@@ -1,5 +1,5 @@ name: telega-version: 0.2.2+version: 0.2.3 synopsis: Telegram Bot API binding description: High-level bindings, typed entities, inline mode only homepage: https://github.com/iokasimov/telega@@ -50,7 +50,7 @@ Network.API.Telegram.Bot.Property.Accessible Network.API.Telegram.Bot.Property.Identifiable Network.API.Telegram.Bot.Property.Persistable- build-depends: base == 4.*, transformers, tagged, with, lens, aeson, text, unordered-containers, time, http-client, wreq+ build-depends: base == 4.*, transformers, with, lens, aeson, text, unordered-containers, time, http-client, wreq default-extensions: DataKinds, LambdaCase, OverloadedStrings, NoImplicitPrelude, PackageImports, ViewPatterns, AllowAmbiguousTypes, MultiParamTypeClasses, ScopedTypeVariables, UndecidableInstances, UndecidableSuperClasses, FlexibleInstances, TypeApplications, TypeFamilies, TypeFamilyDependencies, TypeOperators, PolyKinds