Hello community, here is the log from the commit of package ghc-telegram-api for openSUSE:Factory checked in at 2017-05-18 20:51:10 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ghc-telegram-api (Old) and /work/SRC/openSUSE:Factory/.ghc-telegram-api.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-telegram-api" Thu May 18 20:51:10 2017 rev:2 rq:495712 version:0.6.1.1 Changes: -------- --- /work/SRC/openSUSE:Factory/ghc-telegram-api/ghc-telegram-api.changes 2017-05-10 20:45:56.273620241 +0200 +++ /work/SRC/openSUSE:Factory/.ghc-telegram-api.new/ghc-telegram-api.changes 2017-05-18 20:51:17.946035886 +0200 @@ -1,0 +2,10 @@ +Wed May 3 08:14:03 UTC 2017 - [email protected] + +- Update to version 0.6.1.1 with cabal2obs. + +------------------------------------------------------------------- +Tue Mar 14 09:26:22 UTC 2017 - [email protected] + +- Update to version 0.6.1.0 with cabal2obs. + +------------------------------------------------------------------- Old: ---- telegram-api-0.6.0.2.tar.gz New: ---- telegram-api-0.6.1.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-telegram-api.spec ++++++ --- /var/tmp/diff_new_pack.I50t6S/_old 2017-05-18 20:51:20.009744642 +0200 +++ /var/tmp/diff_new_pack.I50t6S/_new 2017-05-18 20:51:20.009744642 +0200 @@ -19,7 +19,7 @@ %global pkg_name telegram-api %bcond_with tests Name: ghc-%{pkg_name} -Version: 0.6.0.2 +Version: 0.6.1.1 Release: 0 Summary: Telegram Bot API bindings License: BSD-3-Clause ++++++ telegram-api-0.6.0.2.tar.gz -> telegram-api-0.6.1.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/telegram-api-0.6.0.2/CHANGELOG.md new/telegram-api-0.6.1.1/CHANGELOG.md --- old/telegram-api-0.6.0.2/CHANGELOG.md 2017-01-31 20:10:31.000000000 +0100 +++ new/telegram-api-0.6.1.1/CHANGELOG.md 2017-04-30 17:21:45.000000000 +0200 @@ -1,3 +1,18 @@ +## 0.6.1.1 + +Bugfixes: + +* Migration to `Int64` to represent chat id and fix integer overflow issue + +## 0.6.1.0 + +* Added `ChatId` data type since it can be integer or string starting from `@`, f.e. `@channelusername` +* Changes in `getUpdates` and `getUpdateM` function + +## 0.6.0.1 + +* Bump aeson upper bound to include 1.1.* + ## 0.6.0.0 * Added `TelegramClient`, see example of usage in README.md diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/telegram-api-0.6.0.2/src/Web/Telegram/API/Bot/API/Get.hs new/telegram-api-0.6.1.1/src/Web/Telegram/API/Bot/API/Get.hs --- old/telegram-api-0.6.0.2/src/Web/Telegram/API/Bot/API/Get.hs 2017-01-31 20:10:31.000000000 +0100 +++ new/telegram-api-0.6.1.1/src/Web/Telegram/API/Bot/API/Get.hs 2017-03-06 21:48:58.000000000 +0100 @@ -17,8 +17,8 @@ ) where import Data.Proxy -import Data.Text (Text) -import Network.HTTP.Client (Manager) +import Data.Text (Text) +import Network.HTTP.Client (Manager) import Servant.API import Servant.Client import Web.Telegram.API.Bot.API.Core @@ -32,7 +32,7 @@ :> QueryParam "file_id" Text :> Get '[JSON] FileResponse :<|> TelegramToken :> "getUserProfilePhotos" - :> QueryParam "user_id" Int + :> QueryParam "user_id" Integer :> QueryParam "offset" Int :> QueryParam "limit" Int :> Get '[JSON] UserProfilePhotosResponse @@ -43,7 +43,7 @@ getMe_ :: Token -> ClientM GetMeResponse getFile_ :: Token -> Maybe Text -> ClientM FileResponse -getUserProfilePhotos_ :: Token -> Maybe Int -> Maybe Int -> Maybe Int -> ClientM UserProfilePhotosResponse +getUserProfilePhotos_ :: Token -> Maybe Integer -> Maybe Int -> Maybe Int -> ClientM UserProfilePhotosResponse getMe_ :<|> getFile_ :<|> getUserProfilePhotos_ @@ -67,9 +67,9 @@ 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 -> Integer -> 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 :: Integer -> Maybe Int -> Maybe Int -> TelegramClient UserProfilePhotosResponse getUserProfilePhotosM userId offset limit = asking $ \t -> getUserProfilePhotos_ t (Just userId) offset limit diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/telegram-api-0.6.0.2/src/Web/Telegram/API/Bot/API/Updates.hs new/telegram-api-0.6.1.1/src/Web/Telegram/API/Bot/API/Updates.hs --- old/telegram-api-0.6.0.2/src/Web/Telegram/API/Bot/API/Updates.hs 2017-01-31 20:10:31.000000000 +0100 +++ new/telegram-api-0.6.1.1/src/Web/Telegram/API/Bot/API/Updates.hs 2017-03-06 22:07:07.000000000 +0100 @@ -6,6 +6,7 @@ ( -- * Functions getUpdates , getUpdatesM + , getUpdatesM' , setWebhook , setWebhookM , setWebhookWithCertificate @@ -19,8 +20,8 @@ , updatesApi ) where -import Data.Proxy import Data.Maybe +import Data.Proxy import Data.Text (Text, empty) import Network.HTTP.Client (Manager) import Servant.API @@ -61,7 +62,7 @@ :<|> 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 +-- | Use this method to receive incoming updates using long polling. A list of 'Update' objects is returned. Use `getUpdatesM` for more features getUpdates :: Token -> Maybe Int -- ^ offset @@ -69,16 +70,16 @@ -> Maybe Int -- ^ timeout -> Manager -> IO (Either ServantError UpdatesResponse) -getUpdates token offset limit timeout = runClient (getUpdatesM' request) token +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 +-- | Get update with default parameters See 'getUpdates' for details. +getUpdatesM' :: TelegramClient UpdatesResponse +getUpdatesM' = getUpdatesM getUpdatesRequest -- | See 'getUpdates' -getUpdatesM' :: GetUpdatesRequest -> TelegramClient UpdatesResponse -getUpdatesM' = run_ 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. -- @@ -104,7 +105,7 @@ 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. +-- | 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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/telegram-api-0.6.0.2/src/Web/Telegram/API/Bot/Data.hs new/telegram-api-0.6.1.1/src/Web/Telegram/API/Bot/Data.hs --- old/telegram-api-0.6.0.2/src/Web/Telegram/API/Bot/Data.hs 2017-01-31 20:10:31.000000000 +0100 +++ new/telegram-api-0.6.1.1/src/Web/Telegram/API/Bot/Data.hs 2017-04-30 16:45:16.000000000 +0200 @@ -1,5 +1,5 @@ -{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-} -- | This module contains objects which represent data of Telegram Bot API responses @@ -65,12 +65,13 @@ import Prelude hiding (id) import Data.Aeson -import Data.Maybe() import Data.Aeson.Types -import Data.Text (Text) import qualified Data.Char as Char -import GHC.Generics +import Data.Int (Int64) import Data.List +import Data.Text (Text) +import GHC.Generics + import Web.Telegram.API.Bot.JsonExt -- | This object represents a Telegram user or bot. @@ -105,8 +106,13 @@ -- | This object represents a chat. data Chat = Chat - { - chat_id :: Int -- ^ Unique identifier for this chat, not exceeding 1e13 by absolute value + { chat_id :: Int64 + -- ^ Unique identifier for this chat. + -- 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. , chat_type :: ChatType -- ^ Type of chat, can be either 'Private', 'Group', 'Supergroup' or 'Channel' , chat_title :: Maybe Text -- ^ Title, for channels and group chats , chat_username :: Maybe Text -- ^ Username, for private chats and channels if available @@ -811,8 +817,8 @@ , group_chat_created :: Maybe Bool -- ^ Service message: the group has been created , supergroup_chat_created :: Maybe Bool -- ^ Service message: the supergroup has been created , channel_chat_created :: Maybe Bool -- ^ Service message: the channel has been created - , migrate_to_chat_id :: Maybe Int -- ^ The group has been migrated to a supergroup with the specified identifier, not exceeding 1e13 by absolute value - , migrate_from_chat_id :: Maybe Int -- ^ The supergroup has been migrated from a group with the specified identifier, not exceeding 1e13 by absolute value + , migrate_to_chat_id :: Maybe Int64 -- ^ The group has been migrated to a supergroup with the specified identifier, not exceeding 1e13 by absolute value + , migrate_from_chat_id :: Maybe Int64 -- ^ The supergroup has been migrated from a group with the specified identifier, not exceeding 1e13 by absolute value , pinned_message :: Maybe Message -- ^ Specified message was pinned. Note that the Message object in this field will not contain further reply_to_message fields even if it is itself a reply. } deriving (FromJSON, ToJSON, Show, Generic) @@ -878,4 +884,4 @@ toJSON = toJsonDrop 4 instance FromJSON WebhookInfo where - parseJSON = parseJsonDrop 4 \ No newline at end of file + parseJSON = parseJsonDrop 4 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/telegram-api-0.6.0.2/src/Web/Telegram/API/Bot/Requests.hs new/telegram-api-0.6.1.1/src/Web/Telegram/API/Bot/Requests.hs --- old/telegram-api-0.6.0.2/src/Web/Telegram/API/Bot/Requests.hs 2017-01-31 20:10:31.000000000 +0100 +++ new/telegram-api-0.6.1.1/src/Web/Telegram/API/Bot/Requests.hs 2017-04-30 16:49:03.000000000 +0200 @@ -5,7 +5,8 @@ -- | This module contains data objects which represents requests to Telegram Bot API module Web.Telegram.API.Bot.Requests ( -- * Types - SendMessageRequest (..) + ChatId (..) + , SendMessageRequest (..) , ForwardMessageRequest (..) , FileUpload (..) , FileUploadContent (..) @@ -68,9 +69,11 @@ ) where import Data.Aeson +import Data.Aeson.Types (typeMismatch) import qualified Data.ByteString as BS import qualified Data.ByteString.Lazy as LBS import Data.Maybe +import Data.Int (Int64) import Data.Text (Text) import qualified Data.Text as T import qualified Data.Text.Encoding as T @@ -120,14 +123,14 @@ -- | This object represents request for 'setWebhookWithCertificate' data SetWebhookRequest = SetWebhookRequest { - 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_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_url :: Text , webhook_max_connections :: Maybe Int , webhook_allowed_updates :: Maybe [Text] } deriving (Generic) @@ -144,7 +147,7 @@ [ utf8Part "url" $ webhook_url req , fileUploadToPart "certificate" $ webhook_certificate req ] ++ catMaybes - [ utf8Part "max_connections" . T.pack . show <$> webhook_max_connections req + [ utf8Part "max_connections" . tshow <$> webhook_max_connections req -- TODO: , ??? "allowed_updates" ??? <$> webhook_allowed_updates req ] @@ -156,9 +159,9 @@ 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_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) @@ -171,10 +174,27 @@ getUpdatesRequest :: GetUpdatesRequest getUpdatesRequest = GetUpdatesRequest Nothing Nothing Nothing Nothing +-- | Unique identifier for the target chat or username of the target channel (in the format @@channelusername@) +data ChatId = ChatId Int64 | ChatChannel Text + deriving (Show) + +instance ToJSON ChatId where + toJSON (ChatId integer) = toJSON integer + toJSON (ChatChannel text) = String text + +instance FromJSON ChatId where + parseJSON value@Number{} = ChatId <$> parseJSON value + parseJSON (String text) = pure $ ChatChannel text + parseJSON wat = typeMismatch "Int64 or String" wat + +chatIdToPart :: ChatId -> Text +chatIdToPart (ChatId integer) = tshow integer +chatIdToPart (ChatChannel text) = text + -- | This object represents request for 'sendMessage' data SendMessageRequest = SendMessageRequest { - message_chat_id :: Text -- ^ Unique identifier for the target chat or username of the target channel (in the format @@channelusername@) + message_chat_id :: ChatId -- ^ Unique identifier for the target chat or username of the target channel (in the format @@channelusername@) , message_text :: Text -- ^ Text of the message to be sent , message_parse_mode :: Maybe ParseMode -- ^ Send 'Markdown', if you want Telegram apps to show bold, italic and inline URLs in your bot's message , message_disable_web_page_preview :: Maybe Bool -- ^ Disables link previews for links in this message @@ -189,14 +209,14 @@ instance FromJSON SendMessageRequest where parseJSON = parseJsonDrop 8 -sendMessageRequest :: Text -> Text -> SendMessageRequest +sendMessageRequest :: ChatId -> Text -> SendMessageRequest sendMessageRequest chatId text = SendMessageRequest chatId text Nothing Nothing Nothing Nothing Nothing -- | 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_chat_id :: ChatId -- ^ Unique identifier for the target chat or username of the target channel (in the format @@channelusername@) + , forward_from_chat_id :: ChatId -- ^ 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) @@ -207,13 +227,13 @@ instance FromJSON ForwardMessageRequest where parseJSON = parseJsonDrop 8 -forwardMessageRequest :: Text -> Text -> Int -> ForwardMessageRequest +forwardMessageRequest :: ChatId -> ChatId -> Int -> ForwardMessageRequest forwardMessageRequest chatId fromChatId forwardMessageId = ForwardMessageRequest chatId fromChatId Nothing forwardMessageId -- | This object represents request for 'sendPhoto' data SendPhotoRequest payload = SendPhotoRequest { - photo_chat_id :: Text -- ^ Unique identifier for the target chat or username of the target channel (in the format @@channelusername@) + photo_chat_id :: ChatId -- ^ Unique identifier for the target chat or username of the target channel (in the format @@channelusername@) , photo_photo :: payload -- ^ Photo to send. You can either pass a file_id as String to resend a photo that is already on the Telegram servers, or upload a new photo. , photo_caption :: Maybe Text -- ^ Photo caption (may also be used when resending photos by file_id), 0-200 characters. , photo_disable_notification :: Maybe Bool -- ^ Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. @@ -227,19 +247,19 @@ instance FromJSON (SendPhotoRequest Text) where parseJSON = parseJsonDrop 6 -sendPhotoRequest :: Text -> Text -> SendPhotoRequest Text +sendPhotoRequest :: ChatId -> Text -> SendPhotoRequest Text sendPhotoRequest chatId photo = SendPhotoRequest chatId photo Nothing Nothing Nothing Nothing -uploadPhotoRequest :: Text -> FileUpload -> SendPhotoRequest FileUpload +uploadPhotoRequest :: ChatId -> FileUpload -> SendPhotoRequest FileUpload uploadPhotoRequest chatId photo = SendPhotoRequest chatId photo Nothing Nothing Nothing Nothing instance ToMultipartFormData (SendPhotoRequest FileUpload) where toMultipartFormData req = - [ utf8Part "chat_id" (photo_chat_id req) ] ++ + [ utf8Part "chat_id" (chatIdToPart $ photo_chat_id req) ] ++ catMaybes [ utf8Part "caption" <$> photo_caption req , partLBS "disable_notification" . encode <$> photo_disable_notification req - , utf8Part "reply_to_message_id" . T.pack . show <$> photo_reply_to_message_id req + , utf8Part "reply_to_message_id" . tshow <$> photo_reply_to_message_id req , partLBS "reply_markup" . encode <$> photo_reply_markup req ] ++ [ fileUploadToPart "photo" (photo_photo req) ] @@ -247,7 +267,7 @@ -- | This object represents request for 'sendAudio' data SendAudioRequest payload = SendAudioRequest { - _audio_chat_id :: Text -- ^ Unique identifier for the target chat or username of the target channel (in the format @@channelusername@) + _audio_chat_id :: ChatId -- ^ Unique identifier for the target chat or username of the target channel (in the format @@channelusername@) , _audio_audio :: payload -- ^ Audio 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. , _audio_caption :: Maybe Text -- ^ Audio caption, 0-200 characters , _audio_duration :: Maybe Int -- ^ Duration of the audio in seconds @@ -266,27 +286,27 @@ instance ToMultipartFormData (SendAudioRequest FileUpload) where toMultipartFormData req = - [ utf8Part "chat_id" (_audio_chat_id req) ] ++ + [ utf8Part "chat_id" (chatIdToPart $ _audio_chat_id req) ] ++ catMaybes - [ utf8Part "duration" . T.pack . show <$> _audio_duration req + [ utf8Part "duration" . tshow <$> _audio_duration req , utf8Part "performer" <$> _audio_performer req , utf8Part "title" <$> _audio_title req , partLBS "disable_notification" . encode <$> _audio_disable_notification req - , utf8Part "reply_to_message_id" . T.pack . show <$> _audio_reply_to_message_id req + , utf8Part "reply_to_message_id" . tshow <$> _audio_reply_to_message_id req , partLBS "reply_markup" . encode <$> _audio_reply_markup req ] ++ [ fileUploadToPart "audio" (_audio_audio req) ] -sendAudioRequest :: Text -> Text -> SendAudioRequest Text +sendAudioRequest :: ChatId -> Text -> SendAudioRequest Text sendAudioRequest chatId audio = SendAudioRequest chatId audio Nothing Nothing Nothing Nothing Nothing Nothing Nothing -uploadAudioRequest :: Text -> FileUpload -> SendAudioRequest FileUpload +uploadAudioRequest :: ChatId -> FileUpload -> SendAudioRequest FileUpload uploadAudioRequest chatId audio = SendAudioRequest chatId audio Nothing Nothing Nothing Nothing Nothing Nothing Nothing -- | 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_chat_id :: ChatId -- ^ 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 @@ -301,24 +321,24 @@ instance ToMultipartFormData (SendStickerRequest FileUpload) where toMultipartFormData req = - [ utf8Part "chat_id" (sticker_chat_id req) ] ++ + [ utf8Part "chat_id" (chatIdToPart $ sticker_chat_id req) ] ++ catMaybes [ partLBS "disable_notification" . encode <$> sticker_disable_notification req - , utf8Part "reply_to_message_id" . T.pack . show <$> sticker_reply_to_message_id req + , utf8Part "reply_to_message_id" . tshow <$> sticker_reply_to_message_id req , partLBS "reply_markup" . encode <$> sticker_reply_markup req ] ++ [ fileUploadToPart "sticker" (sticker_sticker req) ] -sendStickerRequest :: Text -> Text -> SendStickerRequest Text +sendStickerRequest :: ChatId -> Text -> SendStickerRequest Text sendStickerRequest chatId sticker = SendStickerRequest chatId sticker Nothing Nothing Nothing -uploadStickerRequest :: Text -> FileUpload -> SendStickerRequest FileUpload +uploadStickerRequest :: ChatId -> FileUpload -> SendStickerRequest FileUpload uploadStickerRequest chatId sticker = SendStickerRequest chatId sticker Nothing Nothing Nothing -- | 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_chat_id :: ChatId -- ^ 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. @@ -334,25 +354,25 @@ instance ToMultipartFormData (SendDocumentRequest FileUpload) where toMultipartFormData req = - [ utf8Part "chat_id" (document_chat_id req) ] ++ + [ utf8Part "chat_id" (chatIdToPart $ document_chat_id req) ] ++ catMaybes [ utf8Part "caption" <$> document_caption req , partLBS "disable_notification" . encode <$> document_disable_notification req - , utf8Part "reply_to_message_id" . T.pack . show <$> document_reply_to_message_id req + , utf8Part "reply_to_message_id" . tshow <$> document_reply_to_message_id req , partLBS "reply_markup" . encode <$> document_reply_markup req ] ++ [ fileUploadToPart "document" (document_document req) ] -sendDocumentRequest :: Text -> Text -> SendDocumentRequest Text +sendDocumentRequest :: ChatId -> Text -> SendDocumentRequest Text sendDocumentRequest chatId document = SendDocumentRequest chatId document Nothing Nothing Nothing Nothing -uploadDocumentRequest :: Text -> FileUpload -> SendDocumentRequest FileUpload +uploadDocumentRequest :: ChatId -> FileUpload -> SendDocumentRequest FileUpload uploadDocumentRequest chatId document = SendDocumentRequest chatId document Nothing Nothing Nothing Nothing -- | 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_chat_id :: ChatId -- ^ 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. @@ -369,26 +389,26 @@ instance ToMultipartFormData (SendVideoRequest FileUpload) where toMultipartFormData req = - [ utf8Part "chat_id" (_video_chat_id req) ] ++ + [ utf8Part "chat_id" (chatIdToPart $ _video_chat_id req) ] ++ catMaybes [ partLBS "duration" . encode <$> _video_duration req , utf8Part "caption" <$> _video_caption req , partLBS "disable_notification" . encode <$> _video_disable_notification req - , utf8Part "reply_to_message_id" . T.pack . show <$> _video_reply_to_message_id req + , utf8Part "reply_to_message_id" . tshow <$> _video_reply_to_message_id req , partLBS "reply_markup" . encode <$> _video_reply_markup req ] ++ [ fileUploadToPart "video" (_video_video req) ] -sendVideoRequest :: Text -> Text -> SendVideoRequest Text +sendVideoRequest :: ChatId -> Text -> SendVideoRequest Text sendVideoRequest chatId video = SendVideoRequest chatId video Nothing Nothing Nothing Nothing Nothing -uploadVideoRequest :: Text -> FileUpload -> SendVideoRequest FileUpload +uploadVideoRequest :: ChatId -> FileUpload -> SendVideoRequest FileUpload uploadVideoRequest chatId video = SendVideoRequest chatId video Nothing Nothing Nothing Nothing Nothing -- | 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_chat_id :: ChatId -- ^ 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 @@ -405,25 +425,25 @@ instance ToMultipartFormData (SendVoiceRequest FileUpload) where toMultipartFormData req = - [ utf8Part "chat_id" (_voice_chat_id req) ] ++ + [ utf8Part "chat_id" (chatIdToPart $ _voice_chat_id req) ] ++ catMaybes [ partLBS "duration" . encode <$> _voice_duration req , partLBS "disable_notification" . encode <$> _voice_disable_notification req - , utf8Part "reply_to_message_id" . T.pack . show <$> _voice_reply_to_message_id req + , utf8Part "reply_to_message_id" . tshow <$> _voice_reply_to_message_id req , partLBS "reply_markup" . encode <$> _voice_reply_markup req ] ++ [ fileUploadToPart "voice" (_voice_voice req) ] -sendVoiceRequest :: Text -> Text -> SendVoiceRequest Text +sendVoiceRequest :: ChatId -> Text -> SendVoiceRequest Text sendVoiceRequest chatId voice = SendVoiceRequest chatId voice Nothing Nothing Nothing Nothing Nothing -uploadVoiceRequest :: Text -> FileUpload -> SendVoiceRequest FileUpload +uploadVoiceRequest :: ChatId -> FileUpload -> SendVoiceRequest FileUpload uploadVoiceRequest chatId voice = SendVoiceRequest chatId voice Nothing Nothing Nothing Nothing Nothing -- | 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_chat_id :: ChatId -- ^ 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. @@ -437,13 +457,13 @@ instance FromJSON SendLocationRequest where parseJSON = parseJsonDrop 9 -sendLocationRequest :: Text -> Float -> Float -> SendLocationRequest +sendLocationRequest :: ChatId -> Float -> Float -> SendLocationRequest sendLocationRequest chatId latitude longitude = SendLocationRequest chatId latitude longitude Nothing Nothing Nothing -- | 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_chat_id :: ChatId -- ^ 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 @@ -460,13 +480,13 @@ instance FromJSON SendVenueRequest where parseJSON = parseJsonDrop 7 -sendVenueRequest :: Text -> Float -> Float -> Text -> Text -> SendVenueRequest +sendVenueRequest :: ChatId -> Float -> Float -> Text -> Text -> SendVenueRequest sendVenueRequest chatId latitude longitude title address = SendVenueRequest chatId latitude longitude title address Nothing Nothing Nothing Nothing -- | This object represents request for 'sendContact' data SendContactRequest = SendContactRequest { - _contact_chat_id :: Text -- ^ Unique identifier for the target chat or username of the target channel (in the format @@channelusername@) + _contact_chat_id :: ChatId -- ^ Unique identifier for the target chat or username of the target channel (in the format @@channelusername@) , _contact_phone_number :: Text -- ^ Contact's phone number , _contact_first_name :: Text -- ^ Contact's first name , _contact_last_name :: Maybe Text -- ^ Contact's last name @@ -481,7 +501,7 @@ instance FromJSON SendContactRequest where parseJSON = parseJsonDrop 9 -sendContactRequest :: Text -> Text -> Text -> SendContactRequest +sendContactRequest :: ChatId -> Text -> Text -> SendContactRequest sendContactRequest chatId phoneNumber firstName = SendContactRequest chatId phoneNumber firstName Nothing Nothing Nothing Nothing -- | Type of action to broadcast. @@ -518,7 +538,7 @@ -- | This object represents request for 'sendChatAction' data SendChatActionRequest = SendChatActionRequest { - action_chat_id :: Text -- ^ Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) + action_chat_id :: ChatId -- ^ Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) , action_action :: ChatAction -- ^ Type of action to broadcast. } deriving (Show, Generic) @@ -528,13 +548,13 @@ instance FromJSON SendChatActionRequest where parseJSON = parseJsonDrop 7 -sendChatActionRequest :: Text -> ChatAction -> SendChatActionRequest +sendChatActionRequest :: ChatId -> ChatAction -> SendChatActionRequest sendChatActionRequest = SendChatActionRequest -- | This object represents request for 'sendGame' data SendGameRequest = SendGameRequest { - game_chat_id :: Text -- ^ Unique identifier for the target chat + game_chat_id :: Integer -- ^ 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 @@ -547,7 +567,7 @@ instance FromJSON SendGameRequest where parseJSON = parseJsonDrop 5 -sendGameRequest :: Text -> Text -> SendGameRequest +sendGameRequest :: Integer -> Text -> SendGameRequest sendGameRequest chatId shortName = SendGameRequest chatId shortName Nothing Nothing Nothing data AnswerInlineQueryRequest = AnswerInlineQueryRequest @@ -646,7 +666,7 @@ 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_chat_id :: Maybe ChatId -- ^ 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 @@ -661,7 +681,7 @@ instance FromJSON EditMessageTextRequest where parseJSON = parseJsonDrop 4 -editMessageTextRequest :: Text -> Int -> Text -> EditMessageTextRequest +editMessageTextRequest :: ChatId -> Int -> Text -> EditMessageTextRequest editMessageTextRequest chatId messageId text = EditMessageTextRequest (Just chatId) (Just messageId) Nothing text Nothing Nothing Nothing editInlineMessageTextRequest :: Text -> Text -> EditMessageTextRequest @@ -669,7 +689,7 @@ 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_chat_id :: Maybe ChatId -- ^ 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 @@ -682,7 +702,7 @@ instance FromJSON EditMessageCaptionRequest where parseJSON = parseJsonDrop 4 -editMessageCaptionRequest :: Text -> Int -> Maybe Text -> EditMessageCaptionRequest +editMessageCaptionRequest :: ChatId -> Int -> Maybe Text -> EditMessageCaptionRequest editMessageCaptionRequest chatId messageId caption = EditMessageCaptionRequest (Just chatId) (Just messageId) Nothing caption Nothing editInlineMessageCaptionRequest :: Text -> Maybe Text -> EditMessageCaptionRequest @@ -690,7 +710,7 @@ 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_chat_id :: Maybe ChatId -- ^ 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. @@ -702,8 +722,11 @@ instance FromJSON EditMessageReplyMarkupRequest where parseJSON = parseJsonDrop 5 -editMessageReplyMarkupRequest :: Text -> Int -> Maybe InlineKeyboardMarkup -> EditMessageReplyMarkupRequest +editMessageReplyMarkupRequest :: ChatId -> Int -> Maybe InlineKeyboardMarkup -> EditMessageReplyMarkupRequest editMessageReplyMarkupRequest chatId messageId keyboard = EditMessageReplyMarkupRequest (Just chatId) (Just messageId) Nothing keyboard editInlineMessageReplyMarkupRequest :: Text -> Maybe InlineKeyboardMarkup -> EditMessageReplyMarkupRequest editInlineMessageReplyMarkupRequest inlineMessageId keyboard = EditMessageReplyMarkupRequest Nothing Nothing (Just inlineMessageId) keyboard + +tshow :: Show a => a -> Text +tshow = T.pack . show diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/telegram-api-0.6.0.2/src/Web/Telegram/API/Bot/Responses.hs new/telegram-api-0.6.1.1/src/Web/Telegram/API/Bot/Responses.hs --- old/telegram-api-0.6.0.2/src/Web/Telegram/API/Bot/Responses.hs 2017-01-31 20:10:31.000000000 +0100 +++ new/telegram-api-0.6.1.1/src/Web/Telegram/API/Bot/Responses.hs 2017-04-30 17:07:34.000000000 +0200 @@ -28,6 +28,7 @@ import Data.Aeson import GHC.Generics +import Data.Int (Int64) import Web.Telegram.API.Bot.Data import Web.Telegram.API.Bot.JsonExt @@ -39,8 +40,8 @@ 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_migrate_to_chat_id :: Maybe Int64 -- ^ 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 } deriving (Show, Generic) instance FromJSON ResponseParameters where diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/telegram-api-0.6.0.2/telegram-api.cabal new/telegram-api-0.6.1.1/telegram-api.cabal --- old/telegram-api-0.6.0.2/telegram-api.cabal 2017-02-17 21:25:27.000000000 +0100 +++ new/telegram-api-0.6.1.1/telegram-api.cabal 2017-04-30 17:25:48.000000000 +0200 @@ -1,5 +1,5 @@ name: telegram-api -version: 0.6.0.2 +version: 0.6.1.1 synopsis: Telegram Bot API bindings description: High-level bindings to the Telegram Bot API homepage: http://github.com/klappvisor/haskell-telegram-api#readme diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/telegram-api-0.6.0.2/test/MainSpec.hs new/telegram-api-0.6.1.1/test/MainSpec.hs --- old/telegram-api-0.6.0.2/test/MainSpec.hs 2017-02-17 21:21:28.000000000 +0100 +++ new/telegram-api-0.6.1.1/test/MainSpec.hs 2017-04-30 17:03:54.000000000 +0200 @@ -26,7 +26,7 @@ success e = e `shouldSatisfy` isRight nosuccess e = e `shouldSatisfy` isLeft -spec :: Token -> Text -> Text -> Spec +spec :: Token -> ChatId -> Text -> Spec spec token chatId botName = do manager <- runIO $ newManager tlsManagerSettings dataDir <- runIO getDataDir @@ -45,7 +45,7 @@ text m `shouldBe` Just "test message" it "should return error message" $ do - res <- sendMessage token (sendMessageRequest "" "test message") manager + res <- sendMessage token (sendMessageRequest (ChatChannel "") "test message") manager nosuccess res let Left FailureResponse { responseStatus = Status { statusMessage = msg } } = res msg `shouldBe` "Bad Request" @@ -110,7 +110,7 @@ describe "/sendPhoto" $ do it "should return error message" $ do - let photo = (sendPhotoRequest "" "photo_id") { + let photo = (sendPhotoRequest (ChatChannel "") "photo_id") { photo_caption = Just "photo caption" } Left FailureResponse { responseStatus = Status { statusMessage = msg } } <- sendPhoto token photo manager @@ -134,7 +134,7 @@ describe "/sendAudio" $ do it "should return error message" $ do - let audio = (sendAudioRequest "" "audio_id") { + let audio = (sendAudioRequest (ChatChannel "") "audio_id") { _audio_performer = Just "performer" , _audio_title = Just "title" } @@ -262,8 +262,9 @@ describe "/getUserProfilePhotos" $ it "should get user profile photos" $ do - Right Response { result = photos } <- - getUserProfilePhotos token (read (T.unpack chatId)) Nothing Nothing manager + Right Response { result = photos } <- do + let ChatId userId = chatId + getUserProfilePhotos token (fromIntegral userId) Nothing Nothing manager total_count photos `shouldSatisfy` (>= 0) describe "/setWebhook and /getWebhookInfo" $ do diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/telegram-api-0.6.0.2/test/Spec.hs new/telegram-api-0.6.1.1/test/Spec.hs --- old/telegram-api-0.6.0.2/test/Spec.hs 2017-01-31 20:10:31.000000000 +0100 +++ new/telegram-api-0.6.1.1/test/Spec.hs 2017-03-06 21:48:58.000000000 +0100 @@ -3,6 +3,7 @@ module Main (main) where +import Data.Char (isDigit) import Data.Maybe (fromMaybe) import Data.Monoid ((<>)) import Data.Text (Text) @@ -10,10 +11,10 @@ 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 +import qualified UpdatesSpec import Web.Telegram.API.Bot -- | Command line options for test suite @@ -55,28 +56,28 @@ Options{..} <- execParser opts let integration = opt_integration token = fmap (\x -> Token ("bot" <> T.pack x)) opt_token - chatId = T.pack <$> opt_chatId + chatId = readChatId <$> opt_chatId botName = T.pack <$> opt_botName hspecArgs = fromMaybe [] opt_hSpecOpts withArgs hspecArgs $ hspec (runSpec' integration token chatId botName) where opts = info (helper <*> options) ( fullDesc <> progDescDoc description) -runSpec' :: Bool -> Maybe Token -> Maybe Text -> Maybe Text -> SpecWith () +runSpec' :: Bool -> Maybe Token -> Maybe ChatId -> Maybe Text -> SpecWith () runSpec' integration token chatId botName = do - describe "Unit tests" $ do + describe "Unit tests" $ 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" -runIntegrationSpec :: Maybe Token -> Maybe Text -> Maybe Text -> SpecWith () +runIntegrationSpec :: Maybe Token -> Maybe ChatId -> 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 +runIntegrationSpec _ _ _ = describe "Integration tests" $ fail "Missing required arguments for integration tests. Run stack test --test-arguments \"--help\" for more info" description :: Maybe PP.Doc @@ -84,3 +85,8 @@ (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 -- ")) + +readChatId :: String -> ChatId +readChatId s@('@':_) = ChatChannel $ T.pack s +readChatId s | all isDigit s = ChatId (read s) +readChatId _ = error "ChatId must be either Integer or String in form '@channel'"
