{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
module Telegram.Bot.API.Methods.SendAnimation where

import Control.Monad.IO.Class (liftIO)
import Data.Aeson (ToJSON (..))
import Data.Aeson.Text (encodeToLazyText)
import Data.Bool
import Data.Maybe (catMaybes)
import Data.Functor ((<&>))
import Data.Proxy
import Data.Text
import GHC.Generics (Generic)
import Servant.API
import Servant.Multipart.API
import Servant.Multipart.Client
import Servant.Client hiding (Response)

import qualified Data.Text.Lazy as TL

import Telegram.Bot.API.Internal.Utils
import Telegram.Bot.API.MakingRequests
import Telegram.Bot.API.Types
import Telegram.Bot.API.Types.ParseMode
import Telegram.Bot.API.Internal.TH

-- ** 'sendAnimation'

-- | Request parameters for 'sendAnimation'.
data SendAnimationRequest = SendAnimationRequest
  { SendAnimationRequest -> Maybe BusinessConnectionId
sendAnimationBusinessConnectionId :: Maybe BusinessConnectionId -- ^ Unique identifier of the business connection on behalf of which the message will be sent.
  , SendAnimationRequest -> SomeChatId
sendAnimationChatId :: SomeChatId -- ^ Unique identifier for the target chat or username of the target channel (in the format @channelusername)
  , SendAnimationRequest -> Maybe MessageThreadId
sendAnimationMessageThreadId :: Maybe MessageThreadId -- ^ Unique identifier for the target message thread (topic) of the forum; for forum supergroups only.
  , SendAnimationRequest -> InputFile
sendAnimationAnimation :: InputFile -- ^ Animation to send. Pass a file_id as String to send an animation that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get an animation from the Internet, or upload a new animation using multipart/form-data. More info on Sending Files »
  , SendAnimationRequest -> Maybe Int
sendAnimationDuration :: Maybe Int -- ^ Duration of sent animation in seconds
  , SendAnimationRequest -> Maybe Int
sendAnimationWidth :: Maybe Int -- ^ Animation width
  , SendAnimationRequest -> Maybe Int
sendAnimationHeight :: Maybe Int -- ^ Animation height
  , SendAnimationRequest -> Maybe InputFile
sendAnimationThumbnail :: Maybe InputFile -- ^ Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new file, so you can pass “attach://<file_attach_name>” if the thumbnail was uploaded using multipart/form-data under <file_attach_name>. More info on Sending Files »
  , SendAnimationRequest -> Maybe Text
sendAnimationCaption :: Maybe Text -- ^ Animation caption (may also be used when resending animation by file_id), 0-1024 characters after entities parsing
  , SendAnimationRequest -> Maybe ParseMode
sendAnimationParseMode :: Maybe ParseMode  -- ^ Send 'MarkdownV2', 'HTML' or 'Markdown' (legacy), if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message.
  , SendAnimationRequest -> Maybe [MessageEntity]
sendAnimationCaptionEntities :: Maybe [MessageEntity] -- ^ A JSON-serialized list of special entities that appear in the caption, which can be specified instead of @parse_mode@.
  , SendAnimationRequest -> Maybe Bool
sendAnimationShowCaptionAboveMedia :: Maybe Bool -- ^ Pass 'True', if the caption must be shown above the message media.
  , SendAnimationRequest -> Maybe Bool
sendAnimationHasSpoiler :: Maybe Bool -- ^ Pass 'True' if the animation needs to be covered with a spoiler animation.
  , SendAnimationRequest -> Maybe Bool
sendAnimationDisableNotification :: Maybe Bool -- ^ Sends the message silently. Users will receive a notification with no sound.
  , SendAnimationRequest -> Maybe Bool
sendAnimationProtectContent :: Maybe Bool -- ^ Protects the contents of the sent message from forwarding and saving.
  , SendAnimationRequest -> Maybe Text
sendAnimationMessageEffectId :: Maybe Text -- ^ Unique identifier of the message effect to be added to the message; for private chats only.
  , SendAnimationRequest -> Maybe MessageId
sendAnimationReplyToMessageId :: Maybe MessageId -- ^ If the message is a reply, ID of the original message.
  , SendAnimationRequest -> Maybe ReplyParameters
sendAnimationReplyParameters :: Maybe ReplyParameters -- ^ Description of the message to reply to.
  , SendAnimationRequest -> Maybe InlineKeyboardMarkup
sendAnimationReplyMarkup :: Maybe InlineKeyboardMarkup -- ^ Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user.
  }
  deriving (forall x. SendAnimationRequest -> Rep SendAnimationRequest x)
-> (forall x. Rep SendAnimationRequest x -> SendAnimationRequest)
-> Generic SendAnimationRequest
forall x. Rep SendAnimationRequest x -> SendAnimationRequest
forall x. SendAnimationRequest -> Rep SendAnimationRequest x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. SendAnimationRequest -> Rep SendAnimationRequest x
from :: forall x. SendAnimationRequest -> Rep SendAnimationRequest x
$cto :: forall x. Rep SendAnimationRequest x -> SendAnimationRequest
to :: forall x. Rep SendAnimationRequest x -> SendAnimationRequest
Generic

instance ToJSON SendAnimationRequest where toJSON :: SendAnimationRequest -> Value
toJSON = SendAnimationRequest -> Value
forall a (d :: Meta) (f :: * -> *).
(Generic a, GToJSON Zero (Rep a), Rep a ~ D1 d f, Datatype d) =>
a -> Value
gtoJSON

instance ToMultipart Tmp SendAnimationRequest where
  toMultipart :: SendAnimationRequest -> MultipartData Tmp
toMultipart SendAnimationRequest{Maybe Bool
Maybe Int
Maybe [MessageEntity]
Maybe Text
Maybe BusinessConnectionId
Maybe MessageThreadId
Maybe MessageId
Maybe ParseMode
Maybe InlineKeyboardMarkup
Maybe ReplyParameters
Maybe InputFile
SomeChatId
InputFile
sendAnimationBusinessConnectionId :: SendAnimationRequest -> Maybe BusinessConnectionId
sendAnimationChatId :: SendAnimationRequest -> SomeChatId
sendAnimationMessageThreadId :: SendAnimationRequest -> Maybe MessageThreadId
sendAnimationAnimation :: SendAnimationRequest -> InputFile
sendAnimationDuration :: SendAnimationRequest -> Maybe Int
sendAnimationWidth :: SendAnimationRequest -> Maybe Int
sendAnimationHeight :: SendAnimationRequest -> Maybe Int
sendAnimationThumbnail :: SendAnimationRequest -> Maybe InputFile
sendAnimationCaption :: SendAnimationRequest -> Maybe Text
sendAnimationParseMode :: SendAnimationRequest -> Maybe ParseMode
sendAnimationCaptionEntities :: SendAnimationRequest -> Maybe [MessageEntity]
sendAnimationShowCaptionAboveMedia :: SendAnimationRequest -> Maybe Bool
sendAnimationHasSpoiler :: SendAnimationRequest -> Maybe Bool
sendAnimationDisableNotification :: SendAnimationRequest -> Maybe Bool
sendAnimationProtectContent :: SendAnimationRequest -> Maybe Bool
sendAnimationMessageEffectId :: SendAnimationRequest -> Maybe Text
sendAnimationReplyToMessageId :: SendAnimationRequest -> Maybe MessageId
sendAnimationReplyParameters :: SendAnimationRequest -> Maybe ReplyParameters
sendAnimationReplyMarkup :: SendAnimationRequest -> Maybe InlineKeyboardMarkup
sendAnimationBusinessConnectionId :: Maybe BusinessConnectionId
sendAnimationChatId :: SomeChatId
sendAnimationMessageThreadId :: Maybe MessageThreadId
sendAnimationAnimation :: InputFile
sendAnimationDuration :: Maybe Int
sendAnimationWidth :: Maybe Int
sendAnimationHeight :: Maybe Int
sendAnimationThumbnail :: Maybe InputFile
sendAnimationCaption :: Maybe Text
sendAnimationParseMode :: Maybe ParseMode
sendAnimationCaptionEntities :: Maybe [MessageEntity]
sendAnimationShowCaptionAboveMedia :: Maybe Bool
sendAnimationHasSpoiler :: Maybe Bool
sendAnimationDisableNotification :: Maybe Bool
sendAnimationProtectContent :: Maybe Bool
sendAnimationMessageEffectId :: Maybe Text
sendAnimationReplyToMessageId :: Maybe MessageId
sendAnimationReplyParameters :: Maybe ReplyParameters
sendAnimationReplyMarkup :: Maybe InlineKeyboardMarkup
..} =
    (MultipartData Tmp -> MultipartData Tmp)
-> (InputFile -> MultipartData Tmp -> MultipartData Tmp)
-> Maybe InputFile
-> MultipartData Tmp
-> MultipartData Tmp
forall b a. b -> (a -> b) -> Maybe a -> b
maybe MultipartData Tmp -> MultipartData Tmp
forall a. a -> a
id (Text -> InputFile -> MultipartData Tmp -> MultipartData Tmp
makeFile Text
"thumbnail") Maybe InputFile
sendAnimationThumbnail (MultipartData Tmp -> MultipartData Tmp)
-> MultipartData Tmp -> MultipartData Tmp
forall a b. (a -> b) -> a -> b
$
    Text -> InputFile -> MultipartData Tmp -> MultipartData Tmp
makeFile Text
"animation" InputFile
sendAnimationAnimation (MultipartData Tmp -> MultipartData Tmp)
-> MultipartData Tmp -> MultipartData Tmp
forall a b. (a -> b) -> a -> b
$
    [Input] -> [FileData Tmp] -> MultipartData Tmp
forall tag. [Input] -> [FileData tag] -> MultipartData tag
MultipartData [Input]
fields [] where
    fields :: [Input]
fields =
      [ Text -> Text -> Input
Input Text
"chat_id" (Text -> Input) -> Text -> Input
forall a b. (a -> b) -> a -> b
$ case SomeChatId
sendAnimationChatId of
          SomeChatId (ChatId Integer
chat_id) -> Integer -> Text
forall a. Show a => a -> Text
showText Integer
chat_id
          SomeChatUsername Text
txt -> Text
txt
      ] [Input] -> [Input] -> [Input]
forall a. Semigroup a => a -> a -> a
<> [Maybe Input] -> [Input]
forall a. [Maybe a] -> [a]
catMaybes
      [ Maybe MessageThreadId
sendAnimationMessageThreadId Maybe MessageThreadId -> (MessageThreadId -> Input) -> Maybe Input
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&>
        \MessageThreadId
t -> Text -> Text -> Input
Input Text
"message_thread_id" (MessageThreadId -> Text
forall a. Show a => a -> Text
showText MessageThreadId
t)
      , Maybe Text
sendAnimationCaption Maybe Text -> (Text -> Input) -> Maybe Input
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&>
        \Text
t -> Text -> Text -> Input
Input Text
"caption" Text
t
      , Maybe ParseMode
sendAnimationParseMode Maybe ParseMode -> (ParseMode -> Input) -> Maybe Input
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&>
        \ParseMode
t -> Text -> Text -> Input
Input Text
"parse_mode" (Text -> Text
TL.toStrict (Text -> Text) -> (Text -> Text) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HasCallStack => Text -> Text -> Text -> Text
Text -> Text -> Text -> Text
TL.replace Text
"\"" Text
"" (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ ParseMode -> Text
forall a. ToJSON a => a -> Text
encodeToLazyText ParseMode
t)
      , Maybe [MessageEntity]
sendAnimationCaptionEntities Maybe [MessageEntity] -> ([MessageEntity] -> Input) -> Maybe Input
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&>
        \[MessageEntity]
t -> Text -> Text -> Input
Input Text
"caption_entities" (Text -> Text
TL.toStrict (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ [MessageEntity] -> Text
forall a. ToJSON a => a -> Text
encodeToLazyText [MessageEntity]
t)
      , Maybe Bool
sendAnimationHasSpoiler Maybe Bool -> (Bool -> Input) -> Maybe Input
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&>
        \Bool
t -> Text -> Text -> Input
Input Text
"has_spoiler" (Text -> Text -> Bool -> Text
forall a. a -> a -> Bool -> a
bool Text
"false" Text
"true" Bool
t)
      , Maybe Int
sendAnimationDuration Maybe Int -> (Int -> Input) -> Maybe Input
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&>
        \Int
t -> Text -> Text -> Input
Input Text
"duration" (Text -> Text
TL.toStrict (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Int -> Text
forall a. ToJSON a => a -> Text
encodeToLazyText Int
t)
      , Maybe Int
sendAnimationWidth Maybe Int -> (Int -> Input) -> Maybe Input
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&>
        \Int
t -> Text -> Text -> Input
Input Text
"width" (Text -> Text
TL.toStrict (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Int -> Text
forall a. ToJSON a => a -> Text
encodeToLazyText Int
t)
      , Maybe Int
sendAnimationHeight Maybe Int -> (Int -> Input) -> Maybe Input
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&>
        \Int
t -> Text -> Text -> Input
Input Text
"height" (Text -> Text
TL.toStrict (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Int -> Text
forall a. ToJSON a => a -> Text
encodeToLazyText Int
t)
      , Maybe Bool
sendAnimationDisableNotification Maybe Bool -> (Bool -> Input) -> Maybe Input
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&>
        \Bool
t -> Text -> Text -> Input
Input Text
"disable_notification" (Text -> Text -> Bool -> Text
forall a. a -> a -> Bool -> a
bool Text
"false" Text
"true" Bool
t)
      , Maybe Bool
sendAnimationProtectContent Maybe Bool -> (Bool -> Input) -> Maybe Input
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&>
        \Bool
t -> Text -> Text -> Input
Input Text
"protect_content" (Text -> Text -> Bool -> Text
forall a. a -> a -> Bool -> a
bool Text
"false" Text
"true" Bool
t)
      , Maybe MessageId
sendAnimationReplyToMessageId Maybe MessageId -> (MessageId -> Input) -> Maybe Input
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&>
        \MessageId
t -> Text -> Text -> Input
Input Text
"reply_to_message_id" (Text -> Text
TL.toStrict (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ MessageId -> Text
forall a. ToJSON a => a -> Text
encodeToLazyText MessageId
t)
      , Maybe ReplyParameters
sendAnimationReplyParameters Maybe ReplyParameters -> (ReplyParameters -> Input) -> Maybe Input
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&>
        \ReplyParameters
t -> Text -> Text -> Input
Input Text
"reply_parameters" (Text -> Text
TL.toStrict (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ ReplyParameters -> Text
forall a. ToJSON a => a -> Text
encodeToLazyText ReplyParameters
t)
      , Maybe InlineKeyboardMarkup
sendAnimationReplyMarkup Maybe InlineKeyboardMarkup
-> (InlineKeyboardMarkup -> Input) -> Maybe Input
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&>
        \InlineKeyboardMarkup
t -> Text -> Text -> Input
Input Text
"reply_markup" (Text -> Text
TL.toStrict (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ InlineKeyboardMarkup -> Text
forall a. ToJSON a => a -> Text
encodeToLazyText InlineKeyboardMarkup
t)
      ]

type SendAnimationContent
  = "sendAnimation"
  :> MultipartForm Tmp SendAnimationRequest
  :> Post '[JSON] (Response Message)

type SendAnimationLink
  = "sendAnimation"
  :> ReqBody '[JSON] SendAnimationRequest
  :> Post '[JSON] (Response Message)


-- | Use this method to send animation files
--   (GIF or H.264/MPEG-4 AVC video without sound).
--   On success, the sent Message is returned. Bots
--   can currently send animation files of up to 50
--   MB in size, this limit may be changed in the future.
sendAnimation :: SendAnimationRequest ->  ClientM (Response Message)
sendAnimation :: SendAnimationRequest -> ClientM (Response Message)
sendAnimation SendAnimationRequest
r = case (SendAnimationRequest -> InputFile
sendAnimationAnimation SendAnimationRequest
r, SendAnimationRequest -> Maybe InputFile
sendAnimationThumbnail SendAnimationRequest
r) of
  (InputFile{}, Maybe InputFile
_) -> do
    ByteString
boundary <- IO ByteString -> ClientM ByteString
forall a. IO a -> ClientM a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO ByteString
genBoundary
    Proxy SendAnimationContent -> Client ClientM SendAnimationContent
forall api.
HasClient ClientM api =>
Proxy api -> Client ClientM api
client (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @SendAnimationContent) (ByteString
boundary, SendAnimationRequest
r)
  (InputFile
_, Just InputFile{}) -> do
    ByteString
boundary <- IO ByteString -> ClientM ByteString
forall a. IO a -> ClientM a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO ByteString
genBoundary
    Proxy SendAnimationContent -> Client ClientM SendAnimationContent
forall api.
HasClient ClientM api =>
Proxy api -> Client ClientM api
client (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @SendAnimationContent) (ByteString
boundary, SendAnimationRequest
r)
  (InputFile, Maybe InputFile)
_ ->  Proxy SendAnimationLink -> Client ClientM SendAnimationLink
forall api.
HasClient ClientM api =>
Proxy api -> Client ClientM api
client (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @SendAnimationLink) SendAnimationRequest
r

makeDefault ''SendAnimationRequest