telegram-api 0.5.2.0 → 0.6.0.0
raw patch · 19 files changed
+1187/−591 lines, 19 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Web.Telegram.API.Bot.API: answerCallbackQuery :: Token -> AnswerCallbackQueryRequest -> Manager -> IO (Either ServantError CallbackQueryResponse)
- Web.Telegram.API.Bot.API: answerInlineQuery :: Token -> AnswerInlineQueryRequest -> Manager -> IO (Either ServantError InlineQueryResponse)
- Web.Telegram.API.Bot.API: deleteWebhook :: Token -> Manager -> IO (Either ServantError (Response Bool))
- Web.Telegram.API.Bot.API: editInlineMessageCaption :: Token -> EditMessageCaptionRequest -> Manager -> IO (Either ServantError (Response Bool))
- Web.Telegram.API.Bot.API: editInlineMessageReplyMarkup :: Token -> EditMessageReplyMarkupRequest -> Manager -> IO (Either ServantError (Response Bool))
- Web.Telegram.API.Bot.API: editInlineMessageText :: Token -> EditMessageTextRequest -> Manager -> IO (Either ServantError (Response Bool))
- Web.Telegram.API.Bot.API: editMessageCaption :: Token -> EditMessageCaptionRequest -> Manager -> IO (Either ServantError MessageResponse)
- Web.Telegram.API.Bot.API: editMessageReplyMarkup :: Token -> EditMessageReplyMarkupRequest -> Manager -> IO (Either ServantError MessageResponse)
- Web.Telegram.API.Bot.API: editMessageText :: Token -> EditMessageTextRequest -> Manager -> IO (Either ServantError MessageResponse)
- Web.Telegram.API.Bot.API: forwardMessage :: Token -> ForwardMessageRequest -> Manager -> IO (Either ServantError MessageResponse)
- Web.Telegram.API.Bot.API: getChat :: Token -> Text -> Manager -> IO (Either ServantError GetChatResponse)
- Web.Telegram.API.Bot.API: getChatAdministrators :: Token -> Text -> Manager -> IO (Either ServantError GetChatAdministratorsResponse)
- Web.Telegram.API.Bot.API: getChatMember :: Token -> Text -> Int -> Manager -> IO (Either ServantError GetChatMemberResponse)
- Web.Telegram.API.Bot.API: getChatMembersCount :: Token -> Text -> Manager -> IO (Either ServantError GetChatMembersCountResponse)
- Web.Telegram.API.Bot.API: getFile :: Token -> Text -> Manager -> IO (Either ServantError FileResponse)
- Web.Telegram.API.Bot.API: getMe :: Token -> Manager -> IO (Either ServantError GetMeResponse)
- Web.Telegram.API.Bot.API: getUpdates :: Token -> Maybe Int -> Maybe Int -> Maybe Int -> Manager -> IO (Either ServantError UpdatesResponse)
- Web.Telegram.API.Bot.API: getUserProfilePhotos :: Token -> Int -> Maybe Int -> Maybe Int -> Manager -> IO (Either ServantError UserProfilePhotosResponse)
- Web.Telegram.API.Bot.API: getWebhookInfo :: Token -> Manager -> IO (Either ServantError GetWebhookInfoResponse)
- Web.Telegram.API.Bot.API: instance GHC.Classes.Eq Web.Telegram.API.Bot.API.Token
- Web.Telegram.API.Bot.API: instance GHC.Classes.Ord Web.Telegram.API.Bot.API.Token
- Web.Telegram.API.Bot.API: instance GHC.Show.Show Web.Telegram.API.Bot.API.Token
- Web.Telegram.API.Bot.API: instance Web.Internal.HttpApiData.FromHttpApiData Web.Telegram.API.Bot.API.Token
- Web.Telegram.API.Bot.API: instance Web.Internal.HttpApiData.ToHttpApiData Web.Telegram.API.Bot.API.Token
- Web.Telegram.API.Bot.API: kickChatMember :: Token -> Text -> Int -> Manager -> IO (Either ServantError KickChatMemberResponse)
- Web.Telegram.API.Bot.API: leaveChat :: Token -> Text -> Manager -> IO (Either ServantError LeaveChatResponse)
- Web.Telegram.API.Bot.API: sendAudio :: Token -> SendAudioRequest Text -> Manager -> IO (Either ServantError MessageResponse)
- Web.Telegram.API.Bot.API: sendChatAction :: Token -> SendChatActionRequest -> Manager -> IO (Either ServantError ChatActionResponse)
- Web.Telegram.API.Bot.API: sendContact :: Token -> SendContactRequest -> Manager -> IO (Either ServantError MessageResponse)
- Web.Telegram.API.Bot.API: sendDocument :: Token -> SendDocumentRequest Text -> Manager -> IO (Either ServantError MessageResponse)
- Web.Telegram.API.Bot.API: sendGame :: Token -> SendGameRequest -> Manager -> IO (Either ServantError MessageResponse)
- Web.Telegram.API.Bot.API: sendLocation :: Token -> SendLocationRequest -> Manager -> IO (Either ServantError MessageResponse)
- Web.Telegram.API.Bot.API: sendMessage :: Token -> SendMessageRequest -> Manager -> IO (Either ServantError MessageResponse)
- Web.Telegram.API.Bot.API: sendPhoto :: Token -> SendPhotoRequest Text -> Manager -> IO (Either ServantError MessageResponse)
- Web.Telegram.API.Bot.API: sendSticker :: Token -> SendStickerRequest Text -> Manager -> IO (Either ServantError MessageResponse)
- Web.Telegram.API.Bot.API: sendVenue :: Token -> SendVenueRequest -> Manager -> IO (Either ServantError MessageResponse)
- Web.Telegram.API.Bot.API: sendVideo :: Token -> SendVideoRequest Text -> Manager -> IO (Either ServantError MessageResponse)
- Web.Telegram.API.Bot.API: sendVoice :: Token -> SendVoiceRequest Text -> Manager -> IO (Either ServantError MessageResponse)
- Web.Telegram.API.Bot.API: setWebhook :: Token -> Maybe Text -> Manager -> IO (Either ServantError SetWebhookResponse)
- Web.Telegram.API.Bot.API: setWebhookWithCertificate :: Token -> SetWebhookRequest -> Manager -> IO (Either ServantError SetWebhookResponse)
- Web.Telegram.API.Bot.API: unbanChatMember :: Token -> Text -> Int -> Manager -> IO (Either ServantError UnbanChatMemberResponse)
- Web.Telegram.API.Bot.API: uploadAudio :: Token -> SendAudioRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse)
- Web.Telegram.API.Bot.API: uploadDocument :: Token -> SendDocumentRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse)
- Web.Telegram.API.Bot.API: uploadPhoto :: Token -> SendPhotoRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse)
- Web.Telegram.API.Bot.API: uploadSticker :: Token -> SendStickerRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse)
- Web.Telegram.API.Bot.API: uploadVideo :: Token -> SendVideoRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse)
- Web.Telegram.API.Bot.API: uploadVoice :: Token -> SendVoiceRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse)
+ Web.Telegram.API.Bot.API: runClient :: TelegramClient a -> Token -> Manager -> IO (Either ServantError a)
+ Web.Telegram.API.Bot.API: runClient' :: TelegramClient a -> Token -> ClientEnv -> IO (Either ServantError a)
+ Web.Telegram.API.Bot.API: type TelegramClient a = ReaderT Token ClientM a
+ Web.Telegram.API.Bot.API.Chats: chatsApi :: Proxy TelegramBotChatsAPI
+ Web.Telegram.API.Bot.API.Chats: getChat :: Token -> Text -> Manager -> IO (Either ServantError GetChatResponse)
+ Web.Telegram.API.Bot.API.Chats: getChatAdministrators :: Token -> Text -> Manager -> IO (Either ServantError GetChatAdministratorsResponse)
+ Web.Telegram.API.Bot.API.Chats: getChatAdministratorsM :: Text -> TelegramClient GetChatAdministratorsResponse
+ Web.Telegram.API.Bot.API.Chats: getChatM :: Text -> TelegramClient GetChatResponse
+ Web.Telegram.API.Bot.API.Chats: getChatMember :: Token -> Text -> Int -> Manager -> IO (Either ServantError GetChatMemberResponse)
+ Web.Telegram.API.Bot.API.Chats: getChatMemberM :: Text -> Int -> TelegramClient GetChatMemberResponse
+ Web.Telegram.API.Bot.API.Chats: getChatMembersCount :: Token -> Text -> Manager -> IO (Either ServantError GetChatMembersCountResponse)
+ Web.Telegram.API.Bot.API.Chats: getChatMembersCountM :: Text -> TelegramClient GetChatMembersCountResponse
+ Web.Telegram.API.Bot.API.Chats: kickChatMember :: Token -> Text -> Int -> Manager -> IO (Either ServantError KickChatMemberResponse)
+ Web.Telegram.API.Bot.API.Chats: kickChatMemberM :: Text -> Int -> TelegramClient KickChatMemberResponse
+ Web.Telegram.API.Bot.API.Chats: leaveChat :: Token -> Text -> Manager -> IO (Either ServantError LeaveChatResponse)
+ Web.Telegram.API.Bot.API.Chats: leaveChatM :: Text -> TelegramClient LeaveChatResponse
+ Web.Telegram.API.Bot.API.Chats: type TelegramBotChatsAPI = (TelegramToken :> ("kickChatMember" :> (QueryParam "chat_id" Text :> (QueryParam "user_id" Int :> Post '[JSON] KickChatMemberResponse)))) :<|> ((TelegramToken :> ("leaveChat" :> (QueryParam "chat_id" Text :> Post '[JSON] LeaveChatResponse))) :<|> ((TelegramToken :> ("unbanChatMember" :> (QueryParam "chat_id" Text :> (QueryParam "user_id" Int :> Post '[JSON] UnbanChatMemberResponse)))) :<|> ((TelegramToken :> ("getChat" :> (QueryParam "chat_id" Text :> Post '[JSON] GetChatResponse))) :<|> ((TelegramToken :> ("getChatAdministrators" :> (QueryParam "chat_id" Text :> Post '[JSON] GetChatAdministratorsResponse))) :<|> ((TelegramToken :> ("getChatMembersCount" :> (QueryParam "chat_id" Text :> Post '[JSON] GetChatMembersCountResponse))) :<|> (TelegramToken :> ("getChatMember" :> (QueryParam "chat_id" Text :> (QueryParam "user_id" Int :> Post '[JSON] GetChatMemberResponse)))))))))
+ Web.Telegram.API.Bot.API.Chats: unbanChatMember :: Token -> Text -> Int -> Manager -> IO (Either ServantError UnbanChatMemberResponse)
+ Web.Telegram.API.Bot.API.Chats: unbanChatMemberM :: Text -> Int -> TelegramClient UnbanChatMemberResponse
+ Web.Telegram.API.Bot.API.Edit: editApi :: Proxy TelegramBotEditAPI
+ Web.Telegram.API.Bot.API.Edit: editInlineMessageCaption :: Token -> EditMessageCaptionRequest -> Manager -> IO (Either ServantError (Response Bool))
+ Web.Telegram.API.Bot.API.Edit: editInlineMessageCaptionM :: EditMessageCaptionRequest -> TelegramClient (Response Bool)
+ Web.Telegram.API.Bot.API.Edit: editInlineMessageReplyMarkup :: Token -> EditMessageReplyMarkupRequest -> Manager -> IO (Either ServantError (Response Bool))
+ Web.Telegram.API.Bot.API.Edit: editInlineMessageReplyMarkupM :: EditMessageReplyMarkupRequest -> TelegramClient (Response Bool)
+ Web.Telegram.API.Bot.API.Edit: editInlineMessageText :: Token -> EditMessageTextRequest -> Manager -> IO (Either ServantError (Response Bool))
+ Web.Telegram.API.Bot.API.Edit: editInlineMessageTextM :: EditMessageTextRequest -> TelegramClient (Response Bool)
+ Web.Telegram.API.Bot.API.Edit: editMessageCaption :: Token -> EditMessageCaptionRequest -> Manager -> IO (Either ServantError MessageResponse)
+ Web.Telegram.API.Bot.API.Edit: editMessageCaptionM :: EditMessageCaptionRequest -> TelegramClient MessageResponse
+ Web.Telegram.API.Bot.API.Edit: editMessageReplyMarkup :: Token -> EditMessageReplyMarkupRequest -> Manager -> IO (Either ServantError MessageResponse)
+ Web.Telegram.API.Bot.API.Edit: editMessageReplyMarkupM :: EditMessageReplyMarkupRequest -> TelegramClient MessageResponse
+ Web.Telegram.API.Bot.API.Edit: editMessageText :: Token -> EditMessageTextRequest -> Manager -> IO (Either ServantError MessageResponse)
+ Web.Telegram.API.Bot.API.Edit: editMessageTextM :: EditMessageTextRequest -> TelegramClient MessageResponse
+ Web.Telegram.API.Bot.API.Edit: type TelegramBotEditAPI = (TelegramToken :> ("editMessageText" :> (ReqBody '[JSON] EditMessageTextRequest :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("editMessageCaption" :> (ReqBody '[JSON] EditMessageCaptionRequest :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("editMessageReplyMarkup" :> (ReqBody '[JSON] EditMessageReplyMarkupRequest :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("editMessageText" :> (ReqBody '[JSON] EditMessageTextRequest :> Post '[JSON] (Response Bool)))) :<|> ((TelegramToken :> ("editMessageCaption" :> (ReqBody '[JSON] EditMessageCaptionRequest :> Post '[JSON] (Response Bool)))) :<|> (TelegramToken :> ("editMessageReplyMarkup" :> (ReqBody '[JSON] EditMessageReplyMarkupRequest :> Post '[JSON] (Response Bool))))))))
+ Web.Telegram.API.Bot.API.Get: getApi :: Proxy TelegramBotGetAPI
+ Web.Telegram.API.Bot.API.Get: getFile :: Token -> Text -> Manager -> IO (Either ServantError FileResponse)
+ Web.Telegram.API.Bot.API.Get: getFileM :: Text -> TelegramClient FileResponse
+ Web.Telegram.API.Bot.API.Get: getMe :: Token -> Manager -> IO (Either ServantError GetMeResponse)
+ Web.Telegram.API.Bot.API.Get: getMeM :: TelegramClient GetMeResponse
+ Web.Telegram.API.Bot.API.Get: getUserProfilePhotos :: Token -> Int -> Maybe Int -> Maybe Int -> Manager -> IO (Either ServantError UserProfilePhotosResponse)
+ Web.Telegram.API.Bot.API.Get: getUserProfilePhotosM :: Int -> Maybe Int -> Maybe Int -> TelegramClient UserProfilePhotosResponse
+ Web.Telegram.API.Bot.API.Get: type TelegramBotGetAPI = (TelegramToken :> ("getMe" :> Get '[JSON] GetMeResponse)) :<|> ((TelegramToken :> ("getFile" :> (QueryParam "file_id" Text :> Get '[JSON] FileResponse))) :<|> (TelegramToken :> ("getUserProfilePhotos" :> (QueryParam "user_id" Int :> (QueryParam "offset" Int :> (QueryParam "limit" Int :> Get '[JSON] UserProfilePhotosResponse))))))
+ Web.Telegram.API.Bot.API.Messages: forwardMessage :: Token -> ForwardMessageRequest -> Manager -> IO (Either ServantError MessageResponse)
+ Web.Telegram.API.Bot.API.Messages: forwardMessageM :: ForwardMessageRequest -> TelegramClient MessageResponse
+ Web.Telegram.API.Bot.API.Messages: messagesApi :: Proxy TelegramBotMessagesAPI
+ Web.Telegram.API.Bot.API.Messages: sendAudio :: Token -> SendAudioRequest Text -> Manager -> IO (Either ServantError MessageResponse)
+ Web.Telegram.API.Bot.API.Messages: sendAudioM :: SendAudioRequest Text -> TelegramClient MessageResponse
+ Web.Telegram.API.Bot.API.Messages: sendChatAction :: Token -> SendChatActionRequest -> Manager -> IO (Either ServantError ChatActionResponse)
+ Web.Telegram.API.Bot.API.Messages: sendChatActionM :: SendChatActionRequest -> TelegramClient ChatActionResponse
+ Web.Telegram.API.Bot.API.Messages: sendContact :: Token -> SendContactRequest -> Manager -> IO (Either ServantError MessageResponse)
+ Web.Telegram.API.Bot.API.Messages: sendContactM :: SendContactRequest -> TelegramClient MessageResponse
+ Web.Telegram.API.Bot.API.Messages: sendDocument :: Token -> SendDocumentRequest Text -> Manager -> IO (Either ServantError MessageResponse)
+ Web.Telegram.API.Bot.API.Messages: sendDocumentM :: SendDocumentRequest Text -> TelegramClient MessageResponse
+ Web.Telegram.API.Bot.API.Messages: sendGame :: Token -> SendGameRequest -> Manager -> IO (Either ServantError MessageResponse)
+ Web.Telegram.API.Bot.API.Messages: sendGameM :: SendGameRequest -> TelegramClient MessageResponse
+ Web.Telegram.API.Bot.API.Messages: sendLocation :: Token -> SendLocationRequest -> Manager -> IO (Either ServantError MessageResponse)
+ Web.Telegram.API.Bot.API.Messages: sendLocationM :: SendLocationRequest -> TelegramClient MessageResponse
+ Web.Telegram.API.Bot.API.Messages: sendMessage :: Token -> SendMessageRequest -> Manager -> IO (Either ServantError MessageResponse)
+ Web.Telegram.API.Bot.API.Messages: sendMessageM :: SendMessageRequest -> TelegramClient MessageResponse
+ Web.Telegram.API.Bot.API.Messages: sendPhoto :: Token -> SendPhotoRequest Text -> Manager -> IO (Either ServantError MessageResponse)
+ Web.Telegram.API.Bot.API.Messages: sendPhotoM :: SendPhotoRequest Text -> TelegramClient MessageResponse
+ Web.Telegram.API.Bot.API.Messages: sendSticker :: Token -> SendStickerRequest Text -> Manager -> IO (Either ServantError MessageResponse)
+ Web.Telegram.API.Bot.API.Messages: sendStickerM :: SendStickerRequest Text -> TelegramClient MessageResponse
+ Web.Telegram.API.Bot.API.Messages: sendVenue :: Token -> SendVenueRequest -> Manager -> IO (Either ServantError MessageResponse)
+ Web.Telegram.API.Bot.API.Messages: sendVenueM :: SendVenueRequest -> TelegramClient MessageResponse
+ Web.Telegram.API.Bot.API.Messages: sendVideo :: Token -> SendVideoRequest Text -> Manager -> IO (Either ServantError MessageResponse)
+ Web.Telegram.API.Bot.API.Messages: sendVideoM :: SendVideoRequest Text -> TelegramClient MessageResponse
+ Web.Telegram.API.Bot.API.Messages: sendVoice :: Token -> SendVoiceRequest Text -> Manager -> IO (Either ServantError MessageResponse)
+ Web.Telegram.API.Bot.API.Messages: sendVoiceM :: SendVoiceRequest Text -> TelegramClient MessageResponse
+ Web.Telegram.API.Bot.API.Messages: type TelegramBotMessagesAPI = (TelegramToken :> ("sendMessage" :> (ReqBody '[JSON] SendMessageRequest :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("forwardMessage" :> (ReqBody '[JSON] ForwardMessageRequest :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendPhoto" :> (MultipartFormDataReqBody (SendPhotoRequest FileUpload) :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendPhoto" :> (ReqBody '[JSON] (SendPhotoRequest Text) :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendAudio" :> (MultipartFormDataReqBody (SendAudioRequest FileUpload) :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendAudio" :> (ReqBody '[JSON] (SendAudioRequest Text) :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendDocument" :> (MultipartFormDataReqBody (SendDocumentRequest FileUpload) :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendDocument" :> (ReqBody '[JSON] (SendDocumentRequest Text) :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendSticker" :> (MultipartFormDataReqBody (SendStickerRequest FileUpload) :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendSticker" :> (ReqBody '[JSON] (SendStickerRequest Text) :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendVideo" :> (MultipartFormDataReqBody (SendVideoRequest FileUpload) :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendVideo" :> (ReqBody '[JSON] (SendVideoRequest Text) :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendVoice" :> (MultipartFormDataReqBody (SendVoiceRequest FileUpload) :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendVoice" :> (ReqBody '[JSON] (SendVoiceRequest Text) :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendLocation" :> (ReqBody '[JSON] SendLocationRequest :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendVenue" :> (ReqBody '[JSON] SendVenueRequest :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendContact" :> (ReqBody '[JSON] SendContactRequest :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendChatAction" :> (ReqBody '[JSON] SendChatActionRequest :> Post '[JSON] ChatActionResponse))) :<|> (TelegramToken :> ("sendGame" :> (ReqBody '[JSON] SendGameRequest :> Post '[JSON] MessageResponse))))))))))))))))))))
+ Web.Telegram.API.Bot.API.Messages: uploadAudio :: Token -> SendAudioRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse)
+ Web.Telegram.API.Bot.API.Messages: uploadAudioM :: SendAudioRequest FileUpload -> TelegramClient MessageResponse
+ Web.Telegram.API.Bot.API.Messages: uploadDocument :: Token -> SendDocumentRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse)
+ Web.Telegram.API.Bot.API.Messages: uploadDocumentM :: SendDocumentRequest FileUpload -> TelegramClient MessageResponse
+ Web.Telegram.API.Bot.API.Messages: uploadPhoto :: Token -> SendPhotoRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse)
+ Web.Telegram.API.Bot.API.Messages: uploadPhotoM :: SendPhotoRequest FileUpload -> TelegramClient MessageResponse
+ Web.Telegram.API.Bot.API.Messages: uploadSticker :: Token -> SendStickerRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse)
+ Web.Telegram.API.Bot.API.Messages: uploadStickerM :: SendStickerRequest FileUpload -> TelegramClient MessageResponse
+ Web.Telegram.API.Bot.API.Messages: uploadVideo :: Token -> SendVideoRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse)
+ Web.Telegram.API.Bot.API.Messages: uploadVideoM :: SendVideoRequest FileUpload -> TelegramClient MessageResponse
+ Web.Telegram.API.Bot.API.Messages: uploadVoice :: Token -> SendVoiceRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse)
+ Web.Telegram.API.Bot.API.Messages: uploadVoiceM :: SendVoiceRequest FileUpload -> TelegramClient MessageResponse
+ Web.Telegram.API.Bot.API.Queries: answerCallbackQuery :: Token -> AnswerCallbackQueryRequest -> Manager -> IO (Either ServantError CallbackQueryResponse)
+ Web.Telegram.API.Bot.API.Queries: answerCallbackQueryM :: AnswerCallbackQueryRequest -> TelegramClient CallbackQueryResponse
+ Web.Telegram.API.Bot.API.Queries: answerInlineQuery :: Token -> AnswerInlineQueryRequest -> Manager -> IO (Either ServantError InlineQueryResponse)
+ Web.Telegram.API.Bot.API.Queries: answerInlineQueryM :: AnswerInlineQueryRequest -> TelegramClient InlineQueryResponse
+ Web.Telegram.API.Bot.API.Queries: queriesApi :: Proxy TelegramBotQueriesAPI
+ Web.Telegram.API.Bot.API.Queries: type TelegramBotQueriesAPI = (TelegramToken :> ("answerInlineQuery" :> (ReqBody '[JSON] AnswerInlineQueryRequest :> Post '[JSON] InlineQueryResponse))) :<|> (TelegramToken :> ("answerCallbackQuery" :> (ReqBody '[JSON] AnswerCallbackQueryRequest :> Post '[JSON] CallbackQueryResponse)))
+ Web.Telegram.API.Bot.API.Updates: deleteWebhook :: Token -> Manager -> IO (Either ServantError (Response Bool))
+ Web.Telegram.API.Bot.API.Updates: deleteWebhookM :: TelegramClient (Response Bool)
+ Web.Telegram.API.Bot.API.Updates: getUpdates :: Token -> Maybe Int -> Maybe Int -> Maybe Int -> Manager -> IO (Either ServantError UpdatesResponse)
+ Web.Telegram.API.Bot.API.Updates: getUpdatesM :: TelegramClient UpdatesResponse
+ Web.Telegram.API.Bot.API.Updates: getWebhookInfo :: Token -> Manager -> IO (Either ServantError GetWebhookInfoResponse)
+ Web.Telegram.API.Bot.API.Updates: getWebhookInfoM :: TelegramClient GetWebhookInfoResponse
+ Web.Telegram.API.Bot.API.Updates: setWebhook :: Token -> Maybe Text -> Manager -> IO (Either ServantError SetWebhookResponse)
+ Web.Telegram.API.Bot.API.Updates: setWebhookM :: SetWebhookRequest -> TelegramClient SetWebhookResponse
+ Web.Telegram.API.Bot.API.Updates: setWebhookWithCertificate :: Token -> SetWebhookRequest -> Manager -> IO (Either ServantError SetWebhookResponse)
+ Web.Telegram.API.Bot.API.Updates: setWebhookWithCertificateM :: SetWebhookRequest -> TelegramClient SetWebhookResponse
+ Web.Telegram.API.Bot.API.Updates: type TelegramBotUpdatesAPI = (TelegramToken :> ("getUpdates" :> (ReqBody '[JSON] GetUpdatesRequest :> Get '[JSON] UpdatesResponse))) :<|> ((TelegramToken :> ("setWebhook" :> (ReqBody '[JSON] SetWebhookRequest :> Get '[JSON] SetWebhookResponse))) :<|> ((TelegramToken :> ("setWebhook" :> (MultipartFormDataReqBody SetWebhookRequest :> Post '[JSON] SetWebhookResponse))) :<|> ((TelegramToken :> ("deleteWebhook" :> Post '[JSON] (Response Bool))) :<|> (TelegramToken :> ("getWebhookInfo" :> Get '[JSON] GetWebhookInfoResponse)))))
+ Web.Telegram.API.Bot.API.Updates: updatesApi :: Proxy TelegramBotUpdatesAPI
+ Web.Telegram.API.Bot.Data: [whi_allowed_updates] :: WebhookInfo -> Maybe [Text]
+ Web.Telegram.API.Bot.Data: [whi_max_connections] :: WebhookInfo -> Maybe Int
+ Web.Telegram.API.Bot.Requests: GetUpdatesRequest :: Maybe Int -> Maybe Int -> Maybe Int -> Maybe [Text] -> GetUpdatesRequest
+ Web.Telegram.API.Bot.Requests: SetWebhookWithoutCertRequest :: Text -> Maybe Int -> Maybe [Text] -> SetWebhookRequest
+ Web.Telegram.API.Bot.Requests: [updates_allowed_updates] :: GetUpdatesRequest -> Maybe [Text]
+ Web.Telegram.API.Bot.Requests: [updates_limit] :: GetUpdatesRequest -> Maybe Int
+ Web.Telegram.API.Bot.Requests: [updates_offset] :: GetUpdatesRequest -> Maybe Int
+ Web.Telegram.API.Bot.Requests: [updates_timeout] :: GetUpdatesRequest -> Maybe Int
+ Web.Telegram.API.Bot.Requests: [webhook_allowed_updates] :: SetWebhookRequest -> Maybe [Text]
+ Web.Telegram.API.Bot.Requests: [webhook_max_connections] :: SetWebhookRequest -> Maybe Int
+ Web.Telegram.API.Bot.Requests: data GetUpdatesRequest
+ Web.Telegram.API.Bot.Requests: getUpdatesRequest :: GetUpdatesRequest
+ Web.Telegram.API.Bot.Requests: instance Data.Aeson.Types.FromJSON.FromJSON Web.Telegram.API.Bot.Requests.GetUpdatesRequest
+ Web.Telegram.API.Bot.Requests: instance Data.Aeson.Types.ToJSON.ToJSON Web.Telegram.API.Bot.Requests.GetUpdatesRequest
+ Web.Telegram.API.Bot.Requests: instance Data.Aeson.Types.ToJSON.ToJSON Web.Telegram.API.Bot.Requests.SetWebhookRequest
+ Web.Telegram.API.Bot.Requests: instance GHC.Generics.Generic Web.Telegram.API.Bot.Requests.GetUpdatesRequest
+ Web.Telegram.API.Bot.Requests: instance GHC.Generics.Generic Web.Telegram.API.Bot.Requests.SetWebhookRequest
+ Web.Telegram.API.Bot.Requests: instance GHC.Show.Show Web.Telegram.API.Bot.Requests.GetUpdatesRequest
+ Web.Telegram.API.Bot.Requests: setWebhookRequest' :: Text -> SetWebhookRequest
- Web.Telegram.API.Bot.API: type TelegramBotAPI = (TelegramToken :> ("getMe" :> Get '[JSON] GetMeResponse)) :<|> ((TelegramToken :> ("sendMessage" :> (ReqBody '[JSON] SendMessageRequest :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("forwardMessage" :> (ReqBody '[JSON] ForwardMessageRequest :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendPhoto" :> (MultipartFormDataReqBody (SendPhotoRequest FileUpload) :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendPhoto" :> (ReqBody '[JSON] (SendPhotoRequest Text) :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendAudio" :> (MultipartFormDataReqBody (SendAudioRequest FileUpload) :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendAudio" :> (ReqBody '[JSON] (SendAudioRequest Text) :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendDocument" :> (MultipartFormDataReqBody (SendDocumentRequest FileUpload) :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendDocument" :> (ReqBody '[JSON] (SendDocumentRequest Text) :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendSticker" :> (MultipartFormDataReqBody (SendStickerRequest FileUpload) :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendSticker" :> (ReqBody '[JSON] (SendStickerRequest Text) :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendVideo" :> (MultipartFormDataReqBody (SendVideoRequest FileUpload) :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendVideo" :> (ReqBody '[JSON] (SendVideoRequest Text) :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendVoice" :> (MultipartFormDataReqBody (SendVoiceRequest FileUpload) :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendVoice" :> (ReqBody '[JSON] (SendVoiceRequest Text) :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendLocation" :> (ReqBody '[JSON] SendLocationRequest :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendVenue" :> (ReqBody '[JSON] SendVenueRequest :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendContact" :> (ReqBody '[JSON] SendContactRequest :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("sendChatAction" :> (ReqBody '[JSON] SendChatActionRequest :> Post '[JSON] ChatActionResponse))) :<|> ((TelegramToken :> ("sendGame" :> (ReqBody '[JSON] SendGameRequest :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("getUpdates" :> (QueryParam "offset" Int :> (QueryParam "limit" Int :> (QueryParam "timeout" Int :> Get '[JSON] UpdatesResponse))))) :<|> ((TelegramToken :> ("getFile" :> (QueryParam "file_id" Text :> Get '[JSON] FileResponse))) :<|> ((TelegramToken :> ("getUserProfilePhotos" :> (QueryParam "user_id" Int :> (QueryParam "offset" Int :> (QueryParam "limit" Int :> Get '[JSON] UserProfilePhotosResponse))))) :<|> ((TelegramToken :> ("setWebhook" :> (QueryParam "url" Text :> Get '[JSON] SetWebhookResponse))) :<|> ((TelegramToken :> ("setWebhook" :> (MultipartFormDataReqBody SetWebhookRequest :> Post '[JSON] SetWebhookResponse))) :<|> ((TelegramToken :> ("deleteWebhook" :> Post '[JSON] (Response Bool))) :<|> ((TelegramToken :> ("getWebhookInfo" :> Get '[JSON] GetWebhookInfoResponse)) :<|> ((TelegramToken :> ("answerInlineQuery" :> (ReqBody '[JSON] AnswerInlineQueryRequest :> Post '[JSON] InlineQueryResponse))) :<|> ((TelegramToken :> ("answerCallbackQuery" :> (ReqBody '[JSON] AnswerCallbackQueryRequest :> Post '[JSON] CallbackQueryResponse))) :<|> ((TelegramToken :> ("kickChatMember" :> (QueryParam "chat_id" Text :> (QueryParam "user_id" Int :> Post '[JSON] KickChatMemberResponse)))) :<|> ((TelegramToken :> ("leaveChat" :> (QueryParam "chat_id" Text :> Post '[JSON] LeaveChatResponse))) :<|> ((TelegramToken :> ("unbanChatMember" :> (QueryParam "chat_id" Text :> (QueryParam "user_id" Int :> Post '[JSON] UnbanChatMemberResponse)))) :<|> ((TelegramToken :> ("getChat" :> (QueryParam "chat_id" Text :> Post '[JSON] GetChatResponse))) :<|> ((TelegramToken :> ("getChatAdministrators" :> (QueryParam "chat_id" Text :> Post '[JSON] GetChatAdministratorsResponse))) :<|> ((TelegramToken :> ("getChatMembersCount" :> (QueryParam "chat_id" Text :> Post '[JSON] GetChatMembersCountResponse))) :<|> ((TelegramToken :> ("getChatMember" :> (QueryParam "chat_id" Text :> (QueryParam "user_id" Int :> Post '[JSON] GetChatMemberResponse)))) :<|> ((TelegramToken :> ("editMessageText" :> (ReqBody '[JSON] EditMessageTextRequest :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("editMessageCaption" :> (ReqBody '[JSON] EditMessageCaptionRequest :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("editMessageReplyMarkup" :> (ReqBody '[JSON] EditMessageReplyMarkupRequest :> Post '[JSON] MessageResponse))) :<|> ((TelegramToken :> ("editMessageText" :> (ReqBody '[JSON] EditMessageTextRequest :> Post '[JSON] (Response Bool)))) :<|> ((TelegramToken :> ("editMessageCaption" :> (ReqBody '[JSON] EditMessageCaptionRequest :> Post '[JSON] (Response Bool)))) :<|> (TelegramToken :> ("editMessageReplyMarkup" :> (ReqBody '[JSON] EditMessageReplyMarkupRequest :> Post '[JSON] (Response Bool))))))))))))))))))))))))))))))))))))))))))))
+ Web.Telegram.API.Bot.API: type TelegramBotAPI = TelegramBotMessagesAPI :<|> (TelegramBotUpdatesAPI :<|> (TelegramBotChatsAPI :<|> (TelegramBotEditAPI :<|> (TelegramBotQueriesAPI :<|> TelegramBotGetAPI))))
- Web.Telegram.API.Bot.Data: WebhookInfo :: Text -> Bool -> Int -> Maybe Int -> Maybe Text -> WebhookInfo
+ Web.Telegram.API.Bot.Data: WebhookInfo :: Text -> Bool -> Int -> Maybe Int -> Maybe Text -> Maybe Int -> Maybe [Text] -> WebhookInfo
- Web.Telegram.API.Bot.Requests: SetWebhookRequest :: Text -> FileUpload -> SetWebhookRequest
+ Web.Telegram.API.Bot.Requests: SetWebhookRequest :: Text -> FileUpload -> Maybe Int -> SetWebhookRequest
Files
- CHANGELOG.md +6/−0
- README.md +31/−4
- src/Web/Telegram/API/Bot/API.hs +20/−469
- src/Web/Telegram/API/Bot/API/Chats.hs +134/−0
- src/Web/Telegram/API/Bot/API/Core.hs +58/−0
- src/Web/Telegram/API/Bot/API/Edit.hs +118/−0
- src/Web/Telegram/API/Bot/API/Get.hs +75/−0
- src/Web/Telegram/API/Bot/API/Messages.hs +321/−0
- src/Web/Telegram/API/Bot/API/Queries.hs +58/−0
- src/Web/Telegram/API/Bot/API/Updates.hs +121/−0
- src/Web/Telegram/API/Bot/Data.hs +2/−0
- src/Web/Telegram/API/Bot/Requests.hs +133/−91
- src/Web/Telegram/API/Bot/Responses.hs +4/−4
- telegram-api.cabal +9/−1
- test/InlineSpec.hs +4/−4
- test/JsonSpec.hs +4/−4
- test/MainSpec.hs +11/−10
- test/Spec.hs +6/−4
- test/UpdatesSpec.hs +72/−0
CHANGELOG.md view
@@ -1,3 +1,9 @@+## 0.6.0.0 + +* Added `TelegramClient`, see example of usage in README.md +* Changes from December update of Telegram Bot API +* `TelegramBotAPI` splitted in separate sub-types + ## 0.5.2.0 Features:
README.md view
@@ -9,7 +9,7 @@  High-level bindings to the [Telegram Bot API][telegram-bot-api] based on [servant][servant] library. -Both `getUpdates` request or webhook can be used to receive updates for your bot. +Both `getUpdates` request or webhook can be used to receive updates for your bot. 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. @@ -17,6 +17,33 @@ ## Usage +There are two ways of using Telegram Bot API. First and original way is to run IO directly for every Telegram servers request, another one is based on `TelegramClient` which is just `ReaderT`. + +### Use `TelegramClient` + +```haskell +{-# LANGUAGE OverloadedStrings #-} + +import Network.HTTP.Client (newManager) +import Network.HTTP.Client.TLS (tlsManagerSettings) +import Web.Telegram.API.Bot +import Control.Monad (when) + +main :: IO () +main = do + let token = Token "bot<token>" -- entire Token should be bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11 + manager <- newManager tlsManagerSettings + result <- runClient ( do + info <- getWebhookInfoM + let request = setWebhookRequest' "https://example.com/hook" + isSet <- setWebhookM request + getMeM) token manager + print result + print "done!" +``` + +### Runing IO directly + `getMe` example ```haskell @@ -34,7 +61,7 @@ Left e -> do putStrLn "Request failed" print e - Right GetMeResponse { user_result = u } -> do + Right Response { result = u } -> do putStrLn "Request succeded" print $ user_first_name u where token = Token "bot<token>" -- entire Token should be bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11 @@ -58,12 +85,12 @@ Left e -> do putStrLn "Request failed" print e - Right MessageResponse { message_result = m } -> do + Right Response { result = m } -> do putStrLn "Request succeded" print $ message_id m print $ text m where token = Token "bot<token>" -- entire Token should be bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11 - chatId = "<chat_id> or <@channelusername>" + chatId = "<chat_id> or <@channelusername>" message = "text *bold* _italic_ [github](github.com/klappvisor/haskell-telegram-api)" ```
src/Web/Telegram/API/Bot/API.hs view
@@ -1,487 +1,38 @@-{-# LANGUAGE DataKinds #-} -{-# LANGUAGE GeneralizedNewtypeDeriving #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TypeOperators #-} module Web.Telegram.API.Bot.API ( -- * Functions - getMe - , sendMessage - , forwardMessage - , uploadPhoto - , sendPhoto - , uploadAudio - , sendAudio - , uploadDocument - , sendDocument - , uploadSticker - , sendSticker - , uploadVideo - , sendVideo - , uploadVoice - , sendVoice - , sendLocation - , sendVenue - , sendContact - , sendChatAction - , sendGame - , getUpdates - , getFile - , getUserProfilePhotos - , setWebhook - , setWebhookWithCertificate - , deleteWebhook - , getWebhookInfo - , answerInlineQuery - , answerCallbackQuery - , kickChatMember - , leaveChat - , unbanChatMember - , getChat - , getChatAdministrators - , getChatMembersCount - , getChatMember - , editMessageText - , editMessageCaption - , editMessageReplyMarkup - , editInlineMessageText - , editInlineMessageCaption - , editInlineMessageReplyMarkup + module API + , runClient + , runClient' -- * API , TelegramBotAPI , api -- * Types , Token (..) + , TelegramClient ) where import Data.Proxy -import Data.Text (Text) -import Network.HTTP.Client (Manager) import Servant.API -import Servant.Client -import Servant.Client.MultipartFormData -import Web.Telegram.API.Bot.Responses -import Web.Telegram.API.Bot.Requests - --- | Telegram Bot's Token -newtype Token = Token Text - deriving (Show, Eq, Ord, ToHttpApiData, FromHttpApiData) - -telegramBaseUrl :: BaseUrl -telegramBaseUrl = BaseUrl Https "api.telegram.org" 443 "" - --- | Type for token -type TelegramToken = Capture ":token" Token +import Web.Telegram.API.Bot.API.Chats as API +import Web.Telegram.API.Bot.API.Core +import Web.Telegram.API.Bot.API.Edit as API +import Web.Telegram.API.Bot.API.Get as API +import Web.Telegram.API.Bot.API.Messages as API +import Web.Telegram.API.Bot.API.Queries as API +import Web.Telegram.API.Bot.API.Updates as API --- | Telegram Bot API type TelegramBotAPI = - TelegramToken :> "getMe" - :> Get '[JSON] GetMeResponse - :<|> TelegramToken :> "sendMessage" - :> ReqBody '[JSON] SendMessageRequest - :> Post '[JSON] MessageResponse - :<|> TelegramToken :> "forwardMessage" - :> ReqBody '[JSON] ForwardMessageRequest - :> Post '[JSON] MessageResponse - :<|> TelegramToken :> "sendPhoto" - :> MultipartFormDataReqBody (SendPhotoRequest FileUpload) - :> Post '[JSON] MessageResponse - :<|> TelegramToken :> "sendPhoto" - :> ReqBody '[JSON] (SendPhotoRequest Text) - :> Post '[JSON] MessageResponse - :<|> TelegramToken :> "sendAudio" - :> MultipartFormDataReqBody (SendAudioRequest FileUpload) - :> Post '[JSON] MessageResponse - :<|> TelegramToken :> "sendAudio" - :> ReqBody '[JSON] (SendAudioRequest Text) - :> Post '[JSON] MessageResponse - :<|> TelegramToken :> "sendDocument" - :> MultipartFormDataReqBody (SendDocumentRequest FileUpload) - :> Post '[JSON] MessageResponse - :<|> TelegramToken :> "sendDocument" - :> ReqBody '[JSON] (SendDocumentRequest Text) - :> Post '[JSON] MessageResponse - :<|> TelegramToken :> "sendSticker" - :> MultipartFormDataReqBody (SendStickerRequest FileUpload) - :> Post '[JSON] MessageResponse - :<|> TelegramToken :> "sendSticker" - :> ReqBody '[JSON] (SendStickerRequest Text) - :> Post '[JSON] MessageResponse - :<|> TelegramToken :> "sendVideo" - :> MultipartFormDataReqBody (SendVideoRequest FileUpload) - :> Post '[JSON] MessageResponse - :<|> TelegramToken :> "sendVideo" - :> ReqBody '[JSON] (SendVideoRequest Text) - :> Post '[JSON] MessageResponse - :<|> TelegramToken :> "sendVoice" - :> MultipartFormDataReqBody (SendVoiceRequest FileUpload) - :> Post '[JSON] MessageResponse - :<|> TelegramToken :> "sendVoice" - :> ReqBody '[JSON] (SendVoiceRequest Text) - :> Post '[JSON] MessageResponse - :<|> TelegramToken :> "sendLocation" - :> ReqBody '[JSON] SendLocationRequest - :> Post '[JSON] MessageResponse - :<|> TelegramToken :> "sendVenue" - :> ReqBody '[JSON] SendVenueRequest - :> Post '[JSON] MessageResponse - :<|> TelegramToken :> "sendContact" - :> ReqBody '[JSON] SendContactRequest - :> Post '[JSON] MessageResponse - :<|> TelegramToken :> "sendChatAction" - :> ReqBody '[JSON] SendChatActionRequest - :> Post '[JSON] ChatActionResponse - :<|> TelegramToken :> "sendGame" - :> ReqBody '[JSON] SendGameRequest - :> Post '[JSON] MessageResponse - :<|> TelegramToken :> "getUpdates" - :> QueryParam "offset" Int - :> QueryParam "limit" Int - :> QueryParam "timeout" Int - :> Get '[JSON] UpdatesResponse - :<|> TelegramToken :> "getFile" - :> QueryParam "file_id" Text - :> Get '[JSON] FileResponse - :<|> TelegramToken :> "getUserProfilePhotos" - :> QueryParam "user_id" Int - :> QueryParam "offset" Int - :> QueryParam "limit" Int - :> Get '[JSON] UserProfilePhotosResponse - :<|> TelegramToken :> "setWebhook" - :> QueryParam "url" Text - :> Get '[JSON] SetWebhookResponse - :<|> TelegramToken :> "setWebhook" - :> MultipartFormDataReqBody SetWebhookRequest - :> Post '[JSON] SetWebhookResponse - :<|> TelegramToken :> "deleteWebhook" - :> Post '[JSON] (Response Bool) - :<|> TelegramToken :> "getWebhookInfo" - :> Get '[JSON] GetWebhookInfoResponse - :<|> TelegramToken :> "answerInlineQuery" - :> ReqBody '[JSON] AnswerInlineQueryRequest - :> Post '[JSON] InlineQueryResponse - :<|> TelegramToken :> "answerCallbackQuery" - :> ReqBody '[JSON] AnswerCallbackQueryRequest - :> Post '[JSON] CallbackQueryResponse - :<|> TelegramToken :> "kickChatMember" - :> QueryParam "chat_id" Text - :> QueryParam "user_id" Int - :> Post '[JSON] KickChatMemberResponse - :<|> TelegramToken :> "leaveChat" - :> QueryParam "chat_id" Text - :> Post '[JSON] LeaveChatResponse - :<|> TelegramToken :> "unbanChatMember" - :> QueryParam "chat_id" Text - :> QueryParam "user_id" Int - :> Post '[JSON] UnbanChatMemberResponse - :<|> TelegramToken :> "getChat" - :> QueryParam "chat_id" Text - :> Post '[JSON] GetChatResponse - :<|> TelegramToken :> "getChatAdministrators" - :> QueryParam "chat_id" Text - :> Post '[JSON] GetChatAdministratorsResponse - :<|> TelegramToken :> "getChatMembersCount" - :> QueryParam "chat_id" Text - :> Post '[JSON] GetChatMembersCountResponse - :<|> TelegramToken :> "getChatMember" - :> QueryParam "chat_id" Text - :> QueryParam "user_id" Int - :> Post '[JSON] GetChatMemberResponse - :<|> TelegramToken :> "editMessageText" - :> ReqBody '[JSON] EditMessageTextRequest - :> Post '[JSON] MessageResponse - :<|> TelegramToken :> "editMessageCaption" - :> ReqBody '[JSON] EditMessageCaptionRequest - :> Post '[JSON] MessageResponse - :<|> TelegramToken :> "editMessageReplyMarkup" - :> ReqBody '[JSON] EditMessageReplyMarkupRequest - :> Post '[JSON] MessageResponse - :<|> TelegramToken :> "editMessageText" - :> ReqBody '[JSON] EditMessageTextRequest - :> Post '[JSON] (Response Bool) - :<|> TelegramToken :> "editMessageCaption" - :> ReqBody '[JSON] EditMessageCaptionRequest - :> Post '[JSON] (Response Bool) - :<|> TelegramToken :> "editMessageReplyMarkup" - :> ReqBody '[JSON] EditMessageReplyMarkupRequest - :> Post '[JSON] (Response Bool) + TelegramBotMessagesAPI + :<|> TelegramBotUpdatesAPI + :<|> TelegramBotChatsAPI + :<|> TelegramBotEditAPI + :<|> TelegramBotQueriesAPI + :<|> TelegramBotGetAPI -- | Proxy for Thelegram Bot API api :: Proxy TelegramBotAPI api = Proxy - -getMe_ :: Token -> ClientM GetMeResponse -sendMessage_ :: Token -> SendMessageRequest -> ClientM MessageResponse -forwardMessage_ :: Token -> ForwardMessageRequest -> ClientM MessageResponse -uploadPhoto_ :: Token -> SendPhotoRequest FileUpload -> ClientM MessageResponse -sendPhoto_ :: Token -> SendPhotoRequest Text -> ClientM MessageResponse -uploadAudio_ :: Token -> SendAudioRequest FileUpload -> ClientM MessageResponse -sendAudio_ :: Token -> SendAudioRequest Text -> ClientM MessageResponse -uploadDocument_ :: Token -> SendDocumentRequest FileUpload -> ClientM MessageResponse -sendDocument_ :: Token -> SendDocumentRequest Text -> ClientM MessageResponse -uploadSticker_ :: Token -> SendStickerRequest FileUpload -> ClientM MessageResponse -sendSticker_ :: Token -> SendStickerRequest Text -> ClientM MessageResponse -uploadVideo_ :: Token -> SendVideoRequest FileUpload -> ClientM MessageResponse -sendVideo_ :: Token -> SendVideoRequest Text -> ClientM MessageResponse -uploadVoice_ :: Token -> SendVoiceRequest FileUpload -> ClientM MessageResponse -sendVoice_ :: Token -> SendVoiceRequest Text -> ClientM MessageResponse -sendLocation_ :: Token -> SendLocationRequest -> ClientM MessageResponse -sendVenue_ :: Token -> SendVenueRequest-> ClientM MessageResponse -sendContact_ :: Token -> SendContactRequest -> ClientM MessageResponse -sendChatAction_ :: Token -> SendChatActionRequest -> ClientM ChatActionResponse -sendGame_ :: Token -> SendGameRequest -> ClientM MessageResponse -getUpdates_ :: Token -> Maybe Int -> Maybe Int -> Maybe Int -> ClientM UpdatesResponse -getFile_ :: Token -> Maybe Text -> ClientM FileResponse -getUserProfilePhotos_ :: Token -> Maybe Int -> Maybe Int -> Maybe Int -> ClientM UserProfilePhotosResponse -setWebhook_ :: Token -> Maybe Text -> ClientM SetWebhookResponse -setWebhookWithCert_ :: Token -> SetWebhookRequest -> ClientM SetWebhookResponse -deleteWebhook_ :: Token -> ClientM (Response Bool) -getWebhookInfo_ :: Token -> ClientM GetWebhookInfoResponse -answerInlineQuery_ :: Token -> AnswerInlineQueryRequest -> ClientM InlineQueryResponse -answerCallbackQuery_ :: Token -> AnswerCallbackQueryRequest -> ClientM CallbackQueryResponse -kickChatMember_ :: Token -> Maybe Text -> Maybe Int -> ClientM KickChatMemberResponse -leaveChat_ :: Token -> Maybe Text -> ClientM LeaveChatResponse -unbanChatMember_ :: Token -> Maybe Text -> Maybe Int -> ClientM UnbanChatMemberResponse -getChat_ :: Token -> Maybe Text -> ClientM GetChatResponse -getChatAdministrators_ :: Token -> Maybe Text -> ClientM GetChatAdministratorsResponse -getChatMembersCount_ :: Token -> Maybe Text -> ClientM GetChatMembersCountResponse -getChatMember_ :: Token -> Maybe Text -> Maybe Int -> ClientM GetChatMemberResponse -editMessageText_ :: Token -> EditMessageTextRequest -> ClientM MessageResponse -editMessageCaption_ :: Token -> EditMessageCaptionRequest -> ClientM MessageResponse -editMessageReplyMarkup_ :: Token -> EditMessageReplyMarkupRequest -> ClientM MessageResponse -editMessageText__ :: Token -> EditMessageTextRequest -> ClientM (Response Bool) -editMessageCaption__ :: Token -> EditMessageCaptionRequest -> ClientM (Response Bool) -editMessageReplyMarkup__ :: Token -> EditMessageReplyMarkupRequest -> ClientM (Response Bool) -getMe_ - :<|> sendMessage_ - :<|> forwardMessage_ - :<|> uploadPhoto_ - :<|> sendPhoto_ - :<|> uploadAudio_ - :<|> sendAudio_ - :<|> uploadDocument_ - :<|> sendDocument_ - :<|> uploadSticker_ - :<|> sendSticker_ - :<|> uploadVideo_ - :<|> sendVideo_ - :<|> uploadVoice_ - :<|> sendVoice_ - :<|> sendLocation_ - :<|> sendVenue_ - :<|> sendContact_ - :<|> sendChatAction_ - :<|> sendGame_ - :<|> getUpdates_ - :<|> getFile_ - :<|> getUserProfilePhotos_ - :<|> setWebhook_ - :<|> setWebhookWithCert_ - :<|> deleteWebhook_ - :<|> getWebhookInfo_ - :<|> answerInlineQuery_ - :<|> answerCallbackQuery_ - :<|> kickChatMember_ - :<|> leaveChat_ - :<|> unbanChatMember_ - :<|> getChat_ - :<|> getChatAdministrators_ - :<|> getChatMembersCount_ - :<|> getChatMember_ - :<|> editMessageText_ - :<|> editMessageCaption_ - :<|> editMessageReplyMarkup_ - :<|> editMessageText__ - :<|> editMessageCaption__ - :<|> editMessageReplyMarkup__ = - client api - --- | A simple method for testing your bot's auth token. Requires no parameters. --- Returns basic information about the bot in form of a 'User' object. -getMe :: Token -> Manager -> IO (Either ServantError GetMeResponse) -getMe token manager = runClientM (getMe_ token) (ClientEnv manager telegramBaseUrl) - --- | Use this method to send text messages. On success, the sent 'Message' is returned. -sendMessage :: Token -> SendMessageRequest -> Manager -> IO (Either ServantError MessageResponse) -sendMessage = run telegramBaseUrl sendMessage_ - --- | Use this method to forward messages of any kind. On success, the sent 'Message' is returned. -forwardMessage :: Token -> ForwardMessageRequest -> Manager -> IO (Either ServantError MessageResponse) -forwardMessage = run telegramBaseUrl forwardMessage_ - --- | Use this method to upload and send photos. On success, the sent 'Message' is returned. -uploadPhoto :: Token -> SendPhotoRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse) -uploadPhoto = run telegramBaseUrl uploadPhoto_ - --- | Use this method to send photos that have already been uploaded. On success, the sent 'Message' is returned. -sendPhoto :: Token -> SendPhotoRequest Text -> Manager -> IO (Either ServantError MessageResponse) -sendPhoto = run telegramBaseUrl sendPhoto_ - --- | Use this method to upload and send audio files, if you want Telegram clients to display them in the music player. Your audio must be in the .mp3 format. On success, the sent 'Message' is returned. Bots can currently send audio files of up to 50 MB in size, this limit may be changed in the future. --- --- For backward compatibility, when the fields __title__ and __performer__ are both empty and the mime-type of the file to be sent is not _audio/mpeg_, the file will be sent as a playable voice message. For this to work, the audio must be in an .ogg file encoded with OPUS. This behavior will be phased out in the future. For sending voice messages, use the 'sendVoice' method instead. -uploadAudio :: Token -> SendAudioRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse) -uploadAudio = run telegramBaseUrl uploadAudio_ - --- | Use this method to send audio files that are already on the Telegram servers, if you want Telegram clients to display them in the music player. Your audio must be in the .mp3 format. On success, the sent 'Message' is returned. Bots can currently send audio files of up to 50 MB in size, this limit may be changed in the future. --- --- For backward compatibility, when the fields __title__ and __performer__ are both empty and the mime-type of the file to be sent is not _audio/mpeg_, the file will be sent as a playable voice message. For this to work, the audio must be in an .ogg file encoded with OPUS. This behavior will be phased out in the future. For sending voice messages, use the 'sendVoice' method instead. -sendAudio :: Token -> SendAudioRequest Text -> Manager -> IO (Either ServantError MessageResponse) -sendAudio = run telegramBaseUrl sendAudio_ - --- | Use this method to upload and send general files. On success, the sent 'Message' is returned. Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future. -uploadDocument :: Token -> SendDocumentRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse) -uploadDocument = run telegramBaseUrl uploadDocument_ - --- | Use this method to send general files that have already been uploaded. On success, the sent 'Message' is returned. Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future. -sendDocument :: Token -> SendDocumentRequest Text -> Manager -> IO (Either ServantError MessageResponse) -sendDocument = run telegramBaseUrl sendDocument_ - --- | Use this method to upload and send .webp stickers. On success, the sent 'Message' is returned. -uploadSticker :: Token -> SendStickerRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse) -uploadSticker = run telegramBaseUrl uploadSticker_ - --- | Use this method to send .webp stickers that are already on the Telegram servers. On success, the sent 'Message' is returned. -sendSticker :: Token -> SendStickerRequest Text -> Manager -> IO (Either ServantError MessageResponse) -sendSticker = run telegramBaseUrl sendSticker_ - --- | Use this method to upload and send video files. Telegram clients support mp4 videos (other formats may be sent as 'Document'). On success, the sent 'Message' is returned. Bots can currently send video files of up to 50 MB in size, this limit may be changed in the future. -uploadVideo :: Token -> SendVideoRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse) -uploadVideo = run telegramBaseUrl uploadVideo_ - --- | Use this method to send video files that are already on the Telegram servers. Telegram clients support mp4 videos (other formats may be sent as 'Document'). On success, the sent 'Message' is returned. Bots can currently send video files of up to 50 MB in size, this limit may be changed in the future. -sendVideo :: Token -> SendVideoRequest Text -> Manager -> IO (Either ServantError MessageResponse) -sendVideo = run telegramBaseUrl sendVideo_ - --- | Use this method to upload and send audio files, if you want Telegram clients to display the file as a playable voice message. For this to work, your audio must be in an .ogg file encoded with OPUS (other formats may be sent as 'Audio' or 'Document'). On success, the sent 'Message' is returned. Bots can currently send voice messages of up to 50 MB in size, this limit may be changed in the future. -uploadVoice :: Token -> SendVoiceRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse) -uploadVoice = run telegramBaseUrl uploadVoice_ - --- | Use this method to send audio files that are already on the telegram server, if you want Telegram clients to display the file as a playable voice message. For this to work, your audio must be in an .ogg file encoded with OPUS (other formats may be sent as 'Audio' or 'Document'). On success, the sent 'Message' is returned. Bots can currently send voice messages of up to 50 MB in size, this limit may be changed in the future. -sendVoice :: Token -> SendVoiceRequest Text -> Manager -> IO (Either ServantError MessageResponse) -sendVoice = run telegramBaseUrl sendVoice_ - --- | Use this method to send point on the map. On success, the sent 'Message' is returned. -sendLocation :: Token -> SendLocationRequest -> Manager -> IO (Either ServantError MessageResponse) -sendLocation = run telegramBaseUrl sendLocation_ - --- | Use this method to send information about a venue. On success, the sent 'Message' is returned. -sendVenue :: Token -> SendVenueRequest -> Manager -> IO (Either ServantError MessageResponse) -sendVenue = run telegramBaseUrl sendVenue_ - --- | Use this method to send information about a venue. On success, the sent 'Message' is returned. -sendContact :: Token -> SendContactRequest -> Manager -> IO (Either ServantError MessageResponse) -sendContact = run telegramBaseUrl sendContact_ - --- | Use this method when you need to tell the user that something is happening on the bot's side. --- The status is set for 5 seconds or less (when a message arrives from your bot, --- Telegram clients clear its typing status). -sendChatAction :: Token -> SendChatActionRequest -> Manager -> IO (Either ServantError ChatActionResponse) -sendChatAction = run telegramBaseUrl sendChatAction_ - --- | Use this method to send a game. On success, the sent 'Message' is returned. -sendGame :: Token -> SendGameRequest -> Manager -> IO (Either ServantError MessageResponse) -sendGame = run telegramBaseUrl sendGame_ - --- | Use this method to receive incoming updates using long polling. An Array of 'Update' objects is returned. -getUpdates - :: Token - -> Maybe Int -- ^ offset - -> Maybe Int -- ^ limit - -> Maybe Int -- ^ timeout - -> Manager - -> IO (Either ServantError UpdatesResponse) -getUpdates token offset limit timeout manager = runClientM (getUpdates_ token offset limit timeout) $ ClientEnv manager telegramBaseUrl - --- | Use this method to get basic info about a file and prepare it for downloading. For the moment, bots can download files of up to 20MB in size. On success, a 'File' object is returned. The file can then be downloaded via the link @https://api.telegram.org/file/bot<token>/<file_path>@, where @<file_path>@ is taken from the response. It is guaranteed that the link will be valid for at least 1 hour. When the link expires, a new one can be requested by calling getFile again. -getFile :: Token -> Text -> Manager -> IO (Either ServantError FileResponse) -getFile token file_id manager = runClientM (getFile_ token (Just file_id)) $ ClientEnv manager telegramBaseUrl - --- | Use this method to get a list of profile pictures for a user. Returns a 'UserProfilePhotos' object. -getUserProfilePhotos :: Token -> Int -> Maybe Int -> Maybe Int -> Manager -> IO (Either ServantError UserProfilePhotosResponse) -getUserProfilePhotos token user_id offset limit manager = runClientM (getUserProfilePhotos_ token (Just user_id) offset limit) $ ClientEnv manager telegramBaseUrl - --- | 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 - -> Manager - -> IO (Either ServantError SetWebhookResponse) -setWebhook token url manager = runClientM (setWebhook_ token url) $ ClientEnv manager telegramBaseUrl - --- | 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. -setWebhookWithCertificate :: Token -> SetWebhookRequest -> Manager -> IO (Either ServantError SetWebhookResponse) -setWebhookWithCertificate = run telegramBaseUrl setWebhookWithCert_ - -deleteWebhook :: Token -> Manager -> IO (Either ServantError (Response Bool)) -deleteWebhook token manager = runClientM (deleteWebhook_ token) $ ClientEnv manager telegramBaseUrl - --- | Contains information about the current status of a webhook. -getWebhookInfo :: Token -> Manager -> IO (Either ServantError GetWebhookInfoResponse) -getWebhookInfo token manager = runClientM (getWebhookInfo_ token) $ ClientEnv manager telegramBaseUrl - --- | Use this method to send answers to an inline query. No more than 50 results per query are allowed. -answerInlineQuery :: Token -> AnswerInlineQueryRequest -> Manager -> IO (Either ServantError InlineQueryResponse) -answerInlineQuery = run telegramBaseUrl answerInlineQuery_ - --- | Use this method to send answers to callback queries sent from inline keyboards. The answer will be displayed to the user as a notification at the top of the chat screen or as an alert. -answerCallbackQuery :: Token -> AnswerCallbackQueryRequest -> Manager -> IO (Either ServantError CallbackQueryResponse) -answerCallbackQuery = run telegramBaseUrl answerCallbackQuery_ - --- | Use this method to kick a user from a group or a supergroup. In the case of supergroups, the user will not be able to return to the group on their own using invite links, etc., unless unbanned first. The bot must be an administrator in the group for this to work. -kickChatMember :: Token -> Text -> Int -> Manager -> IO (Either ServantError KickChatMemberResponse) -kickChatMember token chat_id user_id manager = runClientM (kickChatMember_ token (Just chat_id) (Just user_id)) $ ClientEnv manager telegramBaseUrl - --- | Use this method for your bot to leave a group, supergroup or channel. Returns True on success. -leaveChat :: Token -> Text -> Manager -> IO (Either ServantError LeaveChatResponse) -leaveChat token chat_id manager = runClientM (leaveChat_ token (Just chat_id)) $ ClientEnv manager telegramBaseUrl - --- | Use this method to unban a previously kicked user in a supergroup. The user will not return to the group automatically, but will be able to join via link, etc. The bot must be an administrator in the group for this to work. -unbanChatMember :: Token -> Text -> Int -> Manager -> IO (Either ServantError UnbanChatMemberResponse) -unbanChatMember token chat_id user_id manager = runClientM (unbanChatMember_ token (Just chat_id) (Just user_id)) $ ClientEnv manager telegramBaseUrl - --- | Use this method to get up to date information about the chat (current name of the user for one-on-one conversations, current username of a user, group or channel, etc.) -getChat :: Token -> Text -> Manager -> IO (Either ServantError GetChatResponse) -getChat token chat_id manager = runClientM (getChat_ token (Just chat_id)) $ ClientEnv manager telegramBaseUrl - --- | Use this method to get a list of administrators in a chat. On success, returns an Array of 'ChatMember' objects that contains information about all chat administrators except other bots. If the chat is a group or a supergroup and no administrators were appointed, only the creator will be returned. -getChatAdministrators :: Token -> Text -> Manager -> IO (Either ServantError GetChatAdministratorsResponse) -getChatAdministrators token chat_id manager = runClientM (getChatAdministrators_ token (Just chat_id)) $ ClientEnv manager telegramBaseUrl - --- | Use this method to get the number of members in a chat. Returns 'Int' on success. -getChatMembersCount :: Token -> Text -> Manager -> IO (Either ServantError GetChatMembersCountResponse) -getChatMembersCount token chat_id manager = runClientM (getChatMembersCount_ token (Just chat_id)) $ ClientEnv manager telegramBaseUrl - --- | Use this method to get information about a member of a chat. Returns a 'ChatMember' object on success. -getChatMember :: Token -> Text -> Int -> Manager -> IO (Either ServantError GetChatMemberResponse) -getChatMember token chat_id user_id manager = runClientM (getChatMember_ token (Just chat_id) (Just user_id)) $ ClientEnv manager telegramBaseUrl - --- | Use this method to edit text messages sent by the bot. On success, the edited 'Message' is returned, otherwise True is returned. -editMessageText :: Token -> EditMessageTextRequest -> Manager -> IO (Either ServantError MessageResponse) -editMessageText = run telegramBaseUrl editMessageText_ - --- | Use this method to edit captions of messages sent by the bot. On success, the edited 'Message' is returned. -editMessageCaption :: Token -> EditMessageCaptionRequest -> Manager -> IO (Either ServantError MessageResponse) -editMessageCaption = run telegramBaseUrl editMessageCaption_ - --- | Use this method to edit only the reply markup of messages sent by the bot. On success, the edited 'Message' is returned. -editMessageReplyMarkup :: Token -> EditMessageReplyMarkupRequest -> Manager -> IO (Either ServantError MessageResponse) -editMessageReplyMarkup = run telegramBaseUrl editMessageReplyMarkup_ - --- | Use this method to edit text messages sent via the bot (for inline bots). -editInlineMessageText :: Token -> EditMessageTextRequest -> Manager -> IO (Either ServantError (Response Bool)) -editInlineMessageText = run telegramBaseUrl editMessageText__ - --- | Use this method to edit captions of messages sent via the bot (for inline bots). -editInlineMessageCaption :: Token -> EditMessageCaptionRequest -> Manager -> IO (Either ServantError (Response Bool)) -editInlineMessageCaption = run telegramBaseUrl editMessageCaption__ - --- | Use this method to edit only the reply markup of messages sent via the bot (for inline bots). -editInlineMessageReplyMarkup :: Token -> EditMessageReplyMarkupRequest -> Manager -> IO (Either ServantError (Response Bool)) -editInlineMessageReplyMarkup = run telegramBaseUrl editMessageReplyMarkup__ - -run :: BaseUrl -> (Token -> a -> ClientM b) -> Token -> a -> Manager -> IO (Either ServantError b) -run b e t r m = runClientM (e t r) (ClientEnv m b)
+ src/Web/Telegram/API/Bot/API/Chats.hs view
@@ -0,0 +1,134 @@+{-# LANGUAGE DataKinds #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TypeOperators #-} + +module Web.Telegram.API.Bot.API.Chats + ( -- * Functions + kickChatMember + , kickChatMemberM + , leaveChat + , leaveChatM + , unbanChatMember + , unbanChatMemberM + , getChat + , getChatM + , getChatAdministrators + , getChatAdministratorsM + , getChatMembersCount + , getChatMembersCountM + , getChatMember + , getChatMemberM + -- * API + , TelegramBotChatsAPI + , chatsApi + ) where + +import Data.Proxy +import Data.Text (Text) +import Network.HTTP.Client (Manager) +import Servant.API +import Servant.Client +import Web.Telegram.API.Bot.API.Core +import Web.Telegram.API.Bot.Responses + +-- | Telegram Bot API +type TelegramBotChatsAPI = + TelegramToken :> "kickChatMember" + :> QueryParam "chat_id" Text + :> QueryParam "user_id" Int + :> Post '[JSON] KickChatMemberResponse + :<|> TelegramToken :> "leaveChat" + :> QueryParam "chat_id" Text + :> Post '[JSON] LeaveChatResponse + :<|> TelegramToken :> "unbanChatMember" + :> QueryParam "chat_id" Text + :> QueryParam "user_id" Int + :> Post '[JSON] UnbanChatMemberResponse + :<|> TelegramToken :> "getChat" + :> QueryParam "chat_id" Text + :> Post '[JSON] GetChatResponse + :<|> TelegramToken :> "getChatAdministrators" + :> QueryParam "chat_id" Text + :> Post '[JSON] GetChatAdministratorsResponse + :<|> TelegramToken :> "getChatMembersCount" + :> QueryParam "chat_id" Text + :> Post '[JSON] GetChatMembersCountResponse + :<|> TelegramToken :> "getChatMember" + :> QueryParam "chat_id" Text + :> QueryParam "user_id" Int + :> Post '[JSON] GetChatMemberResponse + +-- | Proxy for Thelegram Bot API to administrate chats +chatsApi :: Proxy TelegramBotChatsAPI +chatsApi = Proxy + +kickChatMember_ :: Token -> Maybe Text -> Maybe Int -> ClientM KickChatMemberResponse +leaveChat_ :: Token -> Maybe Text -> ClientM LeaveChatResponse +unbanChatMember_ :: Token -> Maybe Text -> Maybe Int -> ClientM UnbanChatMemberResponse +getChat_ :: Token -> Maybe Text -> ClientM GetChatResponse +getChatAdministrators_ :: Token -> Maybe Text -> ClientM GetChatAdministratorsResponse +getChatMembersCount_ :: Token -> Maybe Text -> ClientM GetChatMembersCountResponse +getChatMember_ :: Token -> Maybe Text -> Maybe Int -> ClientM GetChatMemberResponse +kickChatMember_ + :<|> leaveChat_ + :<|> unbanChatMember_ + :<|> getChat_ + :<|> getChatAdministrators_ + :<|> getChatMembersCount_ + :<|> getChatMember_ = client chatsApi + +-- | Use this method to kick a user from a group or a supergroup. In the case of supergroups, the user will not be able to return to the group on their own using invite links, etc., unless unbanned first. The bot must be an administrator in the group for this to work. +kickChatMember :: Token -> Text -> Int -> Manager -> IO (Either ServantError KickChatMemberResponse) +kickChatMember token chatId userId = runClient (kickChatMemberM chatId userId) token + +-- | See 'kickChatMember' +kickChatMemberM :: Text -> Int -> TelegramClient KickChatMemberResponse +kickChatMemberM chatId userId = asking $ \t -> kickChatMember_ t (Just chatId) (Just userId) + +-- | Use this method for your bot to leave a group, supergroup or channel. Returns True on success. +leaveChat :: Token -> Text -> Manager -> IO (Either ServantError LeaveChatResponse) +leaveChat = runM leaveChatM + +-- | See 'leaveChat' +leaveChatM :: Text -> TelegramClient LeaveChatResponse +leaveChatM chatId = run_ leaveChat_ (Just chatId) + +-- | Use this method to unban a previously kicked user in a supergroup. The user will not return to the group automatically, but will be able to join via link, etc. The bot must be an administrator in the group for this to work. +unbanChatMember :: Token -> Text -> Int -> Manager -> IO (Either ServantError UnbanChatMemberResponse) +unbanChatMember token chatId userId = runClient (unbanChatMemberM chatId userId) token + +-- | See 'unbanChatMember' +unbanChatMemberM :: Text -> Int -> TelegramClient UnbanChatMemberResponse +unbanChatMemberM chatId userId = asking $ \t -> unbanChatMember_ t (Just chatId) (Just userId) + +-- | Use this method to get up to date information about the chat (current name of the user for one-on-one conversations, current username of a user, group or channel, etc.) +getChat :: Token -> Text -> Manager -> IO (Either ServantError GetChatResponse) +getChat = runM getChatM + +-- | See 'getChat' +getChatM :: Text -> TelegramClient GetChatResponse +getChatM chatId = run_ getChat_ (Just chatId) + +-- | Use this method to get a list of administrators in a chat. On success, returns an Array of 'ChatMember' objects that contains information about all chat administrators except other bots. If the chat is a group or a supergroup and no administrators were appointed, only the creator will be returned. +getChatAdministrators :: Token -> Text -> Manager -> IO (Either ServantError GetChatAdministratorsResponse) +getChatAdministrators = runM getChatAdministratorsM + +-- | See 'getChatAdministrators' +getChatAdministratorsM :: Text -> TelegramClient GetChatAdministratorsResponse +getChatAdministratorsM chatId = run_ getChatAdministrators_ (Just chatId) + +-- | Use this method to get the number of members in a chat. Returns 'Int' on success. +getChatMembersCount :: Token -> Text -> Manager -> IO (Either ServantError GetChatMembersCountResponse) +getChatMembersCount = runM getChatMembersCountM + +-- | See 'getChatMembersCount' +getChatMembersCountM :: Text -> TelegramClient GetChatMembersCountResponse +getChatMembersCountM chatId = run_ getChatMembersCount_ (Just chatId) + +-- | Use this method to get information about a member of a chat. Returns a 'ChatMember' object on success. +getChatMember :: Token -> Text -> Int -> Manager -> IO (Either ServantError GetChatMemberResponse) +getChatMember token chatId userId = runClient (getChatMemberM chatId userId) token + +-- | See 'getChatMember' +getChatMemberM :: Text -> Int -> TelegramClient GetChatMemberResponse +getChatMemberM chatId userId = asking $ \t -> getChatMember_ t (Just chatId) (Just userId)
+ src/Web/Telegram/API/Bot/API/Core.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TypeOperators #-} + +module Web.Telegram.API.Bot.API.Core + ( -- * Types + Token (..) + , TelegramToken + , TelegramClient + , run + , run_ + , runM + , asking + , runClient + , runClient' + , telegramBaseUrl + ) where + +import Control.Monad.Trans.Class +import Control.Monad.Trans.Reader + +import Data.Text (Text) +import Network.HTTP.Client (Manager) +import Servant.API +import Servant.Client + +-- | Telegram Bot's Token +newtype Token = Token Text + deriving (Show, Eq, Ord, ToHttpApiData, FromHttpApiData) + +-- | Type for token +type TelegramToken = Capture ":token" Token + +type TelegramClient a = ReaderT Token ClientM a + +telegramBaseUrl :: BaseUrl +telegramBaseUrl = BaseUrl Https "api.telegram.org" 443 "" + +-- | Allows to run 'TelegramClient' against arbitrary url +runClient' :: TelegramClient a -> Token -> ClientEnv -> IO (Either ServantError a) +runClient' tcm token = runClientM (runReaderT tcm token) + +-- | Runs 'TelegramClient' +runClient :: TelegramClient a -> Token -> Manager -> IO (Either ServantError a) +runClient tcm token manager = runClient' tcm token (ClientEnv manager telegramBaseUrl) + +asking :: Monad m => (t -> m b) -> ReaderT t m b +asking op = ask >>= \t -> lift $ op t + +run :: BaseUrl -> (Token -> a -> ClientM b) -> Token -> a -> Manager -> IO (Either ServantError b) +run b e t r m = runClientM (e t r) (ClientEnv m b) + +run_ :: Monad m => (a -> b -> m c) -> b -> ReaderT a m c +run_ act request = asking $ flip act request + +runM :: (r -> TelegramClient a) -> Token -> r -> Manager -> IO (Either ServantError a) +runM tcm token request = runClient (tcm request) token
+ src/Web/Telegram/API/Bot/API/Edit.hs view
@@ -0,0 +1,118 @@+{-# LANGUAGE DataKinds #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TypeOperators #-} + +module Web.Telegram.API.Bot.API.Edit + ( -- * Functions + editMessageText + , editMessageTextM + , editMessageCaption + , editMessageCaptionM + , editMessageReplyMarkup + , editMessageReplyMarkupM + , editInlineMessageText + , editInlineMessageTextM + , editInlineMessageCaption + , editInlineMessageCaptionM + , editInlineMessageReplyMarkup + , editInlineMessageReplyMarkupM + -- * API + , TelegramBotEditAPI + , editApi + -- * Types + ) where + +import Data.Proxy +import Network.HTTP.Client (Manager) +import Servant.API +import Servant.Client +import Web.Telegram.API.Bot.API.Core +import Web.Telegram.API.Bot.Requests +import Web.Telegram.API.Bot.Responses + +-- | Telegram Bot API +type TelegramBotEditAPI = + TelegramToken :> "editMessageText" + :> ReqBody '[JSON] EditMessageTextRequest + :> Post '[JSON] MessageResponse + :<|> TelegramToken :> "editMessageCaption" + :> ReqBody '[JSON] EditMessageCaptionRequest + :> Post '[JSON] MessageResponse + :<|> TelegramToken :> "editMessageReplyMarkup" + :> ReqBody '[JSON] EditMessageReplyMarkupRequest + :> Post '[JSON] MessageResponse + :<|> TelegramToken :> "editMessageText" + :> ReqBody '[JSON] EditMessageTextRequest + :> Post '[JSON] (Response Bool) + :<|> TelegramToken :> "editMessageCaption" + :> ReqBody '[JSON] EditMessageCaptionRequest + :> Post '[JSON] (Response Bool) + :<|> TelegramToken :> "editMessageReplyMarkup" + :> ReqBody '[JSON] EditMessageReplyMarkupRequest + :> Post '[JSON] (Response Bool) + + +-- | Proxy for Thelegram Bot API +editApi :: Proxy TelegramBotEditAPI +editApi = Proxy + +editMessageText_ :: Token -> EditMessageTextRequest -> ClientM MessageResponse +editMessageCaption_ :: Token -> EditMessageCaptionRequest -> ClientM MessageResponse +editMessageReplyMarkup_ :: Token -> EditMessageReplyMarkupRequest -> ClientM MessageResponse +editMessageText__ :: Token -> EditMessageTextRequest -> ClientM (Response Bool) +editMessageCaption__ :: Token -> EditMessageCaptionRequest -> ClientM (Response Bool) +editMessageReplyMarkup__ :: Token -> EditMessageReplyMarkupRequest -> ClientM (Response Bool) +editMessageText_ + :<|> editMessageCaption_ + :<|> editMessageReplyMarkup_ + :<|> editMessageText__ + :<|> editMessageCaption__ + :<|> editMessageReplyMarkup__ + = client editApi + +-- | Use this method to edit text messages sent by the bot. On success, the edited 'Message' is returned, otherwise True is returned. +editMessageText :: Token -> EditMessageTextRequest -> Manager -> IO (Either ServantError MessageResponse) +editMessageText = runM editMessageTextM + +-- | See 'editMessageText' +editMessageTextM :: EditMessageTextRequest -> TelegramClient MessageResponse +editMessageTextM = run_ editMessageText_ + +-- | Use this method to edit captions of messages sent by the bot. On success, the edited 'Message' is returned. +editMessageCaption :: Token -> EditMessageCaptionRequest -> Manager -> IO (Either ServantError MessageResponse) +editMessageCaption = runM editMessageCaptionM + +-- | See 'editMessageCaption' +editMessageCaptionM :: EditMessageCaptionRequest -> TelegramClient MessageResponse +editMessageCaptionM = run_ editMessageCaption_ + +-- | Use this method to edit only the reply markup of messages sent by the bot. On success, the edited 'Message' is returned. +editMessageReplyMarkup :: Token -> EditMessageReplyMarkupRequest -> Manager -> IO (Either ServantError MessageResponse) +editMessageReplyMarkup = runM editMessageReplyMarkupM + +editMessageReplyMarkupM :: EditMessageReplyMarkupRequest -> TelegramClient MessageResponse +editMessageReplyMarkupM = run_ editMessageReplyMarkup_ + +-- | Use this method to edit text messages sent via the bot (for inline bots). +editInlineMessageText :: Token -> EditMessageTextRequest -> Manager -> IO (Either ServantError (Response Bool)) +editInlineMessageText = runM editInlineMessageTextM + +-- | See 'editInlineMessageText' +editInlineMessageTextM :: EditMessageTextRequest -> TelegramClient (Response Bool) +editInlineMessageTextM = run_ editMessageText__ + +-- | Use this method to edit captions of messages sent via the bot (for inline bots). +editInlineMessageCaption :: Token -> EditMessageCaptionRequest -> Manager -> IO (Either ServantError (Response Bool)) +editInlineMessageCaption = runM editInlineMessageCaptionM + +-- | See 'editInlineMessageCaption' +editInlineMessageCaptionM :: EditMessageCaptionRequest -> TelegramClient (Response Bool) +editInlineMessageCaptionM = run_ editMessageCaption__ + +-- | Use this method to edit only the reply markup of messages sent via the bot (for inline bots). +editInlineMessageReplyMarkup :: Token -> EditMessageReplyMarkupRequest -> Manager -> IO (Either ServantError (Response Bool)) +editInlineMessageReplyMarkup = runM editInlineMessageReplyMarkupM + +-- | See 'editInlineMessageReplyMarkup' +editInlineMessageReplyMarkupM :: EditMessageReplyMarkupRequest -> TelegramClient (Response Bool) +editInlineMessageReplyMarkupM = run_ editMessageReplyMarkup__
+ src/Web/Telegram/API/Bot/API/Get.hs view
@@ -0,0 +1,75 @@+{-# LANGUAGE DataKinds #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TypeOperators #-} + +module Web.Telegram.API.Bot.API.Get + ( -- * Functions + getMe + , getMeM + , getFile + , getFileM + , getUserProfilePhotos + , getUserProfilePhotosM + -- * API + , TelegramBotGetAPI + , getApi + -- * Types + ) where + +import Data.Proxy +import Data.Text (Text) +import Network.HTTP.Client (Manager) +import Servant.API +import Servant.Client +import Web.Telegram.API.Bot.API.Core +import Web.Telegram.API.Bot.Responses + +-- | Telegram Bot API +type TelegramBotGetAPI = + TelegramToken :> "getMe" + :> Get '[JSON] GetMeResponse + :<|> TelegramToken :> "getFile" + :> QueryParam "file_id" Text + :> Get '[JSON] FileResponse + :<|> TelegramToken :> "getUserProfilePhotos" + :> QueryParam "user_id" Int + :> QueryParam "offset" Int + :> QueryParam "limit" Int + :> Get '[JSON] UserProfilePhotosResponse + +-- | Proxy for Thelegram Bot API +getApi :: Proxy TelegramBotGetAPI +getApi = Proxy + +getMe_ :: Token -> ClientM GetMeResponse +getFile_ :: Token -> Maybe Text -> ClientM FileResponse +getUserProfilePhotos_ :: Token -> Maybe Int -> Maybe Int -> Maybe Int -> ClientM UserProfilePhotosResponse +getMe_ + :<|> getFile_ + :<|> getUserProfilePhotos_ + = client getApi + +-- | A simple method for testing your bot's auth token. Requires no parameters. +-- Returns basic information about the bot in form of a 'User' object. +getMe :: Token -> Manager -> IO (Either ServantError GetMeResponse) +getMe = runClient getMeM + +-- | See `getMe` +getMeM :: TelegramClient GetMeResponse +getMeM = asking getMe_ + +-- | Use this method to get basic info about a file and prepare it for downloading. For the moment, bots can download files of up to 20MB in size. On success, a 'File' object is returned. The file can then be downloaded via the link @https://api.telegram.org/file/bot<token>/<file_path>@, where @<file_path>@ is taken from the response. It is guaranteed that the link will be valid for at least 1 hour. When the link expires, a new one can be requested by calling getFile again. +getFile :: Token -> Text -> Manager -> IO (Either ServantError FileResponse) +getFile token fileId = runClient (getFileM fileId) token + +-- | See 'getFile' +getFileM :: Text -> TelegramClient FileResponse +getFileM fileId = run_ getFile_ (Just fileId) + +-- | Use this method to get a list of profile pictures for a user. Returns a 'UserProfilePhotos' object. +getUserProfilePhotos :: Token -> Int -> Maybe Int -> Maybe Int -> Manager -> IO (Either ServantError UserProfilePhotosResponse) +getUserProfilePhotos token userId offset limit = runClient (getUserProfilePhotosM userId offset limit) token + +-- | See 'getUserProfilePhotos' +getUserProfilePhotosM :: Int -> Maybe Int -> Maybe Int -> TelegramClient UserProfilePhotosResponse +getUserProfilePhotosM userId offset limit = asking $ \t -> getUserProfilePhotos_ t (Just userId) offset limit
+ src/Web/Telegram/API/Bot/API/Messages.hs view
@@ -0,0 +1,321 @@+{-# LANGUAGE DataKinds #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TypeOperators #-} + +module Web.Telegram.API.Bot.API.Messages + ( -- * Functions + sendMessage + , sendMessageM + , forwardMessage + , forwardMessageM + , uploadPhoto + , uploadPhotoM + , sendPhoto + , sendPhotoM + , uploadAudio + , uploadAudioM + , sendAudio + , sendAudioM + , uploadDocument + , uploadDocumentM + , sendDocument + , sendDocumentM + , uploadSticker + , uploadStickerM + , sendSticker + , sendStickerM + , uploadVideo + , uploadVideoM + , sendVideo + , sendVideoM + , uploadVoice + , uploadVoiceM + , sendVoice + , sendVoiceM + , sendLocation + , sendLocationM + , sendVenue + , sendVenueM + , sendContact + , sendContactM + , sendChatAction + , sendChatActionM + , sendGame + , sendGameM + -- * API + , TelegramBotMessagesAPI + , messagesApi + -- * Types + ) where + +import Data.Proxy +import Data.Text (Text) +import Network.HTTP.Client (Manager) +import Servant.API +import Servant.Client +import Servant.Client.MultipartFormData +import Web.Telegram.API.Bot.API.Core +import Web.Telegram.API.Bot.Requests +import Web.Telegram.API.Bot.Responses + +-- | Telegram Bot API +type TelegramBotMessagesAPI = + TelegramToken :> "sendMessage" + :> ReqBody '[JSON] SendMessageRequest + :> Post '[JSON] MessageResponse + :<|> TelegramToken :> "forwardMessage" + :> ReqBody '[JSON] ForwardMessageRequest + :> Post '[JSON] MessageResponse + :<|> TelegramToken :> "sendPhoto" + :> MultipartFormDataReqBody (SendPhotoRequest FileUpload) + :> Post '[JSON] MessageResponse + :<|> TelegramToken :> "sendPhoto" + :> ReqBody '[JSON] (SendPhotoRequest Text) + :> Post '[JSON] MessageResponse + :<|> TelegramToken :> "sendAudio" + :> MultipartFormDataReqBody (SendAudioRequest FileUpload) + :> Post '[JSON] MessageResponse + :<|> TelegramToken :> "sendAudio" + :> ReqBody '[JSON] (SendAudioRequest Text) + :> Post '[JSON] MessageResponse + :<|> TelegramToken :> "sendDocument" + :> MultipartFormDataReqBody (SendDocumentRequest FileUpload) + :> Post '[JSON] MessageResponse + :<|> TelegramToken :> "sendDocument" + :> ReqBody '[JSON] (SendDocumentRequest Text) + :> Post '[JSON] MessageResponse + :<|> TelegramToken :> "sendSticker" + :> MultipartFormDataReqBody (SendStickerRequest FileUpload) + :> Post '[JSON] MessageResponse + :<|> TelegramToken :> "sendSticker" + :> ReqBody '[JSON] (SendStickerRequest Text) + :> Post '[JSON] MessageResponse + :<|> TelegramToken :> "sendVideo" + :> MultipartFormDataReqBody (SendVideoRequest FileUpload) + :> Post '[JSON] MessageResponse + :<|> TelegramToken :> "sendVideo" + :> ReqBody '[JSON] (SendVideoRequest Text) + :> Post '[JSON] MessageResponse + :<|> TelegramToken :> "sendVoice" + :> MultipartFormDataReqBody (SendVoiceRequest FileUpload) + :> Post '[JSON] MessageResponse + :<|> TelegramToken :> "sendVoice" + :> ReqBody '[JSON] (SendVoiceRequest Text) + :> Post '[JSON] MessageResponse + :<|> TelegramToken :> "sendLocation" + :> ReqBody '[JSON] SendLocationRequest + :> Post '[JSON] MessageResponse + :<|> TelegramToken :> "sendVenue" + :> ReqBody '[JSON] SendVenueRequest + :> Post '[JSON] MessageResponse + :<|> TelegramToken :> "sendContact" + :> ReqBody '[JSON] SendContactRequest + :> Post '[JSON] MessageResponse + :<|> TelegramToken :> "sendChatAction" + :> ReqBody '[JSON] SendChatActionRequest + :> Post '[JSON] ChatActionResponse + :<|> TelegramToken :> "sendGame" + :> ReqBody '[JSON] SendGameRequest + :> Post '[JSON] MessageResponse + +-- | Proxy for Thelegram Bot API +messagesApi :: Proxy TelegramBotMessagesAPI +messagesApi = Proxy + +sendMessage_ :: Token -> SendMessageRequest -> ClientM MessageResponse +forwardMessage_ :: Token -> ForwardMessageRequest -> ClientM MessageResponse +uploadPhoto_ :: Token -> SendPhotoRequest FileUpload -> ClientM MessageResponse +sendPhoto_ :: Token -> SendPhotoRequest Text -> ClientM MessageResponse +uploadAudio_ :: Token -> SendAudioRequest FileUpload -> ClientM MessageResponse +sendAudio_ :: Token -> SendAudioRequest Text -> ClientM MessageResponse +uploadDocument_ :: Token -> SendDocumentRequest FileUpload -> ClientM MessageResponse +sendDocument_ :: Token -> SendDocumentRequest Text -> ClientM MessageResponse +uploadSticker_ :: Token -> SendStickerRequest FileUpload -> ClientM MessageResponse +sendSticker_ :: Token -> SendStickerRequest Text -> ClientM MessageResponse +uploadVideo_ :: Token -> SendVideoRequest FileUpload -> ClientM MessageResponse +sendVideo_ :: Token -> SendVideoRequest Text -> ClientM MessageResponse +uploadVoice_ :: Token -> SendVoiceRequest FileUpload -> ClientM MessageResponse +sendVoice_ :: Token -> SendVoiceRequest Text -> ClientM MessageResponse +sendLocation_ :: Token -> SendLocationRequest -> ClientM MessageResponse +sendVenue_ :: Token -> SendVenueRequest-> ClientM MessageResponse +sendContact_ :: Token -> SendContactRequest -> ClientM MessageResponse +sendChatAction_ :: Token -> SendChatActionRequest -> ClientM ChatActionResponse +sendGame_ :: Token -> SendGameRequest -> ClientM MessageResponse +sendMessage_ + :<|> forwardMessage_ + :<|> uploadPhoto_ + :<|> sendPhoto_ + :<|> uploadAudio_ + :<|> sendAudio_ + :<|> uploadDocument_ + :<|> sendDocument_ + :<|> uploadSticker_ + :<|> sendSticker_ + :<|> uploadVideo_ + :<|> sendVideo_ + :<|> uploadVoice_ + :<|> sendVoice_ + :<|> sendLocation_ + :<|> sendVenue_ + :<|> sendContact_ + :<|> sendChatAction_ + :<|> sendGame_ + = client messagesApi + +-- | Use this method to send text messages. On success, the sent 'Message' is returned. +sendMessage :: Token -> SendMessageRequest -> Manager -> IO (Either ServantError MessageResponse) +sendMessage = runM sendMessageM + +-- | See 'sendMessage' +sendMessageM :: SendMessageRequest -> TelegramClient MessageResponse +sendMessageM = run_ sendMessage_ + +-- | Use this method to forward messages of any kind. On success, the sent 'Message' is returned. +forwardMessage :: Token -> ForwardMessageRequest -> Manager -> IO (Either ServantError MessageResponse) +forwardMessage = runM forwardMessageM + +-- | See 'forwardMessage' +forwardMessageM :: ForwardMessageRequest -> TelegramClient MessageResponse +forwardMessageM = run_ forwardMessage_ + +-- | Use this method to upload and send photos. On success, the sent 'Message' is returned. +uploadPhoto :: Token -> SendPhotoRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse) +uploadPhoto = runM uploadPhotoM + +-- | See 'uploadPhoto' +uploadPhotoM :: SendPhotoRequest FileUpload -> TelegramClient MessageResponse +uploadPhotoM = run_ uploadPhoto_ + +-- | Use this method to send photos that have already been uploaded. On success, the sent 'Message' is returned. +sendPhoto :: Token -> SendPhotoRequest Text -> Manager -> IO (Either ServantError MessageResponse) +sendPhoto = runM sendPhotoM + +-- | See 'sendPhoto' +sendPhotoM :: SendPhotoRequest Text -> TelegramClient MessageResponse +sendPhotoM = run_ sendPhoto_ + +-- | Use this method to upload and send audio files, if you want Telegram clients to display them in the music player. Your audio must be in the .mp3 format. On success, the sent 'Message' is returned. Bots can currently send audio files of up to 50 MB in size, this limit may be changed in the future. +-- +-- For backward compatibility, when the fields __title__ and __performer__ are both empty and the mime-type of the file to be sent is not _audio/mpeg_, the file will be sent as a playable voice message. For this to work, the audio must be in an .ogg file encoded with OPUS. This behavior will be phased out in the future. For sending voice messages, use the 'sendVoice' method instead. +uploadAudio :: Token -> SendAudioRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse) +uploadAudio = runM uploadAudioM + +-- | See 'uploadAudio' +uploadAudioM :: SendAudioRequest FileUpload -> TelegramClient MessageResponse +uploadAudioM = run_ uploadAudio_ + +-- | Use this method to send audio files that are already on the Telegram servers, if you want Telegram clients to display them in the music player. Your audio must be in the .mp3 format. On success, the sent 'Message' is returned. Bots can currently send audio files of up to 50 MB in size, this limit may be changed in the future. +-- +-- For backward compatibility, when the fields __title__ and __performer__ are both empty and the mime-type of the file to be sent is not _audio/mpeg_, the file will be sent as a playable voice message. For this to work, the audio must be in an .ogg file encoded with OPUS. This behavior will be phased out in the future. For sending voice messages, use the 'sendVoice' method instead. +sendAudio :: Token -> SendAudioRequest Text -> Manager -> IO (Either ServantError MessageResponse) +sendAudio = runM sendAudioM + +-- | See 'sendAudio' +sendAudioM :: SendAudioRequest Text -> TelegramClient MessageResponse +sendAudioM = run_ sendAudio_ + +-- | Use this method to upload and send general files. On success, the sent 'Message' is returned. Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future. +uploadDocument :: Token -> SendDocumentRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse) +uploadDocument = runM uploadDocumentM + +-- | See 'uploadDocument' +uploadDocumentM :: SendDocumentRequest FileUpload -> TelegramClient MessageResponse +uploadDocumentM = run_ uploadDocument_ + +-- | Use this method to send general files that have already been uploaded. On success, the sent 'Message' is returned. Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future. +sendDocument :: Token -> SendDocumentRequest Text -> Manager -> IO (Either ServantError MessageResponse) +sendDocument = runM sendDocumentM + +-- | See 'sendDocument' +sendDocumentM :: SendDocumentRequest Text -> TelegramClient MessageResponse +sendDocumentM = run_ sendDocument_ + +-- | Use this method to upload and send .webp stickers. On success, the sent 'Message' is returned. +uploadSticker :: Token -> SendStickerRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse) +uploadSticker = runM uploadStickerM + +-- | See 'uploadSticker' +uploadStickerM :: SendStickerRequest FileUpload -> TelegramClient MessageResponse +uploadStickerM = run_ uploadSticker_ + +-- | Use this method to send .webp stickers that are already on the Telegram servers. On success, the sent 'Message' is returned. +sendSticker :: Token -> SendStickerRequest Text -> Manager -> IO (Either ServantError MessageResponse) +sendSticker = runM sendStickerM + +-- | See 'sendSticker' +sendStickerM :: SendStickerRequest Text -> TelegramClient MessageResponse +sendStickerM = run_ sendSticker_ + +-- | Use this method to upload and send video files. Telegram clients support mp4 videos (other formats may be sent as 'Document'). On success, the sent 'Message' is returned. Bots can currently send video files of up to 50 MB in size, this limit may be changed in the future. +uploadVideo :: Token -> SendVideoRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse) +uploadVideo = runM uploadVideoM + +-- | See 'uploadVideo' +uploadVideoM :: SendVideoRequest FileUpload -> TelegramClient MessageResponse +uploadVideoM = run_ uploadVideo_ + +-- | Use this method to send video files that are already on the Telegram servers. Telegram clients support mp4 videos (other formats may be sent as 'Document'). On success, the sent 'Message' is returned. Bots can currently send video files of up to 50 MB in size, this limit may be changed in the future. +sendVideo :: Token -> SendVideoRequest Text -> Manager -> IO (Either ServantError MessageResponse) +sendVideo = runM sendVideoM + +-- | See 'sendVideo' +sendVideoM :: SendVideoRequest Text -> TelegramClient MessageResponse +sendVideoM = run_ sendVideo_ + +-- | Use this method to upload and send audio files, if you want Telegram clients to display the file as a playable voice message. For this to work, your audio must be in an .ogg file encoded with OPUS (other formats may be sent as 'Audio' or 'Document'). On success, the sent 'Message' is returned. Bots can currently send voice messages of up to 50 MB in size, this limit may be changed in the future. +uploadVoice :: Token -> SendVoiceRequest FileUpload -> Manager -> IO (Either ServantError MessageResponse) +uploadVoice = runM uploadVoiceM + +-- | See 'uploadVoice' +uploadVoiceM :: SendVoiceRequest FileUpload -> TelegramClient MessageResponse +uploadVoiceM = run_ uploadVoice_ + +-- | Use this method to send audio files that are already on the telegram server, if you want Telegram clients to display the file as a playable voice message. For this to work, your audio must be in an .ogg file encoded with OPUS (other formats may be sent as 'Audio' or 'Document'). On success, the sent 'Message' is returned. Bots can currently send voice messages of up to 50 MB in size, this limit may be changed in the future. +sendVoice :: Token -> SendVoiceRequest Text -> Manager -> IO (Either ServantError MessageResponse) +sendVoice = runM sendVoiceM + +-- | See 'sendVoice' +sendVoiceM :: SendVoiceRequest Text -> TelegramClient MessageResponse +sendVoiceM = run_ sendVoice_ + +-- | Use this method to send point on the map. On success, the sent 'Message' is returned. +sendLocation :: Token -> SendLocationRequest -> Manager -> IO (Either ServantError MessageResponse) +sendLocation = runM sendLocationM + +-- | See 'sendLocation' +sendLocationM :: SendLocationRequest -> TelegramClient MessageResponse +sendLocationM = run_ sendLocation_ + +-- | Use this method to send information about a venue. On success, the sent 'Message' is returned. +sendVenue :: Token -> SendVenueRequest -> Manager -> IO (Either ServantError MessageResponse) +sendVenue = runM sendVenueM + +-- | See 'sendVenue' +sendVenueM :: SendVenueRequest -> TelegramClient MessageResponse +sendVenueM = run_ sendVenue_ + +-- | Use this method to send information about a venue. On success, the sent 'Message' is returned. +sendContact :: Token -> SendContactRequest -> Manager -> IO (Either ServantError MessageResponse) +sendContact = runM sendContactM + +-- | See 'sendContact' +sendContactM :: SendContactRequest -> TelegramClient MessageResponse +sendContactM = run_ sendContact_ + +-- | Use this method when you need to tell the user that something is happening on the bot's side. +-- The status is set for 5 seconds or less (when a message arrives from your bot, +-- Telegram clients clear its typing status). +sendChatAction :: Token -> SendChatActionRequest -> Manager -> IO (Either ServantError ChatActionResponse) +sendChatAction = runM sendChatActionM + +-- | See 'sendChatAction' +sendChatActionM :: SendChatActionRequest -> TelegramClient ChatActionResponse +sendChatActionM = run_ sendChatAction_ + +-- | Use this method to send a game. On success, the sent 'Message' is returned. +sendGame :: Token -> SendGameRequest -> Manager -> IO (Either ServantError MessageResponse) +sendGame = runM sendGameM + +-- | See 'sendGame' +sendGameM :: SendGameRequest -> TelegramClient MessageResponse +sendGameM = run_ sendGame_
+ src/Web/Telegram/API/Bot/API/Queries.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE DataKinds #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TypeOperators #-} + +module Web.Telegram.API.Bot.API.Queries + ( -- * Functions + answerInlineQuery + , answerInlineQueryM + , answerCallbackQuery + , answerCallbackQueryM + -- * API + , TelegramBotQueriesAPI + , queriesApi + -- * Types + ) where + +import Data.Proxy +import Network.HTTP.Client (Manager) +import Servant.API +import Servant.Client +import Web.Telegram.API.Bot.API.Core +import Web.Telegram.API.Bot.Requests +import Web.Telegram.API.Bot.Responses + +-- | Telegram Bot API +type TelegramBotQueriesAPI = + TelegramToken :> "answerInlineQuery" + :> ReqBody '[JSON] AnswerInlineQueryRequest + :> Post '[JSON] InlineQueryResponse + :<|> TelegramToken :> "answerCallbackQuery" + :> ReqBody '[JSON] AnswerCallbackQueryRequest + :> Post '[JSON] CallbackQueryResponse + + +-- | Proxy for Thelegram Bot API +queriesApi :: Proxy TelegramBotQueriesAPI +queriesApi = Proxy + +answerInlineQuery_ :: Token -> AnswerInlineQueryRequest -> ClientM InlineQueryResponse +answerCallbackQuery_ :: Token -> AnswerCallbackQueryRequest -> ClientM CallbackQueryResponse +answerInlineQuery_ :<|> answerCallbackQuery_ + = client queriesApi + +-- | Use this method to send answers to an inline query. No more than 50 results per query are allowed. +answerInlineQuery :: Token -> AnswerInlineQueryRequest -> Manager -> IO (Either ServantError InlineQueryResponse) +answerInlineQuery = runM answerInlineQueryM + +-- | See 'answerInlineQuery' +answerInlineQueryM :: AnswerInlineQueryRequest -> TelegramClient InlineQueryResponse +answerInlineQueryM = run_ answerInlineQuery_ + +-- | Use this method to send answers to callback queries sent from inline keyboards. The answer will be displayed to the user as a notification at the top of the chat screen or as an alert. +answerCallbackQuery :: Token -> AnswerCallbackQueryRequest -> Manager -> IO (Either ServantError CallbackQueryResponse) +answerCallbackQuery = runM answerCallbackQueryM + +-- | See 'answerCallbackQuery' +answerCallbackQueryM :: AnswerCallbackQueryRequest -> TelegramClient CallbackQueryResponse +answerCallbackQueryM = run_ answerCallbackQuery_
+ src/Web/Telegram/API/Bot/API/Updates.hs view
@@ -0,0 +1,121 @@+{-# LANGUAGE DataKinds #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TypeOperators #-} + +module Web.Telegram.API.Bot.API.Updates + ( -- * Functions + getUpdates + , getUpdatesM + , setWebhook + , setWebhookM + , setWebhookWithCertificate + , setWebhookWithCertificateM + , deleteWebhook + , deleteWebhookM + , getWebhookInfo + , getWebhookInfoM + -- * API + , TelegramBotUpdatesAPI + , updatesApi + ) where + +import Data.Proxy +import Data.Maybe +import Data.Text (Text, empty) +import Network.HTTP.Client (Manager) +import Servant.API +import Servant.Client +import Servant.Client.MultipartFormData +import Web.Telegram.API.Bot.API.Core +import Web.Telegram.API.Bot.Requests +import Web.Telegram.API.Bot.Responses + +-- | Telegram Bot API +type TelegramBotUpdatesAPI = + TelegramToken :> "getUpdates" + :> ReqBody '[JSON] GetUpdatesRequest + :> Get '[JSON] UpdatesResponse + :<|> TelegramToken :> "setWebhook" + :> ReqBody '[JSON] SetWebhookRequest + :> Get '[JSON] SetWebhookResponse + :<|> TelegramToken :> "setWebhook" + :> MultipartFormDataReqBody SetWebhookRequest + :> Post '[JSON] SetWebhookResponse + :<|> TelegramToken :> "deleteWebhook" + :> Post '[JSON] (Response Bool) + :<|> TelegramToken :> "getWebhookInfo" + :> Get '[JSON] GetWebhookInfoResponse + +-- | Proxy for Thelegram Bot API to configure your bot +updatesApi :: Proxy TelegramBotUpdatesAPI +updatesApi = Proxy + +getUpdates_ :: Token -> GetUpdatesRequest -> ClientM UpdatesResponse +setWebhook_ :: Token -> SetWebhookRequest -> ClientM SetWebhookResponse +setWebhookWithCert_ :: Token -> SetWebhookRequest -> ClientM SetWebhookResponse +deleteWebhook_ :: Token -> ClientM (Response Bool) +getWebhookInfo_ :: Token -> ClientM GetWebhookInfoResponse +getUpdates_ + :<|> setWebhook_ + :<|> setWebhookWithCert_ + :<|> deleteWebhook_ + :<|> getWebhookInfo_ = client updatesApi + +-- | Use this method to receive incoming updates using long polling. An Array of 'Update' objects is returned. Use `getUpdateM` for more features +getUpdates + :: Token + -> Maybe Int -- ^ offset + -> Maybe Int -- ^ limit + -> Maybe Int -- ^ timeout + -> Manager + -> IO (Either ServantError UpdatesResponse) +getUpdates token offset limit timeout = runClient (getUpdatesM' request) token + where request = GetUpdatesRequest offset limit timeout Nothing + +-- | Get update with default parameters See 'getUpdate' for details. +getUpdatesM :: TelegramClient UpdatesResponse +getUpdatesM = getUpdatesM' getUpdatesRequest + +-- | See 'getUpdates' +getUpdatesM' :: GetUpdatesRequest -> TelegramClient UpdatesResponse +getUpdatesM' = run_ getUpdates_ + +-- | 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 + -> Manager + -> IO (Either ServantError SetWebhookResponse) +setWebhook token url = runClient (setWebhookM request) token + where request = setWebhookRequest' $ fromMaybe empty url + +-- | See 'setWebhook' +setWebhookM :: SetWebhookRequest -> TelegramClient SetWebhookResponse +setWebhookM = run_ setWebhook_ + +-- | 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. +setWebhookWithCertificate :: Token -> SetWebhookRequest -> Manager -> IO (Either ServantError SetWebhookResponse) +setWebhookWithCertificate = runM setWebhookWithCertificateM + +-- | See 'setWebhookWithCertificate' +setWebhookWithCertificateM :: SetWebhookRequest -> TelegramClient SetWebhookResponse +setWebhookWithCertificateM = run_ setWebhookWithCert_ + +-- | Use this method to remove webhook integration if you decide to switch back to getUpdates. Returns True on success. +deleteWebhook :: Token -> Manager -> IO (Either ServantError (Response Bool)) +deleteWebhook = runClient deleteWebhookM + +-- | See 'deleteWebhook' +deleteWebhookM :: TelegramClient (Response Bool) +deleteWebhookM = asking deleteWebhook_ + +-- | Contains information about the current status of a webhook. +getWebhookInfo :: Token -> Manager -> IO (Either ServantError GetWebhookInfoResponse) +getWebhookInfo = runClient getWebhookInfoM + +-- | See 'getWebhookInfo' +getWebhookInfoM :: TelegramClient GetWebhookInfoResponse +getWebhookInfoM = asking getWebhookInfo_
src/Web/Telegram/API/Bot/Data.hs view
@@ -870,6 +870,8 @@ , whi_pending_update_count :: Int -- ^ Number of updates awaiting delivery , whi_last_error_date :: Maybe Int -- ^ Unix time for the most recent error that happened when trying to deliver an update via webhook , whi_last_error_message :: Maybe Text -- ^ Error message in human-readable format for the most recent error that happened when trying to deliver an update via webhook + , whi_max_connections :: Maybe Int -- ^ Maximum allowed number of simultaneous HTTPS connections to the webhook for update delivery + , whi_allowed_updates :: Maybe [Text] -- ^ A list of update types the bot is subscribed to. Defaults to all update types } deriving (Show, Generic) instance ToJSON WebhookInfo where
src/Web/Telegram/API/Bot/Requests.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE DeriveGeneric #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE OverloadedStrings #-} -- | This module contains data objects which represents requests to Telegram Bot API module Web.Telegram.API.Bot.Requests @@ -10,6 +10,7 @@ , FileUpload (..) , FileUploadContent (..) , SetWebhookRequest (..) + , GetUpdatesRequest (..) , SendPhotoRequest (..) , SendAudioRequest (..) , SendDocumentRequest (..) @@ -31,6 +32,8 @@ -- * Functions , localFileUpload , setWebhookRequest + , setWebhookRequest' + , getUpdatesRequest , sendMessageRequest , forwardMessageRequest , sendPhotoRequest @@ -65,20 +68,21 @@ ) where import Data.Aeson -import qualified Data.ByteString as BS -import qualified Data.ByteString.Lazy as LBS +import qualified Data.ByteString as BS +import qualified Data.ByteString.Lazy as LBS import Data.Maybe -import Data.Text (Text) -import qualified Data.Text as T -import qualified Data.Text.Encoding as T +import Data.Text (Text) +import qualified Data.Text as T +import qualified Data.Text.Encoding as T import GHC.Generics import Network.HTTP.Client.MultipartFormData import Network.Mime -import Servant.Client.MultipartFormData (ToMultipartFormData (..)) -import Web.Telegram.API.Bot.Data (InlineKeyboardButton, - InlineKeyboardMarkup, - InlineQueryResult, KeyboardButton, - ParseMode) +import Servant.Client.MultipartFormData (ToMultipartFormData (..)) +import Web.Telegram.API.Bot.Data (InlineKeyboardButton, + InlineKeyboardMarkup, + InlineQueryResult, + KeyboardButton, + ParseMode) import Web.Telegram.API.Bot.JsonExt @@ -106,8 +110,8 @@ let part = case fileUpload_content fileUpload of FileUploadFile path -> partFileSource inputName path - FileUploadBS bs -> partBS inputName bs - FileUploadLBS lbs -> partLBS inputName lbs + FileUploadBS bs -> partBS inputName bs + FileUploadLBS lbs -> partLBS inputName lbs in part { partContentType = fileUpload_type fileUpload } utf8Part :: Text -> Text -> Part @@ -118,17 +122,55 @@ { webhook_url :: Text -- ^ HTTPS url to send updates to. Use `setWebhook` function and an empty string to remove webhook integration , webhook_certificate :: FileUpload -- ^ Upload your public key certificate so that the root certificate in use can be checked. + , webhook_max_connections :: Maybe Int +-- TODO: implement , webhook_allowed_updates :: Maybe [Text] } + | SetWebhookWithoutCertRequest + { + webhook_url :: Text + , webhook_max_connections :: Maybe Int + , webhook_allowed_updates :: Maybe [Text] + } deriving (Generic) +instance ToJSON SetWebhookRequest where + toJSON SetWebhookRequest{} = undefined + toJSON (SetWebhookWithoutCertRequest url maxConnections allowedUpdates) = object $ + ("url" .= url) : catMaybes [ + ("max_connections" .=) <$> maxConnections, + ("allowed_updates" .=) <$> allowedUpdates] + instance ToMultipartFormData SetWebhookRequest where toMultipartFormData req = [ utf8Part "url" $ webhook_url req - , fileUploadToPart "certificate" $ webhook_certificate req + , fileUploadToPart "certificate" $ webhook_certificate req ] ++ + catMaybes + [ utf8Part "max_connections" . T.pack . show <$> webhook_max_connections req + -- TODO: , ??? "allowed_updates" ??? <$> webhook_allowed_updates req ] setWebhookRequest :: Text -> FileUpload -> SetWebhookRequest -setWebhookRequest = SetWebhookRequest +setWebhookRequest url certificate = SetWebhookRequest url certificate Nothing +setWebhookRequest' :: Text -> SetWebhookRequest +setWebhookRequest' url = SetWebhookWithoutCertRequest url Nothing Nothing + +data GetUpdatesRequest = GetUpdatesRequest + { + updates_offset :: Maybe Int -- ^ Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as 'getUpdates' is called with an offset higher than its update_id. The negative offset can be specified to retrieve updates starting from -offset update from the end of the updates queue. All previous updates will forgotten. + , updates_limit :: Maybe Int -- ^ Limits the number of updates to be retrieved. Values between 1—100 are accepted. Defaults to 100. + , updates_timeout :: Maybe Int -- ^ Timeout in seconds for long polling. Defaults to 0, i.e. usual short polling. Should be positive, short polling should be used for testing purposes only. + , updates_allowed_updates :: Maybe [Text] -- ^ List the types of updates you want your bot to receive. For example, specify [“message”, “edited_channel_post”, “callback_query”] to only receive updates of these types. See 'Update' for a complete list of available update types. Specify an empty list to receive all updates regardless of type (default). If not specified, the previous setting will be used. + } deriving (Show, Generic) + +instance ToJSON GetUpdatesRequest where + toJSON = toJsonDrop 8 + +instance FromJSON GetUpdatesRequest where + parseJSON = parseJsonDrop 8 + +getUpdatesRequest :: GetUpdatesRequest +getUpdatesRequest = GetUpdatesRequest Nothing Nothing Nothing Nothing + -- | This object represents request for 'sendMessage' data SendMessageRequest = SendMessageRequest { @@ -153,10 +195,10 @@ -- | This object represents request for 'forwardMessage' data ForwardMessageRequest = ForwardMessageRequest { - forward_chat_id :: Text -- ^ Unique identifier for the target chat or username of the target channel (in the format @@channelusername@) - , forward_from_chat_id :: Text -- ^ Unique identifier for the chat where the original message was sent (or channel username in the format @@channelusername@) - , forward_disable_notification :: Maybe Bool -- ^ Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. - , forward_message_id :: Int -- ^ Unique message identifier + forward_chat_id :: Text -- ^ Unique identifier for the target chat or username of the target channel (in the format @@channelusername@) + , forward_from_chat_id :: Text -- ^ Unique identifier for the chat where the original message was sent (or channel username in the format @@channelusername@) + , forward_disable_notification :: Maybe Bool -- ^ Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. + , forward_message_id :: Int -- ^ Unique message identifier } deriving (Show, Generic) instance ToJSON ForwardMessageRequest where @@ -244,11 +286,11 @@ -- | This object represents request for 'sendSticker' data SendStickerRequest payload = SendStickerRequest { - sticker_chat_id :: Text -- ^ Unique identifier for the target chat or username of the target channel (in the format @@channelusername@) - , sticker_sticker :: payload -- ^ Sticker to send. You can either pass a file_id as String to resend a sticker that is already on the Telegram servers, or upload a new sticker. - , sticker_disable_notification :: Maybe Bool -- ^ Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. - , sticker_reply_to_message_id :: Maybe Int -- ^ If the message is a reply, ID of the original message - , sticker_reply_markup :: Maybe ReplyKeyboard -- ^ Additional interface options. A JSON-serialized object for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user. + sticker_chat_id :: Text -- ^ Unique identifier for the target chat or username of the target channel (in the format @@channelusername@) + , sticker_sticker :: payload -- ^ Sticker to send. You can either pass a file_id as String to resend a sticker that is already on the Telegram servers, or upload a new sticker. + , sticker_disable_notification :: Maybe Bool -- ^ Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. + , sticker_reply_to_message_id :: Maybe Int -- ^ If the message is a reply, ID of the original message + , sticker_reply_markup :: Maybe ReplyKeyboard -- ^ Additional interface options. A JSON-serialized object for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user. } deriving (Show, Generic) instance ToJSON (SendStickerRequest Text) where @@ -276,12 +318,12 @@ -- | This object represents request for 'sendDocument' data SendDocumentRequest payload = SendDocumentRequest { - document_chat_id :: Text -- ^ Unique identifier for the target chat or username of the target channel (in the format @@channelusername@) - , document_document :: payload -- ^ File to send. You can either pass a file_id as String to resend a file that is already on the Telegram servers, or upload a new file. - , document_caption :: Maybe Text -- ^ Document caption (may also be used when resending documents by file_id), 0-200 characters - , document_disable_notification :: Maybe Bool -- ^ Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. - , document_reply_to_message_id :: Maybe Int -- ^ If the message is a reply, ID of the original message - , document_reply_markup :: Maybe ReplyKeyboard -- ^ Additional interface options. A JSON-serialized object for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user. + document_chat_id :: Text -- ^ Unique identifier for the target chat or username of the target channel (in the format @@channelusername@) + , document_document :: payload -- ^ File to send. You can either pass a file_id as String to resend a file that is already on the Telegram servers, or upload a new file. + , document_caption :: Maybe Text -- ^ Document caption (may also be used when resending documents by file_id), 0-200 characters + , document_disable_notification :: Maybe Bool -- ^ Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. + , document_reply_to_message_id :: Maybe Int -- ^ If the message is a reply, ID of the original message + , document_reply_markup :: Maybe ReplyKeyboard -- ^ Additional interface options. A JSON-serialized object for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user. } deriving (Show, Generic) instance ToJSON (SendDocumentRequest Text) where @@ -310,13 +352,13 @@ -- | This object represents request for 'sendVideo' data SendVideoRequest payload = SendVideoRequest { - _video_chat_id :: Text -- ^ Unique identifier for the target chat or username of the target channel (in the format @@channelusername@) - , _video_video :: payload -- ^ Video to send. You can either pass a file_id as String to resend a video that is already on the Telegram servers, or upload a new video. - , _video_duration :: Maybe Int -- ^ Duration of sent video in seconds - , _video_caption :: Maybe Text -- ^ Video caption, 0-200 characters. - , _video_disable_notification :: Maybe Bool -- ^ Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. - , _video_reply_to_message_id :: Maybe Int -- ^ If the message is a reply, ID of the original message - , _video_reply_markup :: Maybe ReplyKeyboard -- ^ Additional interface options. A JSON-serialized object for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user. + _video_chat_id :: Text -- ^ Unique identifier for the target chat or username of the target channel (in the format @@channelusername@) + , _video_video :: payload -- ^ Video to send. You can either pass a file_id as String to resend a video that is already on the Telegram servers, or upload a new video. + , _video_duration :: Maybe Int -- ^ Duration of sent video in seconds + , _video_caption :: Maybe Text -- ^ Video caption, 0-200 characters. + , _video_disable_notification :: Maybe Bool -- ^ Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. + , _video_reply_to_message_id :: Maybe Int -- ^ If the message is a reply, ID of the original message + , _video_reply_markup :: Maybe ReplyKeyboard -- ^ Additional interface options. A JSON-serialized object for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user. } deriving (Show, Generic) instance ToJSON (SendVideoRequest Text) where @@ -346,13 +388,13 @@ -- | This object represents request for 'sendVoice' data SendVoiceRequest payload = SendVoiceRequest { - _voice_chat_id :: Text -- ^ Unique identifier for the target chat or username of the target channel (in the format @@channelusername@) - , _voice_voice :: payload -- ^ Audio file to send. You can either pass a file_id as String to resend an audio that is already on the Telegram servers, or upload a new audio file. - , _voice_caption :: Maybe Text -- ^ Voice message caption, 0-200 characters - , _voice_duration :: Maybe Int -- ^ Duration of sent audio in seconds - , _voice_disable_notification :: Maybe Bool -- ^ Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. - , _voice_reply_to_message_id :: Maybe Int -- ^ If the message is a reply, ID of the original message - , _voice_reply_markup :: Maybe ReplyKeyboard -- ^ Additional interface options. A JSON-serialized object for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user. + _voice_chat_id :: Text -- ^ Unique identifier for the target chat or username of the target channel (in the format @@channelusername@) + , _voice_voice :: payload -- ^ Audio file to send. You can either pass a file_id as String to resend an audio that is already on the Telegram servers, or upload a new audio file. + , _voice_caption :: Maybe Text -- ^ Voice message caption, 0-200 characters + , _voice_duration :: Maybe Int -- ^ Duration of sent audio in seconds + , _voice_disable_notification :: Maybe Bool -- ^ Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. + , _voice_reply_to_message_id :: Maybe Int -- ^ If the message is a reply, ID of the original message + , _voice_reply_markup :: Maybe ReplyKeyboard -- ^ Additional interface options. A JSON-serialized object for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user. } deriving (Show, Generic) instance ToJSON (SendVoiceRequest Text) where @@ -381,12 +423,12 @@ -- | This object represents request for 'sendLocation' data SendLocationRequest = SendLocationRequest { - location_chat_id :: Text -- ^ Unique identifier for the target chat or username of the target channel (in the format @@channelusername@) - , location_latitude :: Float -- ^ Latitude of location - , location_longitude :: Float -- ^ Longitude of location - , location_disable_notification :: Maybe Bool -- ^ Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. - , location_reply_to_message_id :: Maybe Int -- ^ If the message is a reply, ID of the original message - , location_reply_markup :: Maybe ReplyKeyboard -- ^ Additional interface options. A JSON-serialized object for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user. + location_chat_id :: Text -- ^ Unique identifier for the target chat or username of the target channel (in the format @@channelusername@) + , location_latitude :: Float -- ^ Latitude of location + , location_longitude :: Float -- ^ Longitude of location + , location_disable_notification :: Maybe Bool -- ^ Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. + , location_reply_to_message_id :: Maybe Int -- ^ If the message is a reply, ID of the original message + , location_reply_markup :: Maybe ReplyKeyboard -- ^ Additional interface options. A JSON-serialized object for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user. } deriving (Show, Generic) instance ToJSON SendLocationRequest where @@ -401,15 +443,15 @@ -- | This object represents request for 'sendVenue' data SendVenueRequest = SendVenueRequest { - _venue_chat_id :: Text -- ^ Unique identifier for the target chat or username of the target channel (in the format @@channelusername@) - , _venue_latitude :: Float -- ^ Latitude of the venue - , _venue_longitude :: Float -- ^ Longitude of the venue - , _venue_title :: Text -- ^ Name of the venue - , _venue_address :: Text -- ^ Address of the venue - , _venue_foursquare_id :: Maybe Text -- ^ Foursquare identifier of the venue - , _venue_disable_notification :: Maybe Bool -- ^ Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. - , _venue_reply_to_message_id :: Maybe Int -- ^ If the message is a reply, ID of the original message - , _venue_reply_markup :: Maybe ReplyKeyboard -- ^ Additional interface options. A JSON-serialized object for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user. + _venue_chat_id :: Text -- ^ Unique identifier for the target chat or username of the target channel (in the format @@channelusername@) + , _venue_latitude :: Float -- ^ Latitude of the venue + , _venue_longitude :: Float -- ^ Longitude of the venue + , _venue_title :: Text -- ^ Name of the venue + , _venue_address :: Text -- ^ Address of the venue + , _venue_foursquare_id :: Maybe Text -- ^ Foursquare identifier of the venue + , _venue_disable_notification :: Maybe Bool -- ^ Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. + , _venue_reply_to_message_id :: Maybe Int -- ^ If the message is a reply, ID of the original message + , _venue_reply_markup :: Maybe ReplyKeyboard -- ^ Additional interface options. A JSON-serialized object for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user. } deriving (Show, Generic) instance ToJSON SendVenueRequest where @@ -477,7 +519,7 @@ data SendChatActionRequest = SendChatActionRequest { action_chat_id :: Text -- ^ Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) - , action_action :: ChatAction -- ^ Type of action to broadcast. + , action_action :: ChatAction -- ^ Type of action to broadcast. } deriving (Show, Generic) instance ToJSON SendChatActionRequest where @@ -492,11 +534,11 @@ -- | This object represents request for 'sendGame' data SendGameRequest = SendGameRequest { - game_chat_id :: Text -- ^ Unique identifier for the target chat - , game_game_short_name :: Text -- ^ Short name of the game, serves as the unique identifier for the game. Set up your games via Botfather. + game_chat_id :: Text -- ^ Unique identifier for the target chat + , game_game_short_name :: Text -- ^ Short name of the game, serves as the unique identifier for the game. Set up your games via Botfather. , game_disable_notification :: Maybe Bool -- ^ Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. - , game_reply_to_message_id :: Maybe Int -- ^ If the message is a reply, ID of the original message - , game_reply_markup :: Maybe InlineKeyboardMarkup -- ^ A JSON-serialized object for an inline keyboard. If empty, one ‘Play game_title’ button will be shown. If not empty, the first button must launch the game. + , game_reply_to_message_id :: Maybe Int -- ^ If the message is a reply, ID of the original message + , game_reply_markup :: Maybe InlineKeyboardMarkup -- ^ A JSON-serialized object for an inline keyboard. If empty, one ‘Play game_title’ button will be shown. If not empty, the first button must launch the game. } deriving (Show, Generic) instance ToJSON SendGameRequest where @@ -538,10 +580,10 @@ data AnswerCallbackQueryRequest = AnswerCallbackQueryRequest { cq_callback_query_id :: Text -- ^ Unique identifier for the query to be answered - , cq_text :: Maybe Text -- ^ Text of the notification. If not specified, nothing will be shown to the user - , cq_show_alert :: Maybe Bool -- ^ If true, an alert will be shown by the client instead of a notification at the top of the chat screen. Defaults to false. - , cq_url :: Maybe Text -- ^ URL that will be opened by the user's client. If you have created a `Game` and accepted the conditions via `@Botfather`, specify the URL that opens your game – note that this will only work if the query comes from a `callback_game` button. Otherwise, you may use links like telegram.me/your_bot?start=XXXX that open your bot with a parameter. - , cq_cache_time :: Maybe Int -- ^ The maximum amount of time in seconds that the result of the callback query may be cached client-side. Telegram apps will support caching starting in version 3.14. Defaults to 0. + , cq_text :: Maybe Text -- ^ Text of the notification. If not specified, nothing will be shown to the user + , cq_show_alert :: Maybe Bool -- ^ If true, an alert will be shown by the client instead of a notification at the top of the chat screen. Defaults to false. + , cq_url :: Maybe Text -- ^ URL that will be opened by the user's client. If you have created a `Game` and accepted the conditions via `@Botfather`, specify the URL that opens your game – note that this will only work if the query comes from a `callback_game` button. Otherwise, you may use links like telegram.me/your_bot?start=XXXX that open your bot with a parameter. + , cq_cache_time :: Maybe Int -- ^ The maximum amount of time in seconds that the result of the callback query may be cached client-side. Telegram apps will support caching starting in version 3.14. Defaults to 0. } deriving (Show, Generic) instance ToJSON AnswerCallbackQueryRequest where @@ -561,27 +603,27 @@ } | ReplyKeyboardMarkup { - reply_keyboard :: [[KeyboardButton]] -- ^ Array of button rows, each represented by an Array of 'KeyboardButton' objects - , reply_resize_keyboard :: Maybe Bool -- ^ Requests clients to resize the keyboard vertically for optimal fit (e.g., make the keyboard smaller if there are just two rows of buttons). Defaults to false, in which case the custom keyboard is always of the same height as the app's standard keyboard. - , reply_one_time_keyboard :: Maybe Bool -- ^ Requests clients to hide the keyboard as soon as it's been used. Defaults to false. - , reply_selective :: Maybe Bool -- ^ Use this parameter if you want to show the keyboard to specific users only. Targets: 1) users that are @mentioned in the text of the Message object; 2) if the bot's message is a reply (has reply_to_message_id), sender of the original message. Example: A user requests to change the bot‘s language, bot replies to the request with a keyboard to select the new language. Other users in the group don’t see the keyboard. + reply_keyboard :: [[KeyboardButton]] -- ^ Array of button rows, each represented by an Array of 'KeyboardButton' objects + , reply_resize_keyboard :: Maybe Bool -- ^ Requests clients to resize the keyboard vertically for optimal fit (e.g., make the keyboard smaller if there are just two rows of buttons). Defaults to false, in which case the custom keyboard is always of the same height as the app's standard keyboard. + , reply_one_time_keyboard :: Maybe Bool -- ^ Requests clients to hide the keyboard as soon as it's been used. Defaults to false. + , reply_selective :: Maybe Bool -- ^ Use this parameter if you want to show the keyboard to specific users only. Targets: 1) users that are @mentioned in the text of the Message object; 2) if the bot's message is a reply (has reply_to_message_id), sender of the original message. Example: A user requests to change the bot‘s language, bot replies to the request with a keyboard to select the new language. Other users in the group don’t see the keyboard. } -- | Upon receiving a message with this object, Telegram clients will hide the current custom keyboard and display the default letter-keyboard. By default, custom keyboards are displayed until a new keyboard is sent by a bot. An exception is made for one-time keyboards that are hidden immediately after the user presses a button | ReplyKeyboardHide { - reply_hide_keyboard :: Bool -- ^ Requests clients to hide the custom keyboard - , reply_selective :: Maybe Bool -- ^ Use this parameter if you want to hide keyboard for specific users only. Targets: 1) users that are @mentioned in the text of the Message object; 2) if the bot's message is a reply (has reply_to_message_id), sender of the original message. Example: A user votes in a poll, bot returns confirmation message in reply to the vote and hides keyboard for that user, while still showing the keyboard with poll options to users who haven't voted yet. + reply_hide_keyboard :: Bool -- ^ Requests clients to hide the custom keyboard + , reply_selective :: Maybe Bool -- ^ Use this parameter if you want to hide keyboard for specific users only. Targets: 1) users that are @mentioned in the text of the Message object; 2) if the bot's message is a reply (has reply_to_message_id), sender of the original message. Example: A user votes in a poll, bot returns confirmation message in reply to the vote and hides keyboard for that user, while still showing the keyboard with poll options to users who haven't voted yet. } | ReplyKeyboardRemove { - reply_remove_keyboard :: Bool -- ^ Requests clients to remove the custom keyboard (user will not be able to summon this keyboard; if you want to hide the keyboard from sight but keep it accessible, use one_time_keyboard in 'ReplyKeyboardMarkup') - , reply_selective :: Maybe Bool -- ^ Use this parameter if you want to hide keyboard for specific users only. Targets: 1) users that are @mentioned in the text of the Message object; 2) if the bot's message is a reply (has reply_to_message_id), sender of the original message. Example: A user votes in a poll, bot returns confirmation message in reply to the vote and hides keyboard for that user, while still showing the keyboard with poll options to users who haven't voted yet. + reply_remove_keyboard :: Bool -- ^ Requests clients to remove the custom keyboard (user will not be able to summon this keyboard; if you want to hide the keyboard from sight but keep it accessible, use one_time_keyboard in 'ReplyKeyboardMarkup') + , reply_selective :: Maybe Bool -- ^ Use this parameter if you want to hide keyboard for specific users only. Targets: 1) users that are @mentioned in the text of the Message object; 2) if the bot's message is a reply (has reply_to_message_id), sender of the original message. Example: A user votes in a poll, bot returns confirmation message in reply to the vote and hides keyboard for that user, while still showing the keyboard with poll options to users who haven't voted yet. } -- | Upon receiving a message with this object, Telegram clients will display a reply interface to the user (act as if the user has selected the bot‘s message and tapped ’Reply'). This can be extremely useful if you want to create user-friendly step-by-step interfaces without having to sacrifice privacy mode. | ForceReply { - reply_force_reply :: Bool -- ^ Shows reply interface to the user, as if they manually selected the bot‘s message and tapped ’Reply' - , reply_selective :: Maybe Bool -- ^ Use this parameter if you want to force reply from specific users only. Targets: 1) users that are @mentioned in the text of the Message object; 2) if the bot's message is a reply (has reply_to_message_id), sender of the original message. + reply_force_reply :: Bool -- ^ Shows reply interface to the user, as if they manually selected the bot‘s message and tapped ’Reply' + , reply_selective :: Maybe Bool -- ^ Use this parameter if you want to force reply from specific users only. Targets: 1) users that are @mentioned in the text of the Message object; 2) if the bot's message is a reply (has reply_to_message_id), sender of the original message. } deriving (Show, Generic) instance ToJSON ReplyKeyboard where @@ -604,13 +646,13 @@ data EditMessageTextRequest = EditMessageTextRequest { - emt_chat_id :: Maybe Text -- ^ Required if `inline_message_id` is not specified. Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) - , emt_message_id :: Maybe Int -- ^ if `inline_message_id` is not specified. Unique identifier of the sent message - , emt_inline_message_id :: Maybe Text -- ^ Required if chat_id and message_id are not specified. Identifier of the inline message - , emt_text :: Text -- ^ New text of the message - , emt_parse_mode :: Maybe ParseMode -- ^ Send `Markdown` or `HTML`, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. + emt_chat_id :: Maybe Text -- ^ Required if `inline_message_id` is not specified. Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) + , emt_message_id :: Maybe Int -- ^ if `inline_message_id` is not specified. Unique identifier of the sent message + , emt_inline_message_id :: Maybe Text -- ^ Required if chat_id and message_id are not specified. Identifier of the inline message + , emt_text :: Text -- ^ New text of the message + , emt_parse_mode :: Maybe ParseMode -- ^ Send `Markdown` or `HTML`, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. , emt_disable_web_page_preview :: Maybe Bool -- ^ Disables link previews for links in this message - , emt_reply_markup :: Maybe InlineKeyboardMarkup -- ^ A JSON-serialized object for an inline keyboard. + , emt_reply_markup :: Maybe InlineKeyboardMarkup -- ^ A JSON-serialized object for an inline keyboard. } deriving (Show, Generic) instance ToJSON EditMessageTextRequest where @@ -627,11 +669,11 @@ data EditMessageCaptionRequest = EditMessageCaptionRequest { - emc_chat_id :: Maybe Text -- ^ Required if `inline_message_id` is not specified. Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) - , emc_message_id :: Maybe Int -- ^ Required if `inline_message_id` is not specified. Unique identifier of the sent message + emc_chat_id :: Maybe Text -- ^ Required if `inline_message_id` is not specified. Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) + , emc_message_id :: Maybe Int -- ^ Required if `inline_message_id` is not specified. Unique identifier of the sent message , emc_inline_message_id :: Maybe Text -- ^ Required if `chat_id` and `message_id` are not specified. Identifier of the inline message - , emc_caption :: Maybe Text -- ^ New caption of the message - , emc_reply_markup :: Maybe InlineKeyboardMarkup -- ^ A JSON-serialized object for an inline keyboard. + , emc_caption :: Maybe Text -- ^ New caption of the message + , emc_reply_markup :: Maybe InlineKeyboardMarkup -- ^ A JSON-serialized object for an inline keyboard. } deriving (Show, Generic) instance ToJSON EditMessageCaptionRequest where @@ -648,10 +690,10 @@ data EditMessageReplyMarkupRequest = EditMessageReplyMarkupRequest { - emrm_chat_id :: Maybe Text -- ^ Required if `inline_message_id` is not specified. Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) - , emrm_message_id :: Maybe Int -- ^ Required if `inline_message_id` is not specified. Unique identifier of the sent message + emrm_chat_id :: Maybe Text -- ^ Required if `inline_message_id` is not specified. Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) + , emrm_message_id :: Maybe Int -- ^ Required if `inline_message_id` is not specified. Unique identifier of the sent message , emrm_inline_message_id :: Maybe Text -- ^ Required if `chat_id` and `message_id` are not specified. Identifier of the inline message - , emrm_reply_markup :: Maybe InlineKeyboardMarkup -- ^ A JSON-serialized object for an inline keyboard. + , emrm_reply_markup :: Maybe InlineKeyboardMarkup -- ^ A JSON-serialized object for an inline keyboard. } deriving (Show, Generic) instance ToJSON EditMessageReplyMarkupRequest where
src/Web/Telegram/API/Bot/Responses.hs view
@@ -1,5 +1,5 @@-{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-} -- | This module contains responses from Telegram Bot API @@ -33,14 +33,14 @@ data Response a = Response { - result :: a + result :: a , parameters :: Maybe ResponseParameters } deriving (Show, Generic, FromJSON) data ResponseParameters = ResponseParameters { res_migrate_to_chat_id :: Maybe Int -- ^ The group has been migrated to a supergroup with the specified identifier. This number may be greater than 32 bits and some programming languages may have difficulty/silent defects in interpreting it. But it is smaller than 52 bits, so a signed 64 bit integer or double-precision float type are safe for storing this identifier. - , res_retry_after :: Maybe Int -- ^ In case of exceeding flood control, the number of seconds left to wait before the request can be repeated + , res_retry_after :: Maybe Int -- ^ In case of exceeding flood control, the number of seconds left to wait before the request can be repeated } deriving (Show, Generic) instance FromJSON ResponseParameters where @@ -89,4 +89,4 @@ type GetChatMemberResponse = Response ChatMember -type GetWebhookInfoResponse = Response WebhookInfo+type GetWebhookInfoResponse = Response WebhookInfo
telegram-api.cabal view
@@ -1,5 +1,5 @@ name: telegram-api -version: 0.5.2.0 +version: 0.6.0.0 synopsis: Telegram Bot API bindings description: High-level bindings to the Telegram Bot API homepage: http://github.com/klappvisor/haskell-telegram-api#readme @@ -28,10 +28,17 @@ hs-source-dirs: src exposed-modules: Web.Telegram.API.Bot , Web.Telegram.API.Bot.API + , Web.Telegram.API.Bot.API.Messages + , Web.Telegram.API.Bot.API.Edit + , Web.Telegram.API.Bot.API.Queries + , Web.Telegram.API.Bot.API.Get + , Web.Telegram.API.Bot.API.Updates + , Web.Telegram.API.Bot.API.Chats , Web.Telegram.API.Bot.Data , Web.Telegram.API.Bot.Responses , Web.Telegram.API.Bot.Requests other-modules: Web.Telegram.API.Bot.JsonExt + , Web.Telegram.API.Bot.API.Core , Servant.Client.MultipartFormData build-depends: base >= 4.7 && < 5 , aeson == 1.0.* @@ -57,6 +64,7 @@ other-modules: MainSpec , InlineSpec , JsonSpec + , UpdatesSpec build-depends: base , aeson == 1.0.* , hjpath
test/InlineSpec.hs view
@@ -2,11 +2,11 @@ module InlineSpec (spec) where -import Web.Telegram.API.Bot +import Data.Text (Text) +import Network.HTTP.Client (newManager) +import Network.HTTP.Client.TLS (tlsManagerSettings) import Test.Hspec -import Data.Text (Text) -import Network.HTTP.Client (newManager) -import Network.HTTP.Client.TLS (tlsManagerSettings) +import Web.Telegram.API.Bot spec :: Token -> Text -> Spec spec token chatId = do
test/JsonSpec.hs view
@@ -2,12 +2,12 @@ module JsonSpec (spec) where -import Web.Telegram.API.Bot -import Test.Hspec -import qualified Data.Text as T import Data.Aeson -import Text.JSON.JPath import Data.ByteString.Lazy.UTF8 +import qualified Data.Text as T +import Test.Hspec +import Text.JSON.JPath +import Web.Telegram.API.Bot spec :: Spec spec = do
test/MainSpec.hs view
@@ -5,19 +5,19 @@ module MainSpec (spec) where +import Control.Concurrent import Control.Monad +import Data.Either (isLeft, isRight) import Data.Monoid -import Web.Telegram.API.Bot -import Test.Hspec -import Data.Either (isRight, isLeft) -import Data.Text (Text) -import qualified Data.Text as T -import Network.HTTP.Client (newManager) -import Network.HTTP.Client.TLS (tlsManagerSettings) -import Servant.Client +import Data.Text (Text) +import qualified Data.Text as T +import Network.HTTP.Client (newManager) +import Network.HTTP.Client.TLS (tlsManagerSettings) import Network.HTTP.Types.Status +import Servant.Client import System.FilePath -import Control.Concurrent +import Test.Hspec +import Web.Telegram.API.Bot import Paths_telegram_api @@ -244,6 +244,7 @@ describe "/getUpdates" $ it "should get all messages" $ do + _ <- deleteWebhook token manager Right Response { result = updates} <- getUpdates token Nothing Nothing Nothing manager length updates `shouldSatisfy` (>= 0) @@ -268,7 +269,7 @@ describe "/setWebhook and /getWebhookInfo" $ do it "should set webhook with certificate" $ do let cert = localFileUpload $ testFile "cert.pem" - req = SetWebhookRequest "https://example.com/secret_token" cert + req = setWebhookRequest "https://example.com/secret_token" cert res <- setWebhookWithCertificate token req manager success res let Right Response { result = val } = res
test/Spec.hs view
@@ -3,13 +3,14 @@ module Main (main) where -import Data.Monoid ((<>)) import Data.Maybe (fromMaybe) +import Data.Monoid ((<>)) import Data.Text (Text) import qualified Data.Text as T -import qualified MainSpec import qualified JsonSpec +import qualified MainSpec import Options.Applicative +import qualified UpdatesSpec import System.Environment (withArgs) import Test.Hspec import qualified Text.PrettyPrint.ANSI.Leijen as PP @@ -64,7 +65,7 @@ runSpec' :: Bool -> Maybe Token -> Maybe Text -> Maybe Text -> SpecWith () runSpec' integration token chatId botName = do describe "Unit tests" $ do - describe "Json tests" $ JsonSpec.spec + describe "Json tests" JsonSpec.spec if integration then runIntegrationSpec token chatId botName else describe "Integration tests" $ it "skipping..." $ pendingWith "Use --integration switch to run integration tests" @@ -73,12 +74,13 @@ runIntegrationSpec :: Maybe Token -> Maybe Text -> Maybe Text -> SpecWith () runIntegrationSpec (Just token) (Just chatId) (Just botName) = do describe "Main integration tests" $ MainSpec.spec token chatId botName + describe "Updates API spec" $ UpdatesSpec.spec token botName --describe "Inline integration tests" $ InlineSpec.spec token chatId botName runIntegrationSpec _ _ _ = describe "Integration tests" $ do fail "Missing required arguments for integration tests. Run stack test --test-arguments \"--help\" for more info" description :: Maybe PP.Doc description = Just $ - (PP.text "Run the haskell-telegram-api tests") + (PP.text "Run the haskell-telegram-api tests") PP.<$> ((PP.text "Running with stack: ") PP.<> (PP.text "stack test --test-arguments=\"--integration -t asd128903uiasbfì1023u -c 1235122 -b MyTeleBot -- -m send\"")) PP.<$> ((PP.red . PP.text $ "WARNING: ") PP.<> (PP.text "the HSPEC_ARGS are optional but if present MUST be at the end and seperated from the other options with a -- "))
+ test/UpdatesSpec.hs view
@@ -0,0 +1,72 @@+{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TypeOperators #-} + +module UpdatesSpec (spec) where + +import Control.Concurrent +import Control.Monad.IO.Class +import Data.Text (Text) +import Network.HTTP.Client (newManager) +import Network.HTTP.Client.TLS (tlsManagerSettings) +import Test.Hspec +import Web.Telegram.API.Bot +import qualified Data.Text as T + +spec :: Token -> Text -> Spec +spec token botName = do + manager <- runIO $ newManager tlsManagerSettings + describe "/getMe and /getWebhookInfo work together" $ + it "responds with correct bot's name and empty webhook" $ do + res <- runClient ( do + b <- getMeM + info <- getWebhookInfoM + return (b, info)) token manager + let Right (Response {result = me}, Response {result = whi}) = res + user_first_name me `shouldBe` botName + whi_url whi `shouldBe` "" + describe "webhook operations" $ do + let url = "https://example.com/bot" + it "able to get and set webhook" $ do + res <- runClient ( do + info <- getWebhookInfoM + liftIO $ (whi_url . result) info `shouldBe` "" + liftIO $ threadDelay $ 2 * 1000 * 1000 -- to avoid Too many request error + set <- setWebhookM $ setWebhookRequest' url + liftIO $ result set `shouldBe` True + info <- getWebhookInfoM + liftIO $ (whi_url . result) info `shouldBe` url + liftIO $ threadDelay $ 2 * 1000 * 1000 -- to avoid Too many request error + del <- deleteWebhookM + liftIO $ result del `shouldBe` True + getWebhookInfoM ) token manager + let Right Response { result = whi } = res + whi_url whi `shouldBe` "" + + it "should set allowed updates" $ do + let allowedUpdates = map T.pack ["message", "callback_query"] + res <- runClient ( do + let request = (setWebhookRequest' url) { + webhook_allowed_updates = Just allowedUpdates + } + set <- setWebhookM request + liftIO $ result set `shouldBe` True + getWebhookInfoM ) token manager + let Right Response { result = whi } = res + whi_allowed_updates whi `shouldBe` Just allowedUpdates + + it "should set max connections" $ do + res <- runClient ( do + + let request = (setWebhookRequest' url) { + webhook_max_connections = Just 5 + } + liftIO $ threadDelay $ 2 * 1000 * 1000 -- to avoid Too many request error + set <- setWebhookM request + liftIO $ result set `shouldBe` True + getWebhookInfoM ) token manager + let Right Response { result = whi } = res + whi_max_connections whi `shouldBe` Just 5 + +