diff options
Diffstat (limited to 'Omni/Agent/Telegram')
| -rw-r--r-- | Omni/Agent/Telegram/Types.hs | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/Omni/Agent/Telegram/Types.hs b/Omni/Agent/Telegram/Types.hs index 7a91df3..e6d8957 100644 --- a/Omni/Agent/Telegram/Types.hs +++ b/Omni/Agent/Telegram/Types.hs @@ -22,9 +22,15 @@ module Omni.Agent.Telegram.Types BotAddedToGroup (..), ChatType (..), + -- * Inline Keyboard + InlineKeyboardMarkup (..), + InlineKeyboardButton (..), + CallbackQuery (..), + -- * Parsing parseUpdate, parseBotAddedToGroup, + parseCallbackQuery, parseDocument, parseLargestPhoto, parsePhotoSize, @@ -652,3 +658,109 @@ shouldRespondInGroup botUsername msg mention = "@" <> Text.toLower botUsername isMentioned = mention `Text.isInfixOf` msgText isReplyToBot = isJust (tmReplyTo msg) + +-- | Inline keyboard button +data InlineKeyboardButton = InlineKeyboardButton + { ikbText :: Text, + ikbCallbackData :: Maybe Text, + ikbUrl :: Maybe Text + } + deriving (Show, Eq, Generic) + +instance Aeson.ToJSON InlineKeyboardButton where + toJSON b = + Aeson.object + <| catMaybes + [ Just ("text" .= ikbText b), + ("callback_data" .=) </ ikbCallbackData b, + ("url" .=) </ ikbUrl b + ] + +instance Aeson.FromJSON InlineKeyboardButton where + parseJSON = + Aeson.withObject "InlineKeyboardButton" <| \v -> + (InlineKeyboardButton </ (v .: "text")) + <*> (v .:? "callback_data") + <*> (v .:? "url") + +-- | Inline keyboard markup (grid of buttons) +newtype InlineKeyboardMarkup = InlineKeyboardMarkup + { ikmInlineKeyboard :: [[InlineKeyboardButton]] + } + deriving (Show, Eq, Generic) + +instance Aeson.ToJSON InlineKeyboardMarkup where + toJSON m = Aeson.object ["inline_keyboard" .= ikmInlineKeyboard m] + +instance Aeson.FromJSON InlineKeyboardMarkup where + parseJSON = + Aeson.withObject "InlineKeyboardMarkup" <| \v -> + InlineKeyboardMarkup </ (v .: "inline_keyboard") + +-- | Callback query from inline keyboard button press +data CallbackQuery = CallbackQuery + { cqId :: Text, + cqFromId :: Int, + cqFromFirstName :: Text, + cqChatId :: Int, + cqMessageId :: Int, + cqData :: Text + } + deriving (Show, Eq, Generic) + +instance Aeson.ToJSON CallbackQuery where + toJSON cq = + Aeson.object + [ "id" .= cqId cq, + "from_id" .= cqFromId cq, + "from_first_name" .= cqFromFirstName cq, + "chat_id" .= cqChatId cq, + "message_id" .= cqMessageId cq, + "data" .= cqData cq + ] + +instance Aeson.FromJSON CallbackQuery where + parseJSON = + Aeson.withObject "CallbackQuery" <| \v -> + (CallbackQuery </ (v .: "id")) + <*> (v .: "from_id") + <*> (v .: "from_first_name") + <*> (v .: "chat_id") + <*> (v .: "message_id") + <*> (v .: "data") + +-- | Parse a callback query from a raw Telegram update +parseCallbackQuery :: Aeson.Value -> Maybe CallbackQuery +parseCallbackQuery val = do + Aeson.Object obj <- pure val + Aeson.Object cqObj <- KeyMap.lookup "callback_query" obj + cqId <- case KeyMap.lookup "id" cqObj of + Just (Aeson.String s) -> Just s + _ -> Nothing + Aeson.Object fromObj <- KeyMap.lookup "from" cqObj + fromId <- case KeyMap.lookup "id" fromObj of + Just (Aeson.Number n) -> Just (round n) + _ -> Nothing + fromFirstName <- case KeyMap.lookup "first_name" fromObj of + Just (Aeson.String s) -> Just s + _ -> Nothing + Aeson.Object msgObj <- KeyMap.lookup "message" cqObj + Aeson.Object chatObj <- KeyMap.lookup "chat" msgObj + chatId <- case KeyMap.lookup "id" chatObj of + Just (Aeson.Number n) -> Just (round n) + _ -> Nothing + messageId <- case KeyMap.lookup "message_id" msgObj of + Just (Aeson.Number n) -> Just (round n) + _ -> Nothing + callbackData <- case KeyMap.lookup "data" cqObj of + Just (Aeson.String s) -> Just s + _ -> Nothing + pure + CallbackQuery + { cqId = cqId, + cqFromId = fromId, + cqFromFirstName = fromFirstName, + cqChatId = chatId, + cqMessageId = messageId, + cqData = callbackData + } |
