telegram-api 0.1.0.0 → 0.1.0.1
raw patch · 9 files changed
+390/−223 lines, 9 filesdep ~basedep ~eitherdep ~servantsetup-changed
Dependency ranges changed: base, either, servant
Files
- LICENSE +29/−29
- README.md +96/−0
- Setup.hs +2/−2
- src/Web/Telegram/API/Bot.hs +19/−19
- src/Web/Telegram/API/Bot/API.hs +17/−2
- src/Web/Telegram/API/Bot/JsonExt.hs +28/−0
- src/Web/Telegram/API/Bot/Responses.hs +14/−1
- telegram-api.cabal +51/−47
- test/Spec.hs +134/−123
LICENSE view
@@ -1,30 +1,30 @@-Copyright Alexey Rodiontsev (c) 2015--All rights reserved.--Redistribution and use in source and binary forms, with or without-modification, are permitted provided that the following conditions are met:-- * Redistributions of source code must retain the above copyright- notice, this list of conditions and the following disclaimer.-- * Redistributions in binary form must reproduce the above- copyright notice, this list of conditions and the following- disclaimer in the documentation and/or other materials provided- with the distribution.-- * Neither the name of Alexey Rodiontsev nor the names of other- contributors may be used to endorse or promote products derived- from this software without specific prior written permission.--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+Copyright Alexey Rodiontsev (c) 2015 + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of Alexey Rodiontsev nor the names of other + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,96 @@+# telegram-api + + + + + + + +High-level bindings to the [Telegram Bots API][telegram-bot-api] based on [servant][servant] library. +Currently supports only one way of receiving updates based on [`getUpdates`](https://core.telegram.org/bots/api#getupdates) method. +Uploading stickers, documents, video, etc is not supported yet, so you can only send items which are already uploaded on the Telegram servers. +See list of supported methods below in TODO section. + +## Usage + +`getMe` example + +```haskell +import Control.Monad +import qualified Data.Text.IO as T +import Data.Maybe +import Telegram.API.Data +import Telegram.API.Responses +import Telegram.API.Bot + +main :: IO () +main = do + Right GetMeResponse { user_result = u } <- + getMe token + T.putStrLn (user_first_name u) + where token = Token "bot<token>" -- entire Token should be bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11 +``` + +`sendMessage` example + +```haskell +import Control.Monad +import qualified Data.Text.IO as T +import Data.Maybe +import Telegram.API.Data +import Telegram.API.Requests +import Telegram.API.Responses +import Telegram.API.Bot + +main :: IO () +main = do + Right MessageResponse { message_result = m } <- + sendMessage token (SendMessageRequest chatId message (Just Markdown) Nothing Nothing) + T.putStrLn (message_id m) + T.putStrLn (text m) + where token = Token "bot<token>" -- entire Token should be bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11 + chatId = "<chat_id> or <@channelusername>" + message = "text *bold* _italic_ [github](github.com/klappvisor/haskell-telegram-api)" +``` + +## TODO + +### General + +* `reply_markup` is skipped for all methods +* Inline mode is not supported yet +* Uploading of Files, Documents, Stickers, etc + +### Methods + +##### Currently supported: + +* `getMe` +* `sendMessage` +* `forwardMessage` +* `sendPhoto` - without upload +* `sendAudio` - without upload +* `sendDocument` - without upload +* `sendSticker` - without upload +* `sendVideo` - without upload +* `sendVoice` - without upload +* `sendLocation` +* `getUpdates` +* `getFile` +* `sendChatAction` +* `getUserProfilePhotos` +* `setWebhook` - without uploading certificate + +##### To be done: + +* `sendPhoto` - upload photo +* `sendAudio` - upload audio +* `sendDocument` - upload documents +* `sendSticker` - upload stickers +* `sendVideo` - upload video +* `sendVoice` - upload voice +* `setWebhook` - upload certificate +* `answerInlineQuery` inline bots + +[telegram-bot-api]: https://core.telegram.org/bots/api +[servant]: https://haskell-servant.github.io/
Setup.hs view
@@ -1,2 +1,2 @@-import Distribution.Simple-main = defaultMain+import Distribution.Simple +main = defaultMain
src/Web/Telegram/API/Bot.hs view
@@ -1,20 +1,20 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE DeriveAnyClass #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE TemplateHaskell #-}---- | This module provides Telegram Bot API-module Web.Telegram.API.Bot- (- module Web.Telegram.API.Bot.API- , module Web.Telegram.API.Bot.Data- , module Web.Telegram.API.Bot.Responses- , module Web.Telegram.API.Bot.Requests- ) where--import Web.Telegram.API.Bot.API-import Web.Telegram.API.Bot.Data-import Web.Telegram.API.Bot.Responses+{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE TemplateHaskell #-} + +-- | This module provides Telegram Bot API +module Web.Telegram.API.Bot + ( + module Web.Telegram.API.Bot.API + , module Web.Telegram.API.Bot.Data + , module Web.Telegram.API.Bot.Responses + , module Web.Telegram.API.Bot.Requests + ) where + +import Web.Telegram.API.Bot.API +import Web.Telegram.API.Bot.Data +import Web.Telegram.API.Bot.Responses import Web.Telegram.API.Bot.Requests
src/Web/Telegram/API/Bot/API.hs view
@@ -21,6 +21,7 @@ , getUpdates , getFile , getUserProfilePhotos + , setWebhook -- * API , TelegramBotAPI , api @@ -104,6 +105,10 @@ :> QueryParam "offset" Int :> QueryParam "limit" Int :> Get '[JSON] UserProfilePhotosResponse + :<|> TelegramToken :> "setWebhook" + :> QueryParam "url" Text + :> Get '[JSON] + SetWebhookResponse -- | Proxy for Thelegram Bot API api :: Proxy TelegramBotAPI @@ -123,6 +128,7 @@ getUpdates_ :: Token -> Maybe Int -> Maybe Int -> Maybe Int -> EitherT ServantError IO UpdatesResponse getFile_ :: Token -> Maybe Text -> EitherT ServantError IO FileResponse getUserProfilePhotos_ :: Token -> Maybe Int -> Maybe Int -> Maybe Int -> EitherT ServantError IO UserProfilePhotosResponse +setWebhook_ :: Token -> Maybe Text -> EitherT ServantError IO SetWebhookResponse getMe_ :<|> sendMessage_ :<|> forwardMessage_ @@ -136,7 +142,8 @@ :<|> sendChatAction_ :<|> getUpdates_ :<|> getFile_ - :<|> getUserProfilePhotos_ = + :<|> getUserProfilePhotos_ + :<|> setWebhook_ = client api (BaseUrl Https "api.telegram.org" 443) -- | A simple method for testing your bot's auth token. Requires no parameters. @@ -197,4 +204,12 @@ -- | Use this method to get a list of profile pictures for a user. Returns a 'UserProfilePhotos' object. getUserProfilePhotos :: Token -> Int -> Maybe Int -> Maybe Int -> IO (Either ServantError UserProfilePhotosResponse) -getUserProfilePhotos token user_id offset limit = runEitherT $ getUserProfilePhotos_ token (Just user_id) offset limit+getUserProfilePhotos token user_id offset limit = runEitherT $ getUserProfilePhotos_ token (Just user_id) offset limit + +-- | Use this method to specify a url and receive incoming updates via an outgoing webhook. Whenever there is an update for the bot, we will send an HTTPS POST request to the specified url, containing a JSON-serialized 'Update'. In case of an unsuccessful request, we will give up after a reasonable amount of attempts. +-- +-- If you'd like to make sure that the Webhook request comes from Telegram, we recommend using a secret path in the URL, e.g. @https://www.example.com/<token>@. Since nobody else knows your bot‘s token, you can be pretty sure it’s us. +setWebhook :: Token + -> Maybe Text -- ^ HTTPS url to send updates to. Use an empty string to remove webhook integration + -> IO (Either ServantError SetWebhookResponse) +setWebhook token url = runEitherT $ setWebhook_ token url
+ src/Web/Telegram/API/Bot/JsonExt.hs view
@@ -0,0 +1,28 @@+{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE FlexibleContexts #-} + +-- | This module contains helper functions to work with JSON +module Web.Telegram.API.Bot.JsonExt + ( + toJsonDrop, + parseJsonDrop + ) where + +import Data.Aeson +import Data.Aeson.Types +import GHC.Generics +import GHC.TypeLits + +-- | Method used to drop prefix from field name during serialization +toJsonDrop prefix = genericToJSON defaultOptions { + fieldLabelModifier = drop prefix + , omitNothingFields = True + } + +-- | Method used to drop prefix from field name during deserialization +parseJsonDrop prefix = genericParseJSON defaultOptions { fieldLabelModifier = drop prefix }
src/Web/Telegram/API/Bot/Responses.hs view
@@ -15,6 +15,7 @@ , UpdatesResponse (..) , FileResponse (..) , UserProfilePhotosResponse (..) + , SetWebhookResponse (..) ) where import Data.Aeson @@ -98,4 +99,16 @@ toJSON = toJsonDrop 7 instance FromJSON UserProfilePhotosResponse where - parseJSON = parseJsonDrop 7+ parseJSON = parseJsonDrop 7 + +-- | This object represents 'setWebhook' response +data SetWebhookResponse = SetWebhookResponse + { + webhook_result :: Bool + } deriving (Show, Generic) + +instance ToJSON SetWebhookResponse where + toJSON = toJsonDrop 8 + +instance FromJSON SetWebhookResponse where + parseJSON = parseJsonDrop 8
telegram-api.cabal view
@@ -1,47 +1,51 @@-name: telegram-api-version: 0.1.0.0-synopsis: Telegram Bot API bindings-description: High-level bindings to the Telegram Bots API-homepage: http://github.com/klappvisor/telegram-api#readme-license: BSD3-license-file: LICENSE-author: Alexey Rodiontsev-maintainer: alex.rodiontsev@gmail.com-copyright: Alexey Rodiontsev (c) 2016-category: Web-build-type: Simple--- extra-source-files:-cabal-version: >=1.10--library- hs-source-dirs: src- exposed-modules: Web.Telegram.API.Bot- , Web.Telegram.API.Bot.API- , Web.Telegram.API.Bot.Data- , Web.Telegram.API.Bot.Responses- , Web.Telegram.API.Bot.Requests- build-depends: base >= 4.7 && < 5- , aeson- , servant- , servant-client- , text- , either- default-language: Haskell2010--test-suite telegram-api-test- type: exitcode-stdio-1.0- hs-source-dirs: test- main-is: Spec.hs- build-depends: base- , text- , hspec- , servant- , servant-client- , telegram-api- , http-types- ghc-options: -threaded -rtsopts -with-rtsopts=-N- default-language: Haskell2010--source-repository head- type: git- location: https://github.com/klappvisor/telegram-api+name: telegram-api +version: 0.1.0.1 +synopsis: Telegram Bot API bindings +description: High-level bindings to the Telegram Bot API +homepage: http://github.com/klappvisor/haskell-telegram-api#readme +license: BSD3 +license-file: LICENSE +author: Alexey Rodiontsev +maintainer: alex.rodiontsev@gmail.com +copyright: Alexey Rodiontsev (c) 2016 +category: Web +build-type: Simple +-- extra-source-files: +cabal-version: >=1.10 + +extra-source-files: + README.md + +library + hs-source-dirs: src + exposed-modules: Web.Telegram.API.Bot + , Web.Telegram.API.Bot.API + , Web.Telegram.API.Bot.Data + , Web.Telegram.API.Bot.Responses + , Web.Telegram.API.Bot.Requests + other-modules: Web.Telegram.API.Bot.JsonExt + build-depends: base >= 4.7 && < 5 + , aeson + , servant + , servant-client + , text + , either + default-language: Haskell2010 + +test-suite telegram-api-test + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Spec.hs + build-depends: base + , text + , hspec + , servant + , servant-client + , telegram-api + , http-types + ghc-options: -threaded -rtsopts -with-rtsopts=-N + default-language: Haskell2010 + +source-repository head + type: git + location: https://github.com/klappvisor/haskell-telegram-api
test/Spec.hs view
@@ -1,124 +1,135 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE DeriveAnyClass #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE TemplateHaskell #-}--module Main (main) where--import Control.Monad-import Web.Telegram.API.Bot-import Test.Hspec-import Data.Text (Text)-import qualified Data.Text as T-import Servant.Client-import Servant.API-import Network.HTTP.Types.Status-import System.Environment--main :: IO ()-main = do- [token, chatId] <- getArgs- withArgs [] $ hspec (spec (Token (T.pack token)) (T.pack chatId))--spec :: Token -> Text -> Spec-spec token chatId = do- describe "/getMe" $ do- it "responds with correct bot's name" $ do- Right GetMeResponse { user_result = u } <-- getMe token- (user_first_name u) `shouldBe` "TelegramAPIBot"-- describe "/sendMessage" $ do- it "should send message" $ do- Right MessageResponse { message_result = m } <-- sendMessage token (SendMessageRequest chatId "test message" Nothing Nothing Nothing)- (text m) `shouldBe` (Just "test message")-- it "should return error message" $ do- Left FailureResponse { responseStatus = Status { statusMessage = msg } } <-- sendMessage token (SendMessageRequest "" "test message" Nothing Nothing Nothing)- msg `shouldBe` "Bad Request"-- it "should send message markdown" $ do- Right MessageResponse { message_result = m } <-- sendMessage token (SendMessageRequest chatId "text *bold* _italic_ [github](github.com/klappvisor/telegram-api)" (Just Markdown) Nothing Nothing)- (text m) `shouldBe` (Just "text bold italic github")-- describe "/forwardMessage" $ do- it "should forward message" $ do- Left FailureResponse { responseStatus = Status { statusMessage = msg } } <-- forwardMessage token (ForwardMessageRequest chatId chatId 123)- msg `shouldBe` "Bad Request"-- describe "/sendPhoto" $ do- it "should return error message" $ do- Left FailureResponse { responseStatus = Status { statusMessage = msg } } <-- sendPhoto token (SendPhotoRequest "" "photo_id" (Just "photo caption") Nothing)- msg `shouldBe` "Bad Request"- it "should send photo" $ do- Right MessageResponse { message_result = Message { caption = Just cpt } } <-- sendPhoto token (SendPhotoRequest chatId "AgADBAADv6cxGybVMgABtZ_EOpBSdxYD5xwZAAQ4ElUVMAsbbBqFAAIC" (Just "photo caption") Nothing)- cpt `shouldBe` "photo caption"-- describe "/sendAudio" $ do- it "should return error message" $ do- Left FailureResponse { responseStatus = Status { statusMessage = msg } } <-- sendAudio token (SendAudioRequest "" "audio_id" Nothing (Just "performer") (Just "title") Nothing)- msg `shouldBe` "Bad Request"--- it "should send audio" $ do--- Right MessageResponse { message_result = Message { audio = Just Audio { audio_title = Just title } } } <---- sendAudio token (SendAudioRequest chatId "audio_id" Nothing (Just "performer") (Just "my title 1") Nothing)--- title `shouldBe` "my title 1"-- describe "/sendSticker" $ do- it "should send sticker" $ do- Right MessageResponse { message_result = Message { sticker = Just sticker } } <-- sendSticker token (SendStickerRequest chatId "BQADAgADGgADkWgMAAGXlYGBiM_d2wI" Nothing)- (sticker_file_id sticker) `shouldBe` "BQADAgADGgADkWgMAAGXlYGBiM_d2wI"-- describe "/sendLocation" $ do- it "should send location" $ do- Right MessageResponse { message_result = Message { location = Just loc } } <-- sendLocation token (SendLocationRequest chatId 52.38 4.9 Nothing)- (latitude loc) `shouldSatisfy` (liftM2 (&&) (> 52) (< 52.4))- (longitude loc) `shouldSatisfy` (liftM2 (&&) (> 4.89) (< 5))-- describe "/sendChatAction" $ do- it "should set typing action" $ do- Right ChatActionResponse { action_result = res} <-- sendChatAction token (SendChatActionRequest chatId Typing)- res `shouldBe` True- it "should set find location action" $ do- Right ChatActionResponse { action_result = res} <-- sendChatAction token (SendChatActionRequest chatId FindLocation)- res `shouldBe` True- it "should set upload photo action" $ do- Right ChatActionResponse { action_result = res} <-- sendChatAction token (SendChatActionRequest chatId UploadPhoto)+{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE TemplateHaskell #-} + +module Main (main) where + +import Control.Monad +import Web.Telegram.API.Bot +import Test.Hspec +import Data.Text (Text) +import qualified Data.Text as T +import Servant.Client +import Servant.API +import Network.HTTP.Types.Status +import System.Environment + +main :: IO () +main = do + [token, chatId] <- getArgs + withArgs [] $ hspec (spec (Token (T.pack token)) (T.pack chatId)) + +spec :: Token -> Text -> Spec +spec token chatId = do + describe "/getMe" $ do + it "responds with correct bot's name" $ do + Right GetMeResponse { user_result = u } <- + getMe token + (user_first_name u) `shouldBe` "TelegramAPIBot" + + describe "/sendMessage" $ do + it "should send message" $ do + Right MessageResponse { message_result = m } <- + sendMessage token (SendMessageRequest chatId "test message" Nothing Nothing Nothing) + (text m) `shouldBe` (Just "test message") + + it "should return error message" $ do + Left FailureResponse { responseStatus = Status { statusMessage = msg } } <- + sendMessage token (SendMessageRequest "" "test message" Nothing Nothing Nothing) + msg `shouldBe` "Bad Request" + + it "should send message markdown" $ do + Right MessageResponse { message_result = m } <- + sendMessage token (SendMessageRequest chatId "text *bold* _italic_ [github](github.com/klappvisor/telegram-api)" (Just Markdown) Nothing Nothing) + (text m) `shouldBe` (Just "text bold italic github") + + describe "/forwardMessage" $ do + it "should forward message" $ do + Left FailureResponse { responseStatus = Status { statusMessage = msg } } <- + forwardMessage token (ForwardMessageRequest chatId chatId 123) + msg `shouldBe` "Bad Request" + + describe "/sendPhoto" $ do + it "should return error message" $ do + Left FailureResponse { responseStatus = Status { statusMessage = msg } } <- + sendPhoto token (SendPhotoRequest "" "photo_id" (Just "photo caption") Nothing) + msg `shouldBe` "Bad Request" + it "should send photo" $ do + Right MessageResponse { message_result = Message { caption = Just cpt } } <- + sendPhoto token (SendPhotoRequest chatId "AgADBAADv6cxGybVMgABtZ_EOpBSdxYD5xwZAAQ4ElUVMAsbbBqFAAIC" (Just "photo caption") Nothing) + cpt `shouldBe` "photo caption" + + describe "/sendAudio" $ do + it "should return error message" $ do + Left FailureResponse { responseStatus = Status { statusMessage = msg } } <- + sendAudio token (SendAudioRequest "" "audio_id" Nothing (Just "performer") (Just "title") Nothing) + msg `shouldBe` "Bad Request" +-- it "should send audio" $ do +-- Right MessageResponse { message_result = Message { audio = Just Audio { audio_title = Just title } } } <- +-- sendAudio token (SendAudioRequest chatId "audio_id" Nothing (Just "performer") (Just "my title 1") Nothing) +-- title `shouldBe` "my title 1" + + describe "/sendSticker" $ do + it "should send sticker" $ do + Right MessageResponse { message_result = Message { sticker = Just sticker } } <- + sendSticker token (SendStickerRequest chatId "BQADAgADGgADkWgMAAGXlYGBiM_d2wI" Nothing) + (sticker_file_id sticker) `shouldBe` "BQADAgADGgADkWgMAAGXlYGBiM_d2wI" + + describe "/sendLocation" $ do + it "should send location" $ do + Right MessageResponse { message_result = Message { location = Just loc } } <- + sendLocation token (SendLocationRequest chatId 52.38 4.9 Nothing) + (latitude loc) `shouldSatisfy` (liftM2 (&&) (> 52) (< 52.4)) + (longitude loc) `shouldSatisfy` (liftM2 (&&) (> 4.89) (< 5)) + + describe "/sendChatAction" $ do + it "should set typing action" $ do + Right ChatActionResponse { action_result = res} <- + sendChatAction token (SendChatActionRequest chatId Typing) + res `shouldBe` True + it "should set find location action" $ do + Right ChatActionResponse { action_result = res} <- + sendChatAction token (SendChatActionRequest chatId FindLocation) + res `shouldBe` True + it "should set upload photo action" $ do + Right ChatActionResponse { action_result = res} <- + sendChatAction token (SendChatActionRequest chatId UploadPhoto) + res `shouldBe` True + + describe "/getUpdates" $ do + it "should get all messages" $ do + Right UpdatesResponse { update_result = updates} <- + getUpdates token Nothing Nothing Nothing + (length updates) `shouldSatisfy` (> 0) + ((message_id . message) (head updates)) `shouldSatisfy` (> 0) + + describe "/getFile" $ do + it "should get file" $ do + Right FileResponse { file_result = file } <- + getFile token "AAQEABMXDZEwAARC0Kj3twkzNcMkAAIC" + (fmap (T.take 10) (file_path file)) `shouldBe` (Just "thumb/file") + + it "should return error" $ do + Left FailureResponse { responseStatus = Status { statusMessage = msg } } <- + getFile token "AAQEABMXDZEwAARC0Kj3twkzNcMkAmm" + msg `shouldBe` "Bad Request" + + describe "/getUserProfilePhotos" $ do + it "should get user profile photos" $ do + Right UserProfilePhotosResponse { photos_result = photos } <- + getUserProfilePhotos token (read (T.unpack chatId)) Nothing Nothing + (total_count photos) `shouldSatisfy` (> 0) + + describe "/setWebhook" $ do + it "should set webhook" $ do + Right SetWebhookResponse { webhook_result = res } <- + setWebhook token (Just "https://example.com/secret_token") + res `shouldBe` True + + it "should remove webhook" $ do + Right SetWebhookResponse { webhook_result = res } <- + setWebhook token Nothing res `shouldBe` True-- describe "/getUpdates" $ do- it "should get all messages" $ do- Right UpdatesResponse { update_result = updates} <-- getUpdates token Nothing Nothing Nothing- (length updates) `shouldSatisfy` (> 0)- ((message_id . message) (head updates)) `shouldSatisfy` (> 0)-- describe "/getFile" $ do- it "should get file" $ do- Right FileResponse { file_result = file } <-- getFile token "AAQEABMXDZEwAARC0Kj3twkzNcMkAAIC"- (file_path file) `shouldBe` (Just "thumb/file_2")-- it "should return error" $ do- Left FailureResponse { responseStatus = Status { statusMessage = msg } } <-- getFile token "AAQEABMXDZEwAARC0Kj3twkzNcMkAmm"- msg `shouldBe` "Bad Request"-- describe "/getUserProfilePhotos" $ do- it "should get user profile photos" $ do- Right UserProfilePhotosResponse { photos_result = photos } <-- getUserProfilePhotos token (read (T.unpack chatId)) Nothing Nothing- (total_count photos) `shouldSatisfy` (> 0)