packages feed

telegram-bot-api-6.7: src/Telegram/Bot/API/InlineMode/InlineQueryResult.hs

{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE DeriveGeneric              #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase                 #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE RecordWildCards            #-}
module Telegram.Bot.API.InlineMode.InlineQueryResult where

import           Data.Aeson
                 ( FromJSON (..), ToJSON (..), KeyValue ((.=)), Value (..)
                 , withObject, (.:), (.:?)
                 )
import           Data.Aeson.Types (Parser)
import           Data.Hashable                   (Hashable)
import           Data.Text                       (Text)
import           GHC.Generics                    (Generic)

import           Telegram.Bot.API.Internal.Utils
import           Telegram.Bot.API.Types
import           Telegram.Bot.API.InlineMode.InputMessageContent
import           Telegram.Bot.API.Internal.TH (makeDefault)

import qualified Data.Text as Text

newtype InlineQueryResultId = InlineQueryResultId Text
  deriving (Eq, Show, Generic, ToJSON, FromJSON, Hashable)

data InlineQueryResultGeneric = InlineQueryResultGeneric
  { inlineQueryResultId :: InlineQueryResultId -- ^ Unique identifier for this result, 1-64 Bytes
  , inlineQueryResultTitle :: Maybe Text -- ^ Title of the result (only valid for "Article", "Photo", "Gif", "Mpeg4Gif", "Video", "Audio", "Voice", "Document", "Location", "Venue", "CachedPhoto", "CachedGif", "CachedMpeg4Gif", "CachedDocument", "CachedVideo", "CachedVoice" types of results)
  , inlineQueryResultCaption :: Maybe Text -- ^ Caption of the media to be sent, 0-1024 characters after entities parsing.
  , inlineQueryResultParseMode :: Maybe Text -- ^ Mode for parsing entities in the photo caption. See formatting options <https:\/\/core.telegram.org\/bots\/api#formatting-options> for more details.
  , inlineQueryResultCaptionEntities :: Maybe [MessageEntity] -- ^ List of special entities that appear in the caption, which can be specified instead of @parse_mode@.
  , inlineQueryResultReplyMarkup :: Maybe InlineKeyboardMarkup -- ^ Inline keyboard attached to the message.
  , inlineQueryResultInputMessageContent :: Maybe InputMessageContent -- ^  Content of the message to be sent instead of the media.
  , inlineQueryResultDescription :: Maybe Text -- ^ Short description of the result.
  }
  deriving (Generic, Show)

instance ToJSON InlineQueryResultGeneric where toJSON = gtoJSON

instance FromJSON InlineQueryResultGeneric where parseJSON = gparseJSON

data InlineQueryResultGenericThumbnail = InlineQueryResultGenericThumbnail
  { inlineQueryResultGenericGeneric :: InlineQueryResultGeneric
  , inlineQueryResultGenericThumbnailUrl :: Maybe Text -- ^ URL of the thumbnail for the media.
  , inlineQueryResultGenericThumbnailMimeType :: Maybe Text -- ^ MIME type of the thumbnail, must be one of @image/jpeg@, @image/gif@, or @video/mp4@. Defaults to @image/jpeg@.
  , inlineQueryResultGenericThumbnailWidth :: Maybe Integer -- ^ Media width.
  , inlineQueryResultGenericThumbnailHeight :: Maybe Integer -- ^ Media height.
  }
  deriving (Generic, Show)

instance ToJSON InlineQueryResultGenericThumbnail where
  toJSON InlineQueryResultGenericThumbnail{..}
    = addJsonFields (toJSON inlineQueryResultGenericGeneric)
      [ "thumbnail_url" .= inlineQueryResultGenericThumbnailUrl
      , "thumbnail_mime_type" .= inlineQueryResultGenericThumbnailMimeType
      , "thumbnail_width" .= inlineQueryResultGenericThumbnailWidth
      , "thumbnail_height" .= inlineQueryResultGenericThumbnailHeight
      ]

instance FromJSON InlineQueryResultGenericThumbnail where
  parseJSON = withObject "InlineQueryResult" \o -> InlineQueryResultGenericThumbnail
    <$> parseJSON (Object o)
    <*> o .: "thumbnail_url"
    <*> o .: "thumbnail_mime_type"
    <*> o .: "thumbnail_width"
    <*> o .: "thumbnail_height"

-- | This object represents one result of an inline query
data InlineQueryResult
  = InlineQueryResultArticle
    { inlineQueryResultArticleGeneric :: InlineQueryResultGenericThumbnail
    , inlineQueryResultArticleUrl :: Maybe Text -- ^ URL of the result.
    , inlineQueryResultArticleHideUrl :: Maybe Bool -- ^ 'True' if you don't want the URL to be shown in the message.
    }
  | InlineQueryResultPhoto
    { inlineQueryResultPhotoGeneric :: InlineQueryResultGenericThumbnail
    , inlineQueryResultPhotoPhotoUrl :: Text -- ^ A valid URL of the photo. Photo must be in **JPEG** format. Photo size must not exceed 5MB.
    , inlineQueryResultPhotoPhotoWidth :: Maybe Integer -- ^ Width of the photo.
    , inlineQueryResultPhotoPhotoHeight :: Maybe Integer -- ^ Height of the photo.
    }
  | InlineQueryResultGif
    { inlineQueryResultGifGeneric :: InlineQueryResultGenericThumbnail
    , inlineQueryResultGifGifUrl :: Text -- ^ A valid URL for the GIF file. File size must not exceed 1MB.
    , inlineQueryResultGifGifWidth :: Maybe Integer -- ^ Width of the GIF.
    , inlineQueryResultGifGifHeight :: Maybe Integer -- ^ Height of the GIF.
    , inlineQueryResultGifGifDuration :: Maybe Integer -- ^ Duration of the GIF in seconds.
    }
  | InlineQueryResultMpeg4Gif
    { inlineQueryResultMpeg4GifGeneric :: InlineQueryResultGenericThumbnail
    , inlineQueryResultMpeg4GifMpeg4Url :: Text -- ^ A valid URL for the MPEG4 file. File size must not exceed 1MB.
    , inlineQueryResultMpeg4GifMpeg4Width :: Maybe Integer -- ^ Video width.
    , inlineQueryResultMpeg4GifMpeg4Height :: Maybe Integer -- ^ Video height.
    , inlineQueryResultMpeg4GifMpeg4Duration :: Maybe Integer -- ^ Video duration in seconds.
    }
  | InlineQueryResultVideo
    { inlineQueryResultVideoGeneric :: InlineQueryResultGenericThumbnail
    , inlineQueryResultVideoVideoUrl :: Text -- ^ A valid URL for the embedded video player or video file.
    , inlineQueryResultVideoMimeType :: Text -- ^ MIME type of the content of the video URL, @text/html@ or @video/mp4@.
    , inlineQueryResultVideoVideoWidth :: Maybe Integer -- ^ Video width.
    , inlineQueryResultVideoVideoHeight :: Maybe Integer -- ^ Video height.
    , inlineQueryResultVideoVideoDuration :: Maybe Integer -- ^ Video duration in seconds.
    }
  | InlineQueryResultAudio
    { inlineQueryResultAudioGeneric :: InlineQueryResultGeneric
    , inlineQueryResultAudioAudioUrl :: Text -- ^ A valid URL for the audio file.
    , inlineQueryResultAudioPerformer :: Maybe Text -- ^ Performer.
    , inlineQueryResultAudioAudioDuration :: Maybe Integer -- ^ Audio duration in seconds.
    }
  | InlineQueryResultVoice
    { inlineQueryResultVoiceGeneric :: InlineQueryResultGeneric
    , inlineQueryResultVoiceVoiceUrl :: Text -- ^ A valid URL for the voice recording.
    , inlineQueryResultVoiceVoiceDuration :: Maybe Integer -- ^ Recording duration in seconds.
    }
  | InlineQueryResultDocument
    { inlineQueryResultDocumentGeneric :: InlineQueryResultGenericThumbnail
    , inlineQueryResultDocumentDocumentUrl :: Text -- ^ A valid URL for the file.
    , inlineQueryResultDocumentMimeType :: Text -- ^ MIME type of the content of the file, either @application/pdf@ or @application/zip@.
    }
  | InlineQueryResultLocation
    { inlineQueryResultLocationGeneric :: InlineQueryResultGenericThumbnail
    , inlineQueryResultLocationLatitude :: Float -- ^ Location latitude in degrees.
    , inlineQueryResultLocationLongitude :: Float -- ^ Location longitude in degrees.
    , inlineQueryResultLocationHorizontalAccuracy :: Maybe Float -- ^ The radius of uncertainty for the location, measured in meters; 0-1500.
    , inlineQueryResultLocationLivePeriod :: Maybe Seconds -- ^ Period in seconds for which the location can be updated, should be between 60 and 86400.
    , inlineQueryResultLocationHeading :: Maybe Int -- ^ For live locations, a direction in which the user is moving, in degrees. Must be between 1 and 360 if specified.
    , inlineQueryResultLocationProximityAlertRadius :: Maybe Int -- ^ For live locations, a maximum distance for proximity alerts about approaching another chat member, in meters. Must be between 1 and 100000 if specified.
    }
  | InlineQueryResultVenue
    { inlineQueryResultVenueGeneric :: InlineQueryResultGenericThumbnail
    , inlineQueryResultVenueLatitude :: Float -- ^ Latitude of the venue location in degrees.
    , inlineQueryResultVenueLongitude :: Float -- ^ Longitude of the venue location in degrees.
    , inlineQueryResultVenueAddress :: Text -- ^ Address of the venue.
    , inlineQueryResultVenueFoursquareId :: Maybe Text -- ^ Foursquare identifier of the venue if known.
    , inlineQueryResultVenueFoursquareType :: Maybe Text -- ^ Foursquare type of the venue, if known. (For example, @arts_entertainment/default@, @arts_entertainment/aquarium@ or @food/icecream@.)
    , inlineQueryResultVenueGooglePlaceId :: Maybe Text -- ^ Google Places identifier of the venue.
    , inlineQueryResultVenueGooglePlaceType :: Maybe Text -- ^ Google Places type of the venue. (See supported types <https:\/\/developers.google.com\/places\/web-service\/supported_types>.)
    }
  | InlineQueryResultContact
    { inlineQueryResultContactGeneric :: InlineQueryResultGenericThumbnail
    , inlineQueryResultContactPhoneNumber :: Text -- ^ Contact's phone number.
    , inlineQueryResultContactFirstName :: Text -- ^ Contact's first name.
    , inlineQueryResultContactLastName :: Maybe Text -- ^ Contact's last name.
    , inlineQueryResultContactVcard :: Maybe Text -- ^ Additional data about the contact in the form of a vCard <https:\/\/en.wikipedia.org\/wiki\/VCard>, 0-2048 bytes.
    }
  | InlineQueryResultGame
    { inlineQueryResultGameGeneric :: InlineQueryResultGeneric
    , inlineQueryResultGameGameShortName :: Text -- ^ Short name of the game.
    }
  | InlineQueryResultCachedPhoto
    { inlineQueryResultCachedPhotoGeneric :: InlineQueryResultGeneric
    , inlineQueryResultCachedPhotoPhotoFileId :: FileId -- ^ A valid file identifier of the photo.
    }
  | InlineQueryResultCachedGif
    { inlineQueryResultCachedGifGeneric :: InlineQueryResultGeneric
    , iinlineQueryResultCachedGifGifFileId :: FileId -- ^ A valid file identifier for the GIF file.
    }
  | InlineQueryResultCachedMpeg4Gif
    { inlineQueryResultCachedMpeg4GifGeneric :: InlineQueryResultGeneric
    , inlineQueryResultCachedMpeg4GifMpeg4FileId :: FileId -- ^ A valid file identifier for the MPEG4 file.
    }
  | InlineQueryResultCachedSticker
    { inlineQueryResultCachedStickerGeneric :: InlineQueryResultGeneric
    , inlineQueryResultCachedStickerStickerFileId :: FileId -- ^ A valid file identifier of the sticker.
    }
  | InlineQueryResultCachedDocument
    { inlineQueryResultCachedDocumentGeneric :: InlineQueryResultGeneric
    , inlineQueryResultCachedDocumentDocumentFileId :: FileId -- ^ A valid file identifier for the file.
    }
  | InlineQueryResultCachedVideo
    { inlineQueryResultCachedVideoGeneric :: InlineQueryResultGeneric
    , inlineQueryResultCachedVideoVideoFileId :: FileId -- ^ A valid file identifier for the video file.
    }
  | InlineQueryResultCachedVoice
    { inlineQueryResultCachedVoiceGeneric :: InlineQueryResultGeneric
    , inlineQueryResultCachedVoiceVoiceFileId :: FileId -- ^ A valid file identifier for the voice message.
    }
  | InlineQueryResultCachedAudio
    { inlineQueryResultCachedAudioGeneric :: InlineQueryResultGeneric
    , inlineQueryResultCachedAudioAudioFileId :: FileId -- ^ A valid file identifier for the audio file.
    }
  deriving (Generic, Show)

instance ToJSON InlineQueryResult where
  toJSON = \case
    InlineQueryResultArticle g url hideUrl ->
      addJsonFields (toJSON g)
        (addType "article"
        [ "url" .= url
        , "hide_url" .= hideUrl
        ])
    InlineQueryResultPhoto g photoUrl photoWidth photoHeight ->
      addJsonFields (toJSON g)
        (addType "photo"
        [ "photo_url" .= photoUrl
        , "photo_width" .= photoWidth
        , "photo_height" .= photoHeight
        ])
    InlineQueryResultGif g gifUrl gifWidth gifHeight gifDuration ->
      addJsonFields (toJSON g)
        (addType "gif"
        [ "gif_url" .= gifUrl
        , "gif_width" .= gifWidth
        , "gif_height" .= gifHeight
        , "gif_duration" .= gifDuration
        ])
    InlineQueryResultMpeg4Gif g mpeg4Url mpeg4Width mpeg4Height mpeg4Duration ->
      addJsonFields (toJSON g)
        (addType "mpeg4_gif"
        [ "mpeg4_url" .= mpeg4Url
        , "mpeg4_width" .= mpeg4Width
        , "mpeg4_height" .= mpeg4Height
        , "mpeg4_duration" .= mpeg4Duration
        ])
    InlineQueryResultVideo g videoUrl mimeType videoWidth videoHeight videoDuration ->
      addJsonFields (toJSON g)
        (addType "video"
        [ "video_url" .= videoUrl
        , "mime_type" .= mimeType
        , "video_width" .= videoWidth
        , "video_height" .= videoHeight
        , "video_duration" .= videoDuration
        ])
    InlineQueryResultAudio g audioUrl performer audioDuration ->
      addJsonFields (toJSON g)
        (addType "audio"
        [ "audio_url" .= audioUrl
        , "performer" .= performer
        , "audio_duration" .= audioDuration
        ])
    InlineQueryResultVoice g voiceUrl voiceDuration ->
      addJsonFields (toJSON g)
        (addType "voice"
        [ "voice_url" .= voiceUrl
        , "voice_duration" .= voiceDuration
        ])
    InlineQueryResultDocument g documentUrl mimeType ->
      addJsonFields (toJSON g)
        (addType "document"
        [ "document_url" .= documentUrl
        , "mime_type" .= mimeType
        ])
    InlineQueryResultLocation g latitude longitude horizontalAccuracy livePeriod heading proximityAlertRadius ->
      addJsonFields (toJSON g)
        (addType "location"
        [ "latitude" .= latitude
        , "longitude" .= longitude
        , "horizontal_accuracy" .= horizontalAccuracy
        , "live_period" .= livePeriod
        , "heading" .= heading
        , "proximity_alert_radius" .= proximityAlertRadius
        ])
    InlineQueryResultVenue g latitude longitude address foursquareId foursquareType googlePlaceId googlePlaceType ->
      addJsonFields (toJSON g)
        (addType "venue"
        [ "latitude" .= latitude
        , "longitude" .= longitude
        , "address" .= address
        , "foursquare_id" .= foursquareId
        , "foursquare_type" .= foursquareType
        , "google_place_id" .= googlePlaceId
        , "google_place_type" .= googlePlaceType
        ])
    InlineQueryResultContact g phoneNumber firstName lastName vcard ->
      addJsonFields (toJSON g)
        (addType "contact"
        [ "phone_number" .= phoneNumber
        , "first_name" .= firstName
        , "last_name" .= lastName
        , "vcard" .= vcard
        ])
    InlineQueryResultGame g gameShortName ->
      addJsonFields (toJSON g)
        (addType "game"
        [ "game_short_name" .= gameShortName
        ])
    InlineQueryResultCachedPhoto g photoFileId ->
      addJsonFields (toJSON g)
        (addType "photo"
        [ "photo_file_id" .= photoFileId
        ])
    InlineQueryResultCachedGif g gifFileId ->
      addJsonFields (toJSON g)
        (addType "gif"
        [ "gif_file_id" .= gifFileId
        ])
    InlineQueryResultCachedMpeg4Gif g mpeg4FileId ->
      addJsonFields (toJSON g)
        (addType "mpeg4_gif"
        [ "mpeg4_file_id" .= mpeg4FileId
        ])
    InlineQueryResultCachedSticker g stickerFileId ->
      addJsonFields (toJSON g)
        (addType "sticker"
        [ "sticker_file_id" .= stickerFileId
        ])
    InlineQueryResultCachedDocument g documentFileId ->
      addJsonFields (toJSON g)
        (addType "document"
        [ "document_file_id" .= documentFileId
        ])
    InlineQueryResultCachedVideo g videoFileId ->
      addJsonFields (toJSON g)
        (addType "video"
        [ "video_file_id" .= videoFileId
        ])
    InlineQueryResultCachedVoice g voiceFileId ->
      addJsonFields (toJSON g)
        (addType "voice"
        [ "voice_file_id" .= voiceFileId
        ])
    InlineQueryResultCachedAudio g audioFileId ->
      addJsonFields (toJSON g)
        (addType "audio"
        [ "audio_file_id" .= audioFileId
        ])

instance FromJSON InlineQueryResult where
  parseJSON = withObject "InlineQueryResult" \o ->
    (o .: "type" :: Parser Text) >>= \case
    "article" -> InlineQueryResultArticle
      <$> parseJSON (Object o)
      <*> o .: "url"
      <*> o .: "hide_url"
    "photo" -> parseFileId o "photo_file_id" >>= \case
      Nothing -> InlineQueryResultPhoto
        <$> parseJSON (Object o) -- generic thumbnail
        <*> o .: "photo_url"
        <*> o .: "photo_width"
        <*> o .: "photo_height"
      Just fileId -> InlineQueryResultCachedPhoto <$> parseJSON (Object o) <*> pure fileId
    "gif" -> parseFileId o "gif_file_id" >>= \case
      Nothing -> InlineQueryResultGif
        <$> parseJSON (Object o) -- generic thumbnail
        <*> o .: "gif_url"
        <*> o .: "gif_width"
        <*> o .: "gif_height"
        <*> o .: "gif_duration"
      Just fileId -> InlineQueryResultCachedGif <$> parseJSON (Object o) <*> pure fileId
    "mpeg4_gif" -> parseFileId o "mpeg4_file_id" >>= \case
      Nothing -> InlineQueryResultMpeg4Gif
        <$> parseJSON (Object o) -- generic thumbnail
        <*> o .: "mpeg4_url"
        <*> o .: "mpeg4_width"
        <*> o .: "mpeg4_height"
        <*> o .: "mpeg4_duration"
      Just fileId -> InlineQueryResultCachedMpeg4Gif
        <$> parseJSON (Object o)
        <*> pure fileId
    "video" -> parseFileId o "video_file_id" >>= \case
      Nothing -> InlineQueryResultVideo
        <$> parseJSON (Object o)
        <*> o .: "video_url"
        <*> o .: "mime_type"
        <*> o .: "video_width"
        <*> o .: "video_height"
        <*> o .: "video_duration"
      Just fileId -> InlineQueryResultCachedVideo
        <$> parseJSON (Object o)
        <*> pure fileId
    "audio" -> parseFileId o "audio_file_id" >>= \case
      Nothing -> InlineQueryResultAudio
        <$> parseJSON (Object o)
        <*> o .: "audio_url"
        <*> o .: "performer"
        <*> o .: "duration"
      Just fileId -> InlineQueryResultCachedAudio <$> parseJSON (Object o) <*> pure fileId
    "voice" -> parseFileId o "voice_file_id" >>= \case
      Nothing -> InlineQueryResultVoice
        <$> parseJSON (Object o)
        <*> o .: "voice_url"
        <*> o .: "voice_duration"
      Just fileId -> InlineQueryResultCachedVoice <$> parseJSON (Object o) <*> pure fileId
    "document" -> parseFileId o "document_file_id" >>= \case
      Nothing -> InlineQueryResultDocument
        <$> parseJSON (Object o)
        <*> o .: "document_url"
        <*> o .: "mime_type"
      Just fileId -> InlineQueryResultCachedDocument <$> parseJSON (Object o) <*> pure fileId
    "location" -> InlineQueryResultLocation
      <$> parseJSON (Object o)
      <*> o .: "latitude"
      <*> o .: "longitude"
      <*> o .: "horizontal_accuracy"
      <*> o .: "live_period"
      <*> o .: "heading"
      <*> o .: "proximity_alert_radius"
    "venue" -> InlineQueryResultVenue
      <$> parseJSON (Object o)
      <*> o .: "latitude"
      <*> o .: "longitude"
      <*> o .: "address"
      <*> o .: "foursquare_id"
      <*> o .: "foursquare_type"
      <*> o .: "google_place_id"
      <*> o .: "google_place_type"
    "contact" -> InlineQueryResultContact
      <$> parseJSON (Object o)
      <*> o .: "phone_number"
      <*> o .: "first_name"
      <*> o .: "last_name"
      <*> o .: "vcard"
    "game" -> InlineQueryResultGame
      <$> parseJSON (Object o)
      <*> o .: "game_short_name"
    t -> fail $ Text.unpack ("Unknown type: " <> t)
    where
      parseFileId o fileField = o .:? fileField :: Parser (Maybe FileId)
    
defInlineQueryResultArticle :: InlineQueryResultGenericThumbnail -> InlineQueryResult
defInlineQueryResultArticle g = InlineQueryResultArticle g Nothing Nothing

defInlineQueryResultPhotoUrl :: InlineQueryResultGenericThumbnail -> Text -> InlineQueryResult
defInlineQueryResultPhotoUrl g photoUrl = InlineQueryResultPhoto g photoUrl Nothing Nothing

defInlineQueryResultGif :: InlineQueryResultGenericThumbnail -> Text -> InlineQueryResult
defInlineQueryResultGif g gifUrl = InlineQueryResultGif g gifUrl Nothing Nothing Nothing

defInlineQueryResultMpeg4Gif :: InlineQueryResultGenericThumbnail -> Text -> InlineQueryResult
defInlineQueryResultMpeg4Gif g mpeg4Url = InlineQueryResultMpeg4Gif g mpeg4Url Nothing Nothing Nothing

defInlineQueryResultVideo :: InlineQueryResultGenericThumbnail -> Text -> Text -> InlineQueryResult
defInlineQueryResultVideo g videoUrl mimeType
  = InlineQueryResultVideo g videoUrl mimeType Nothing Nothing Nothing

defInlineQueryResultAudio :: InlineQueryResultGeneric -> Text -> InlineQueryResult
defInlineQueryResultAudio g audioUrl = InlineQueryResultAudio g audioUrl Nothing Nothing

defInlineQueryResultVoice :: InlineQueryResultGeneric -> Text -> InlineQueryResult
defInlineQueryResultVoice g voiceUrl = InlineQueryResultVoice g voiceUrl Nothing

defInlineQueryResultDocument :: InlineQueryResultGenericThumbnail -> Text -> Text -> InlineQueryResult
defInlineQueryResultDocument = InlineQueryResultDocument

defInlineQueryResultLocation :: InlineQueryResultGenericThumbnail -> Float -> Float -> InlineQueryResult
defInlineQueryResultLocation g lat lon
  = InlineQueryResultLocation g lat lon Nothing Nothing Nothing Nothing

defInlineQueryResultVenue :: InlineQueryResultGenericThumbnail -> Float -> Float -> Text -> InlineQueryResult
defInlineQueryResultVenue g lat lon address
  = InlineQueryResultVenue g lat lon address Nothing Nothing Nothing Nothing

defInlineQueryResultContact :: InlineQueryResultGenericThumbnail -> Text -> Text -> InlineQueryResult
defInlineQueryResultContact g phoneNumber firstName
  = InlineQueryResultContact g phoneNumber firstName Nothing Nothing

-- | This object represents a button to be shown above inline query results. You must use exactly one of the optional fields.
data InlineQueryResultsButton = InlineQueryResultsButton
  { inlineQueryResultsButtonText :: Text 
  , inlineQueryResultsButtonWebApp :: Maybe WebAppInfo
  , inlineQueryResultsButtonStartParameter :: Maybe Text -- ^ [Deep-linking](https://core.telegram.org/bots/features#deep-linking) parameter for the /start message sent to the bot when a user presses the button. 1-64 characters, only @A-Z@, @a-z@, @0-9@, @_@ and @-@ are allowed.
-- 
-- Example: An inline bot that sends YouTube videos can ask the user to connect the bot to their YouTube account to adapt search results accordingly. To do this, it displays a 'Connect your YouTube account' button above the results, or even before showing any. The user presses the button, switches to a private chat with the bot and, in doing so, passes a start parameter that instructs the bot to return an OAuth link. Once done, the bot can offer a [switch_inline](https://core.telegram.org/bots/api#inlinekeyboardmarkup) button so that the user can easily return to the chat where they wanted to use the bot's inline capabilities.
  }
  deriving Generic

instance ToJSON InlineQueryResultsButton where toJSON = gtoJSON

instance FromJSON InlineQueryResultsButton where parseJSON = gparseJSON

foldMap makeDefault
  [ ''InlineQueryResultGeneric
  , ''InlineQueryResultGenericThumbnail
  ]