telegram-bot-simple-0.10: src/Telegram/Bot/Simple/BotApp.hs
{-# LANGUAGE RecordWildCards #-}
module Telegram.Bot.Simple.BotApp (
BotApp(..),
BotJob(..),
WebhookConfig(..),
startBot,
startBot_,
startBotAsync,
startBotAsync_,
startBotWebhook,
startBotWebhook_,
getEnvToken,
) where
import Control.Concurrent (forkIO)
import Control.Monad (void)
import Data.String (fromString)
import Servant.Client
import System.Environment (getEnv)
import Control.Exception (finally)
import Data.Either (isLeft)
import Network.Wai.Handler.Warp
import Network.Wai.Handler.WarpTLS
import qualified Telegram.Bot.API as Telegram
import Telegram.Bot.API.Webhook (SetWebhookRequest,
deleteWebhook,
setUpWebhook)
import Telegram.Bot.Simple.BotApp.Internal
import Telegram.Bot.Simple.Webhook (webhookApp)
-- | Start bot with asynchronous polling.
-- The result is a function that allows you to send actions
-- directly to the bot.
startBotAsync :: BotApp model action -> ClientEnv -> IO (action -> IO ())
startBotAsync bot env = do
botEnv <- startBotEnv bot env
fork_ $ startBotPolling bot botEnv
return (issueAction botEnv Nothing . Just)
where
fork_ = void . forkIO . void . flip runClientM env
-- | Like 'startBotAsync', but ignores result.
startBotAsync_ :: BotApp model action -> ClientEnv -> IO ()
startBotAsync_ bot env = void (startBotAsync bot env)
-- | Start bot with update polling in the main thread.
startBot :: BotApp model action -> ClientEnv -> IO (Either ClientError ())
startBot bot env = do
botEnv <- startBotEnv bot env
runClientM (startBotPolling bot botEnv) env
-- | Like 'startBot', but ignores result.
startBot_ :: BotApp model action -> ClientEnv -> IO ()
startBot_ bot = void . startBot bot
data WebhookConfig = WebhookConfig
{ webhookConfigTlsSettings :: TLSSettings,
webhookConfigTlsWarpSettings :: Settings,
webhookConfigSetWebhookRequest :: SetWebhookRequest
}
-- | Start bot with webhook on update in the main thread.
-- Port must be one of 443, 80, 88, 8443
-- certPath must be provided if using self signed certificate.
startBotWebhook :: BotApp model action -> WebhookConfig -> ClientEnv -> IO (Either ClientError ())
startBotWebhook bot (WebhookConfig{..}) env = do
botEnv <- startBotEnv bot env
res <- setUpWebhook webhookConfigSetWebhookRequest env
if isLeft res
then return res
else Right <$> runTLS webhookConfigTlsSettings webhookConfigTlsWarpSettings (webhookApp bot botEnv)
`finally`
deleteWebhook env
-- | Like 'startBotWebhook', but ignores result.
startBotWebhook_ :: BotApp model action -> WebhookConfig -> ClientEnv -> IO ()
startBotWebhook_ bot webhookConfig = void . startBotWebhook bot webhookConfig
-- | Get a 'Telegram.Token' from environment variable.
--
-- Common use:
--
-- @
-- 'getEnvToken' "TELEGRAM_BOT_TOKEN"
-- @
getEnvToken :: String -> IO Telegram.Token
getEnvToken varName = fromString <$> getEnv varName
startBotEnv :: BotApp model action -> ClientEnv -> IO (BotEnv model action)
startBotEnv bot env = do
botEnv <- defaultBotEnv bot env
_jobThreadIds <- scheduleBotJobs botEnv (botJobs bot)
_actionsThreadId <- processActionsIndefinitely bot botEnv
return botEnv