packages feed

telegram-api 0.6.2.0 → 0.6.3.0

raw patch · 8 files changed

+170/−39 lines, 8 filesdep ~aesondep ~servantdep ~servant-clientbinary-added

Dependency ranges changed: aeson, servant, servant-client

Files

CHANGELOG.md view
@@ -1,3 +1,17 @@+## 0.6.3.0++* New fields *gif_duration* in `InlineQueryResultGif` and *mpeg4_duration* in `InlineQueryResultMpeg4Gif`.+* Replaced the field *new_chat_member* in `Message` with *new_chat_members* (the old field will still be available for a while for compatibility purposes).+* The `User` object now may have a *language_code* field that contains the IETF language tag of the user's language.+* Added the `sendVideoNote` method, the new field *video_note* to `Message`, the fields `RecordVideoNote* or *UploadVideoNote* to `sendChatAction`.+* Added a new type of button, the pay button to `InlineKeyboardButton`.+* Updated dependencies++## 0.6.2.0++* Added new kinds of updates, *shipping_query* and *pre_checkout_query*, and new types of message content, *invoice* and *successful_payment*.+* Added new methods for payments: `sendInvoiceM`, `answerShippingQueryM`, and `answerPreCheckoutQueryM`.+ ## 0.6.1.1  Bugfixes:
README.md view
@@ -13,7 +13,7 @@ Inline mode is supported. Uploading stickers, documents, video, etc is not supported yet, but you can send items which are already uploaded on the Telegram servers. -**Support of [Bot-2.0 API][bot-2.0]**+**Support of [Bot-3.0 API][bot-3.0]**  ## Usage @@ -164,4 +164,4 @@ [telegram-bot-api]: https://core.telegram.org/bots/api [servant]: https://haskell-servant.github.io/ [hspec-args]: https://hspec.github.io/running-specs.html-[bot-2.0]: https://core.telegram.org/bots/2-0-intro+[bot-3.0]: https://core.telegram.org/bots/api
src/Web/Telegram/API/Bot/API/Messages.hs view
@@ -32,6 +32,10 @@   , uploadVoiceM   , sendVoice   , sendVoiceM+  , uploadVideoNote+  , uploadVideoNoteM+  , sendVideoNote+  , sendVideoNoteM   , sendLocation   , sendLocationM   , sendVenue@@ -102,6 +106,12 @@     :<|> TelegramToken :> "sendVoice"          :> ReqBody '[JSON] (SendVoiceRequest Text)          :> Post '[JSON] MessageResponse+    :<|> TelegramToken :> "sendVideoNote"+         :> MultipartFormDataReqBody (SendVideoNoteRequest FileUpload)+         :> Post '[JSON] MessageResponse+    :<|> TelegramToken :> "sendVideoNote"+         :> ReqBody '[JSON] (SendVideoNoteRequest Text)+         :> Post '[JSON] MessageResponse     :<|> TelegramToken :> "sendLocation"          :> ReqBody '[JSON] SendLocationRequest          :> Post '[JSON] MessageResponse@@ -136,6 +146,8 @@ sendVideo_                 :: Token -> SendVideoRequest Text -> ClientM MessageResponse uploadVoice_               :: Token -> SendVoiceRequest FileUpload -> ClientM MessageResponse sendVoice_                 :: Token -> SendVoiceRequest Text -> ClientM MessageResponse+uploadVideoNote_           :: Token -> SendVideoNoteRequest FileUpload -> ClientM MessageResponse+sendVideoNote_             :: Token -> SendVideoNoteRequest Text -> ClientM MessageResponse sendLocation_              :: Token -> SendLocationRequest -> ClientM MessageResponse sendVenue_                 :: Token -> SendVenueRequest-> ClientM MessageResponse sendContact_               :: Token -> SendContactRequest -> ClientM MessageResponse@@ -155,6 +167,8 @@   :<|> sendVideo_   :<|> uploadVoice_   :<|> sendVoice_+  :<|> uploadVideoNote_+  :<|> sendVideoNote_   :<|> sendLocation_   :<|> sendVenue_   :<|> sendContact_@@ -277,6 +291,22 @@ -- | See 'sendVoice' sendVoiceM :: SendVoiceRequest Text -> TelegramClient MessageResponse sendVoiceM = run_ sendVoice_++-- | As of v.4.0, Telegram clients support rounded square mp4 videos of up to 1 minute long. Use this method to send video messages. On success, the sent Message is returned.+uploadVideoNote :: Token -> SendVideoNoteRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse)+uploadVideoNote = runM uploadVideoNoteM++-- | See 'uploadVideoNote'+uploadVideoNoteM :: SendVideoNoteRequest FileUpload -> TelegramClient MessageResponse+uploadVideoNoteM = run_ uploadVideoNote_++-- | As of v.4.0, Telegram clients support rounded square mp4 videos of up to 1 minute long. Use this method to send video messages. On success, the sent Message is returned.+sendVideoNote :: Token -> SendVideoNoteRequest Text -> Manager -> IO (Either ServantError MessageResponse)+sendVideoNote = runM sendVideoNoteM++-- | See 'sendVoice'+sendVideoNoteM :: SendVideoNoteRequest Text -> TelegramClient MessageResponse+sendVideoNoteM = run_ sendVideoNote_  -- | Use this method to send point on the map. On success, the sent 'Message' is returned. sendLocation :: Token -> SendLocationRequest -> Manager -> IO (Either ServantError MessageResponse)
src/Web/Telegram/API/Bot/Data.hs view
@@ -6,6 +6,7 @@ module Web.Telegram.API.Bot.Data     ( -- * Types       User                          (..)+    , LanguageCode                  (..)     , ChatMember                    (..)     , Chat                          (..)     , Message                       (..)@@ -18,6 +19,7 @@     , Sticker                       (..)     , Video                         (..)     , Voice                         (..)+    , VideoNote                     (..)     , Venue                         (..)     , Contact                       (..)     , Location                      (..)@@ -86,10 +88,11 @@ -- | This object represents a Telegram user or bot. data User = User   {-    user_id         :: Int        -- ^ Unique identifier for this user or bot-  , user_first_name :: Text       -- ^ User‘s or bot’s first name-  , user_last_name  :: Maybe Text -- ^ User‘s or bot’s last name-  , user_username   :: Maybe Text -- ^ User‘s or bot’s username+    user_id            :: Int        -- ^ Unique identifier for this user or bot+  , user_first_name    :: Text       -- ^ User‘s or bot’s first name+  , user_last_name     :: Maybe Text -- ^ User‘s or bot’s last name+  , user_username      :: Maybe Text -- ^ User‘s or bot’s username+  , user_language_code :: Maybe LanguageCode   } deriving (Show, Generic)  instance ToJSON User where@@ -98,6 +101,31 @@ instance FromJSON User where   parseJSON = parseJsonDrop 5 +newtype LanguageCode = LanguageCode Text+  deriving (Show, Eq, Ord)++instance ToJSON LanguageCode where+  toJSON (LanguageCode code) = toJSON code++instance FromJSON LanguageCode where+  parseJSON (String code) = pure $ LanguageCode code+  parseJSON _ = fail "Unable to parse LanguageCode"++data VideoNote = VideoNote+  {+    vid_note_file_id   :: Text -- ^ Unique identifier for this file+  , vid_note_length    :: Int -- ^ Video width and height as defined by sender+  , vid_note_duration  :: Int -- ^ Duration of the video in seconds as defined by sender+  , vid_note_thumb     :: Maybe PhotoSize -- ^ Video thumbnail+  , vid_note_file_size :: Maybe Int -- ^ File size+  } deriving (Show, Generic)++instance ToJSON VideoNote where+  toJSON = toJsonDrop 9++instance FromJSON VideoNote where+  parseJSON = parseJsonDrop 9+ -- | This object represents a phone contact. data Contact = Contact   {@@ -409,6 +437,7 @@   , iq_res_caption               :: Maybe Text -- ^ Caption of the GIF file to be sent, 0-200 characters   , iq_res_reply_markup          :: Maybe InlineKeyboardMarkup -- ^ Inline keyboard attached to the message   , iq_res_input_message_content :: Maybe InputMessageContent -- ^ Content of the message to be sent instead of the GIF animation+  , iq_res_gif_duration          :: Maybe Int -- ^ Duration of the GIF   }   -- | Represents a link to a video animation (H.264/MPEG-4 AVC video without sound). By default, this animated MPEG-4 file will be sent by the user with optional caption. Alternatively, you can provide message_text to send it instead of the animation.   | InlineQueryResultMpeg4Gif@@ -422,6 +451,7 @@   , iq_res_caption               :: Maybe Text -- ^ Caption of the MPEG-4 file to be sent, 0-200 characters   , iq_res_reply_markup          :: Maybe InlineKeyboardMarkup -- ^ Inline keyboard attached to the message   , iq_res_input_message_content :: Maybe InputMessageContent -- ^ Content of the message to be sent instead of the video animation+  , iq_res_mpeg4_duration        :: Maybe Int -- ^ Video duration   }   -- | Represents link to a page containing an embedded video player or a video file.   | InlineQueryResultVideo@@ -635,10 +665,10 @@ inlineQueryResultPhoto id photoUrl thumbUlr = InlineQueryResultPhoto id photoUrl (Just thumbUlr) Nothing Nothing Nothing Nothing Nothing Nothing Nothing  inlineQueryResultGif :: Text -> Text -> Text -> InlineQueryResult-inlineQueryResultGif id gifUrl thumbUrl = InlineQueryResultGif id gifUrl Nothing Nothing (Just thumbUrl) Nothing Nothing Nothing Nothing+inlineQueryResultGif id gifUrl thumbUrl = InlineQueryResultGif id gifUrl Nothing Nothing (Just thumbUrl) Nothing Nothing Nothing Nothing Nothing  inlineQueryResultMpeg4Gif :: Text -> Text -> Text -> InlineQueryResult-inlineQueryResultMpeg4Gif id mpeg4Url thumbUrl = InlineQueryResultMpeg4Gif id mpeg4Url Nothing Nothing (Just thumbUrl) Nothing Nothing Nothing Nothing+inlineQueryResultMpeg4Gif id mpeg4Url thumbUrl = InlineQueryResultMpeg4Gif id mpeg4Url Nothing Nothing (Just thumbUrl) Nothing Nothing Nothing Nothing Nothing  inlineQueryResultVideo :: Text -> Text -> Text -> Text -> Text -> InlineQueryResult inlineQueryResultVideo id videoUrl mimeType thumbUrl title = InlineQueryResultVideo id videoUrl mimeType (Just thumbUrl) (Just title) Nothing Nothing Nothing Nothing Nothing Nothing Nothing@@ -695,12 +725,13 @@  data InlineKeyboardButton = InlineKeyboardButton   {-    ikb_text                             :: Text-  , ikb_url                              :: Maybe Text-  , ikb_callback_data                    :: Maybe Text-  , ikb_switch_inline_query              :: Maybe Text-  , ikb_callback_game                    :: Maybe CallbackGame+    ikb_text                             :: Text -- ^ Label text on the button+  , ikb_url                              :: Maybe Text -- ^ HTTP url to be opened when button is pressed+  , ikb_callback_data                    :: Maybe Text -- ^ Data to be sent in a callback query to the bot when button is pressed, 1-64 bytes+  , ikb_switch_inline_query              :: Maybe Text -- ^  If set, pressing the button will prompt the user to select one of their chats, open that chat and insert the bot‘s username and the specified inline query in the input field. Can be empty, in which case just the bot’s username will be inserted.+  , ikb_callback_game                    :: Maybe CallbackGame -- ^  Description of the game that will be launched when the user presses the button. NOTE: This type of button must always be the first button in the first row.   , ikb_switch_inline_query_current_chat :: Maybe Text -- ^ If set, pressing the button will insert the bot‘s username and the specified inline query in the current chat's input field. Can be empty, in which case only the bot’s username will be inserted.+  , ikb_pay                              :: Maybe Bool -- ^ Specify True, to send a Pay button. NOTE: This type of button must always be the first button in the first row.   } deriving (Show, Generic)  instance ToJSON InlineKeyboardButton where@@ -711,7 +742,7 @@  inlineKeyboardButton :: Text -> InlineKeyboardButton inlineKeyboardButton buttonText =-  InlineKeyboardButton buttonText Nothing Nothing Nothing Nothing Nothing+  InlineKeyboardButton buttonText Nothing Nothing Nothing Nothing Nothing Nothing  data CallbackGame = CallbackGame   {@@ -833,6 +864,8 @@   , pinned_message          :: Maybe Message -- ^ Specified message was pinned. Note that the Message object in this field will not contain further reply_to_message fields even if it is itself a reply.   , invoice                 :: Maybe Invoice -- ^  Message is an invoice for a payment, information about the invoice.   , successful_payment      :: Maybe SuccessfulPayment -- ^  Message is a service message about a successful payment, information about the payment.+  , video_note              :: Maybe VideoNote -- ^ Message is a video note, information about the video message+  , new_chat_members        :: Maybe [User] -- ^ New members that were added to the group or supergroup and information about them (the bot itself may be one of these members)   } deriving (FromJSON, ToJSON, Show, Generic)  -- | This object represents one special entity in a text message. For example, hashtags, usernames, URLs, etc.
src/Web/Telegram/API/Bot/Requests.hs view
@@ -18,6 +18,7 @@     , SendStickerRequest             (..)     , SendVideoRequest               (..)     , SendVoiceRequest               (..)+    , SendVideoNoteRequest           (..)     , SendLocationRequest            (..)     , SendVenueRequest               (..)     , SendContactRequest             (..)@@ -52,6 +53,8 @@     , uploadVideoRequest     , sendVoiceRequest     , uploadVoiceRequest+    , sendVideoNoteRequest+    , uploadVideoNoteRequest     , sendLocationRequest     , sendVenueRequest     , sendContactRequest@@ -448,6 +451,41 @@ uploadVoiceRequest :: ChatId -> FileUpload -> SendVoiceRequest FileUpload uploadVoiceRequest chatId voice = SendVoiceRequest chatId voice Nothing Nothing Nothing Nothing Nothing +data SendVideoNoteRequest payload = SendVideoNoteRequest+  {+    _vid_note_chat_id :: ChatId -- ^ Unique identifier for the target chat or username of the target channel (in the format @channelusername)+  , _vid_note_video_note :: payload -- ^ Video note to send. Pass a file_id as String to send a video note that exists on the Telegram servers (recommended) or upload a new video using multipart/form-data. More info on Sending Files ». Sending video notes by a URL is currently unsupported+  , _vid_note_duration :: Maybe Int -- ^ Duration of sent video in seconds+  , _vid_note_length :: Maybe Int -- ^ Video width and height+  , _vid_note_disable_notification :: Maybe Bool -- ^ Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.+  , _vid_note_reply_to_message_id :: Maybe Int -- ^ If the message is a reply, ID of the original message+  , _vid_note_reply_markup :: Maybe ReplyKeyboard -- ^ Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user.+  } deriving (Show, Generic)++instance ToJSON (SendVideoNoteRequest Text) where+  toJSON = toJsonDrop 9++instance FromJSON (SendVideoNoteRequest Text) where+  parseJSON = parseJsonDrop 9++instance ToMultipartFormData (SendVideoNoteRequest FileUpload) where+  toMultipartFormData req =+    [ utf8Part "chat_id" (chatIdToPart $ _vid_note_chat_id req) ] +++    catMaybes+    [ partLBS "duration" . encode <$> _vid_note_duration req+    , partLBS "length" . encode <$> _vid_note_length req+    , partLBS "disable_notification" . encode <$> _vid_note_disable_notification req+    , utf8Part "reply_to_message_id" . tshow <$> _vid_note_reply_to_message_id req+    , partLBS "reply_markup" . encode <$> _vid_note_reply_markup req+    ] +++    [ fileUploadToPart "video_note" (_vid_note_video_note req) ]++sendVideoNoteRequest :: ChatId -> Text -> SendVideoNoteRequest Text+sendVideoNoteRequest chatId videoNote = SendVideoNoteRequest chatId videoNote Nothing Nothing Nothing Nothing Nothing++uploadVideoNoteRequest :: ChatId -> FileUpload -> SendVideoNoteRequest FileUpload+uploadVideoNoteRequest chatId videoNote = SendVideoNoteRequest chatId videoNote Nothing Nothing Nothing Nothing Nothing+ -- | This object represents request for 'sendLocation' data SendLocationRequest = SendLocationRequest   {@@ -520,28 +558,34 @@                 | RecordAudio                 | UploadAudio                 | UploadDocument-                | FindLocation deriving (Show, Generic)+                | FindLocation+                | RecordVideoNote+                | UploadVideoNote deriving (Show, Generic)  instance ToJSON ChatAction where-  toJSON Typing         = "typing"-  toJSON UploadPhoto    = "upload_photo"-  toJSON RecordVideo    = "record_video"-  toJSON UploadVideo    = "upload_video"-  toJSON RecordAudio    = "record_audio"-  toJSON UploadAudio    = "upload_audio"-  toJSON UploadDocument = "upload_document"-  toJSON FindLocation   = "find_location"+  toJSON Typing          = "typing"+  toJSON UploadPhoto     = "upload_photo"+  toJSON RecordVideo     = "record_video"+  toJSON UploadVideo     = "upload_video"+  toJSON RecordAudio     = "record_audio"+  toJSON UploadAudio     = "upload_audio"+  toJSON UploadDocument  = "upload_document"+  toJSON FindLocation    = "find_location"+  toJSON RecordVideoNote = "record_video_note"+  toJSON UploadVideoNote = "upload_video_note"  instance FromJSON ChatAction where-  parseJSON "typing"          = pure Typing-  parseJSON "upload_photo"    = pure UploadPhoto-  parseJSON "record_video"    = pure RecordVideo-  parseJSON "upload_video"    = pure UploadVideo-  parseJSON "record_audio"    = pure RecordAudio-  parseJSON "upload_audio"    = pure UploadAudio-  parseJSON "upload_document" = pure UploadDocument-  parseJSON "find_location"   = pure FindLocation-  parseJSON _                 = fail "Failed to parse ChatAction"+  parseJSON "typing"            = pure Typing+  parseJSON "upload_photo"      = pure UploadPhoto+  parseJSON "record_video"      = pure RecordVideo+  parseJSON "upload_video"      = pure UploadVideo+  parseJSON "record_audio"      = pure RecordAudio+  parseJSON "upload_audio"      = pure UploadAudio+  parseJSON "upload_document"   = pure UploadDocument+  parseJSON "find_location"     = pure FindLocation+  parseJSON "record_video_note" = pure RecordVideoNote+  parseJSON "upload_video_note" = pure UploadVideoNote+  parseJSON _                   = fail "Failed to parse ChatAction"  -- | This object represents request for 'sendChatAction' data SendChatActionRequest = SendChatActionRequest
telegram-api.cabal view
@@ -1,5 +1,5 @@ name:                telegram-api-version:             0.6.2.0+version:             0.6.3.0 synopsis:            Telegram Bot API bindings description:         High-level bindings to the Telegram Bot API homepage:            http://github.com/klappvisor/haskell-telegram-api#readme@@ -16,6 +16,7 @@                    , test-data/cert.pem                    , test-data/haskell-logo.webp                    , test-data/lego-video.mp4+                   , test-data/lego-square.mp4                    , test-data/Possible_PDM_signal_labeled_as_Sputnik_by_NASA.ogg                    , test-data/concerto-for-2-trumpets-in-c-major.mp3                    , test-data/wikipedia-telegram.txt@@ -42,11 +43,11 @@                      , Web.Telegram.API.Bot.API.Core                      , Servant.Client.MultipartFormData   build-depends:       base >= 4.7 && < 5-                     , aeson >= 1.0 && < 1.2+                     , aeson >= 1.0 && < 1.3                      , http-api-data                      , http-client >= 0.5 && < 0.6-                     , servant >= 0.9 && <0.10-                     , servant-client >= 0.9 && <0.10+                     , servant >= 0.9 && <0.11+                     , servant-client >= 0.9 && <0.11                      , mtl >= 2.2 && < 2.3                      , text                      , transformers@@ -68,7 +69,7 @@                      , JsonSpec                      , UpdatesSpec   build-depends:       base-                     , aeson >= 1.0 && < 1.2+                     , aeson >= 1.0 && < 1.3                      , hjpath                      , ansi-wl-pprint                      , http-client >= 0.5 && < 0.6@@ -76,8 +77,8 @@                      , http-types                      , hspec                      , optparse-applicative-                     , servant >= 0.9 && <0.10-                     , servant-client >= 0.9 && <0.10+                     , servant >= 0.9 && <0.11+                     , servant-client >= 0.9 && <0.11                      , telegram-api                      , http-types                      , filepath
+ test-data/lego-square.mp4 view

binary file changed (absent → 182242 bytes)

test/MainSpec.hs view
@@ -184,6 +184,15 @@       Right Response { result = Message { voice = Just voice } } <-         uploadVoice token voiceReq manager       voice_duration voice `shouldBe` 10+  describe "/sendVideoNote" $+    it "should upload video note" $ do+      let fileUpload = localFileUpload $ testFile "lego-square.mp4"+          videoNoteReq = (uploadVideoNoteRequest chatId fileUpload)+            { _vid_note_length = Just 320 }+      res <- uploadVideoNote token videoNoteReq manager+      success res+      let Right Response { result = Message { video_note = Just video } } = res+      vid_note_duration video `shouldBe` 6    describe "/sendVideo" $     it "should upload video" $ do