{-# 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, webhookApp)
import Telegram.Bot.Simple.BotApp.Internal
startBotAsync :: BotApp model action -> ClientEnv -> IO (action -> IO ())
startBotAsync :: forall model action.
BotApp model action -> ClientEnv -> IO (action -> IO ())
startBotAsync BotApp model action
bot ClientEnv
env = do
BotEnv model action
botEnv <- forall model action.
BotApp model action -> ClientEnv -> IO (BotEnv model action)
startBotEnv BotApp model action
bot ClientEnv
env
forall {a}. ClientM a -> IO ()
fork_ forall a b. (a -> b) -> a -> b
$ forall model action.
BotApp model action -> BotEnv model action -> ClientM ()
startBotPolling BotApp model action
bot BotEnv model action
botEnv
forall (m :: * -> *) a. Monad m => a -> m a
return (forall model action.
BotEnv model action -> Maybe Update -> Maybe action -> IO ()
issueAction BotEnv model action
botEnv forall a. Maybe a
Nothing forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Maybe a
Just)
where
fork_ :: ClientM a -> IO ()
fork_ = forall (f :: * -> *) a. Functor f => f a -> f ()
void forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO () -> IO ThreadId
forkIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. Functor f => f a -> f ()
void forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. ClientM a -> ClientEnv -> IO (Either ClientError a)
runClientM ClientEnv
env
startBotAsync_ :: BotApp model action -> ClientEnv -> IO ()
startBotAsync_ :: forall model action. BotApp model action -> ClientEnv -> IO ()
startBotAsync_ BotApp model action
bot ClientEnv
env = forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall model action.
BotApp model action -> ClientEnv -> IO (action -> IO ())
startBotAsync BotApp model action
bot ClientEnv
env)
startBot :: BotApp model action -> ClientEnv -> IO (Either ClientError ())
startBot :: forall model action.
BotApp model action -> ClientEnv -> IO (Either ClientError ())
startBot BotApp model action
bot ClientEnv
env = do
BotEnv model action
botEnv <- forall model action.
BotApp model action -> ClientEnv -> IO (BotEnv model action)
startBotEnv BotApp model action
bot ClientEnv
env
forall a. ClientM a -> ClientEnv -> IO (Either ClientError a)
runClientM (forall model action.
BotApp model action -> BotEnv model action -> ClientM ()
startBotPolling BotApp model action
bot BotEnv model action
botEnv) ClientEnv
env
startBot_ :: BotApp model action -> ClientEnv -> IO ()
startBot_ :: forall model action. BotApp model action -> ClientEnv -> IO ()
startBot_ BotApp model action
bot = forall (f :: * -> *) a. Functor f => f a -> f ()
void forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall model action.
BotApp model action -> ClientEnv -> IO (Either ClientError ())
startBot BotApp model action
bot
data WebhookConfig = WebhookConfig
{ WebhookConfig -> TLSSettings
webhookConfigTlsSettings :: TLSSettings,
WebhookConfig -> Settings
webhookConfigTlsWarpSettings :: Settings,
WebhookConfig -> SetWebhookRequest
webhookConfigSetWebhookRequest :: SetWebhookRequest
}
startBotWebhook :: BotApp model action -> WebhookConfig -> ClientEnv -> IO (Either ClientError ())
startBotWebhook :: forall model action.
BotApp model action
-> WebhookConfig -> ClientEnv -> IO (Either ClientError ())
startBotWebhook BotApp model action
bot (WebhookConfig{SetWebhookRequest
Settings
TLSSettings
webhookConfigSetWebhookRequest :: SetWebhookRequest
webhookConfigTlsWarpSettings :: Settings
webhookConfigTlsSettings :: TLSSettings
webhookConfigSetWebhookRequest :: WebhookConfig -> SetWebhookRequest
webhookConfigTlsWarpSettings :: WebhookConfig -> Settings
webhookConfigTlsSettings :: WebhookConfig -> TLSSettings
..}) ClientEnv
env = do
BotEnv model action
botEnv <- forall model action.
BotApp model action -> ClientEnv -> IO (BotEnv model action)
startBotEnv BotApp model action
bot ClientEnv
env
Either ClientError ()
res <- SetWebhookRequest -> ClientEnv -> IO (Either ClientError ())
setUpWebhook SetWebhookRequest
webhookConfigSetWebhookRequest ClientEnv
env
if forall a b. Either a b -> Bool
isLeft Either ClientError ()
res
then forall (m :: * -> *) a. Monad m => a -> m a
return Either ClientError ()
res
else forall a b. b -> Either a b
Right forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TLSSettings -> Settings -> Application -> IO ()
runTLS TLSSettings
webhookConfigTlsSettings Settings
webhookConfigTlsWarpSettings (forall model action.
BotApp model action -> BotEnv model action -> Application
webhookApp BotApp model action
bot BotEnv model action
botEnv)
forall a b. IO a -> IO b -> IO a
`finally`
ClientEnv -> IO (Either ClientError ())
deleteWebhook ClientEnv
env
startBotWebhook_ :: BotApp model action -> WebhookConfig -> ClientEnv -> IO ()
startBotWebhook_ :: forall model action.
BotApp model action -> WebhookConfig -> ClientEnv -> IO ()
startBotWebhook_ BotApp model action
bot WebhookConfig
webhookConfig = forall (f :: * -> *) a. Functor f => f a -> f ()
void forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall model action.
BotApp model action
-> WebhookConfig -> ClientEnv -> IO (Either ClientError ())
startBotWebhook BotApp model action
bot WebhookConfig
webhookConfig
getEnvToken :: String -> IO Telegram.Token
getEnvToken :: String -> IO Token
getEnvToken String
varName = forall a. IsString a => String -> a
fromString forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO String
getEnv String
varName
startBotEnv :: BotApp model action -> ClientEnv -> IO (BotEnv model action)
startBotEnv :: forall model action.
BotApp model action -> ClientEnv -> IO (BotEnv model action)
startBotEnv BotApp model action
bot ClientEnv
env = do
BotEnv model action
botEnv <- forall model action.
BotApp model action -> ClientEnv -> IO (BotEnv model action)
defaultBotEnv BotApp model action
bot ClientEnv
env
[ThreadId]
_jobThreadIds <- forall model action.
BotEnv model action -> [BotJob model action] -> IO [ThreadId]
scheduleBotJobs BotEnv model action
botEnv (forall model action. BotApp model action -> [BotJob model action]
botJobs BotApp model action
bot)
ThreadId
_actionsThreadId <- forall model action.
BotApp model action -> BotEnv model action -> IO ThreadId
processActionsIndefinitely BotApp model action
bot BotEnv model action
botEnv
forall (m :: * -> *) a. Monad m => a -> m a
return BotEnv model action
botEnv