{-# LANGUAGE OverloadedStrings #-}
module Main where
import Data.Maybe
import Data.Text (Text)
import qualified Data.Text as Text
import Telegram.Bot.API
import Telegram.Bot.API.InlineMode.InlineQueryResult
import Telegram.Bot.API.InlineMode.InputMessageContent (defaultInputTextMessageContent)
import Telegram.Bot.Simple
import Telegram.Bot.Simple.UpdateParser (updateMessageSticker,
updateMessageText)
import Network.Wai.Handler.Warp (Port,
defaultSettings,
setPort)
import Network.Wai.Handler.WarpTLS (OnInsecure (AllowInsecure),
TLSSettings (onInsecure),
tlsSettings)
type Model = ()
data Action
= InlineEcho InlineQueryId Text
| StickerEcho InputFile ChatId
| Echo Text
echoBot :: BotApp Model Action
echoBot = BotApp
{ botInitialModel = ()
, botAction = updateToAction
, botHandler = handleAction
, botJobs = []
}
updateToAction :: Update -> Model -> Maybe Action
updateToAction update _
| isJust $ updateInlineQuery update = do
query <- updateInlineQuery update
let queryId = inlineQueryId query
let msg = inlineQueryQuery query
Just $ InlineEcho queryId msg
| isJust $ updateMessageSticker update = do
fileId <- stickerFileId <$> updateMessageSticker update
chatOfUser <- updateChatId update
pure $ StickerEcho (InputFileId fileId) chatOfUser
| otherwise = case updateMessageText update of
Just text -> Just (Echo text)
Nothing -> Nothing
handleAction :: Action -> Model -> Eff Action Model
handleAction action model = case action of
InlineEcho queryId msg -> model <# do
let result = (defInlineQueryResultGeneric (InlineQueryResultId msg))
{ inlineQueryResultTitle = Just msg
, inlineQueryResultInputMessageContent = Just (defaultInputTextMessageContent msg)
}
thumbnail = defInlineQueryResultGenericThumbnail result
article = defInlineQueryResultArticle thumbnail
answerInlineQueryRequest = defAnswerInlineQuery queryId [article]
_ <- runTG answerInlineQueryRequest
return ()
StickerEcho file chat -> model <# do
_ <- runTG
(defSendSticker (SomeChatId chat) file)
return ()
Echo msg -> model <# do
pure msg -- or replyText msg
run :: Token -> FilePath -> FilePath -> Port -> String -> IO ()
run token certPath keyPath port ip = do
env <- defaultTelegramClientEnv token
res <- startBotWebhook bot config env
print res
where
bot = conversationBot updateChatId echoBot
tlsOpts = (tlsSettings certPath keyPath) {onInsecure = AllowInsecure}
warpOpts = setPort port defaultSettings
certFile = Just $ InputFile certPath "application/x-pem-file"
url = "https://" ++ ip ++ ":" ++ show port
config = WebhookConfig
{ webhookConfigTlsSettings = tlsOpts,
webhookConfigTlsWarpSettings = warpOpts,
webhookConfigSetWebhookRequest = requestData
}
requestData = (defSetWebhook url)
{ setWebhookCertificate = certFile,
setWebhookAllowedUpdates = Just ["message"]
}
main :: IO ()
main = do
putStrLn "Please, enter Telegram bot's API token:"
token <- Token . Text.pack <$> getLine
putStrLn "Please, enter a path to certificate:"
cert <- getLine
putStrLn "Please, enter a path to key:"
key <- getLine
putStrLn "Please, enter port(80, 88, 443, 8443):"
port <- read <$> getLine
putStrLn "Please, enter ip:"
ip <- getLine
run token cert key port ip