{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE UnicodeSyntax #-}
{-# LANGUAGE OverloadedRecordDot #-}
module MatrixBot.App
( runApp
) where
import GHC.Generics (Generic)
import Data.Aeson (ToJSON (..), FromJSON (..), eitherDecodeFileStrict)
import Data.Aeson.Text (encodeToLazyText)
import Data.String (IsString)
import Data.Text (Text, pack)
import Data.Text.Lazy (toStrict)
import qualified Data.Text.IO as TextIO
import Control.Lens.Lens (lens)
import Control.Monad.IO.Class
import Control.Monad.IO.Unlift (MonadUnliftIO)
import qualified Control.Exception.Safe as E
import qualified Control.Monad.Logger as ML
import qualified Control.Monad.Reader as MR
import System.Exit (ExitCode (..))
import System.IO
import MatrixBot.AesonUtils (myGenericToJSON, myGenericParseJSON)
import MatrixBot.Log
import MatrixBot.MatrixApi (EventResponse)
import qualified MatrixBot.Auth as Auth
import qualified MatrixBot.Bot as Bot
import qualified MatrixBot.Options as O
import qualified MatrixBot.SharedTypes as T
import MatrixBot.Bot.Jobs.Handlers.SendMessage (sendMessage, MessageEdit (..))
import qualified MatrixBot.Bot.Jobs.Queue as BotJobsQueue
import qualified Control.Lens as Lens
import qualified UnliftIO as UIO
type AppM m =
( MonadIO m
, MonadUnliftIO m
, MonadFail m
, E.MonadMask m
)
runApp ∷ AppM m ⇒ m ()
runApp :: forall (m :: * -> *). AppM m => m ()
runApp = m ()
forall {m :: * -> *}.
(MonadUnliftIO m, MonadFail m, MonadMask m) =>
m ()
go where
go :: m ()
go = do
LogStateHandle
logStateHandle ← m LogStateHandle
forall (m :: * -> *). MonadIO m => m LogStateHandle
createLogState
LogStateHandle -> (Logger -> m ()) -> m ()
forall (m :: * -> *) a.
MonadUnliftIO m =>
LogStateHandle -> (Logger -> m a) -> m a
withLogger LogStateHandle
logStateHandle ((Logger -> m ()) -> m ())
-> (ReaderT Logger m () -> Logger -> m ())
-> ReaderT Logger m ()
-> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReaderT Logger m () -> Logger -> m ()
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
MR.runReaderT (ReaderT Logger m () -> m ()) -> ReaderT Logger m () -> m ()
forall a b. (a -> b) -> a -> b
$
ReaderT Logger m ()
-> (SomeException -> ReaderT Logger m ()) -> ReaderT Logger m ()
forall (m :: * -> *) e a.
(HasCallStack, MonadCatch m, Exception e) =>
m a -> (e -> m a) -> m a
E.catch (LogStateHandle -> ReaderT Logger m ()
forall (m :: * -> *).
(AppM m, MonadLogger m) =>
LogStateHandle -> m ()
startApp LogStateHandle
logStateHandle) (LogStateHandle -> SomeException -> ReaderT Logger m ()
forall (m :: * -> *).
(MonadUnliftIO m, MonadThrow m, MonadLogger m) =>
LogStateHandle -> SomeException -> m ()
exceptionHandler LogStateHandle
logStateHandle)
exceptionHandler
∷ (UIO.MonadUnliftIO m, E.MonadThrow m, ML.MonadLogger m)
⇒ LogStateHandle
→ E.SomeException
→ m ()
exceptionHandler :: forall (m :: * -> *).
(MonadUnliftIO m, MonadThrow m, MonadLogger m) =>
LogStateHandle -> SomeException -> m ()
exceptionHandler LogStateHandle
logStateHandle SomeException
e = do
LogStateHandle -> m ()
forall (m :: * -> *).
(MonadUnliftIO m, MonadLogger m) =>
LogStateHandle -> m ()
forceLogInitialization LogStateHandle
logStateHandle
case forall e. Exception e => SomeException -> Maybe e
E.fromException @ExitCode SomeException
e of
Just ExitCode
ExitSuccess → do
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m ()) -> (SomeException -> Text) -> SomeException -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
pack (String -> Text)
-> (SomeException -> String) -> SomeException -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String
"Application exits with: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<>) (String -> String)
-> (SomeException -> String) -> SomeException -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SomeException -> String
forall e. Exception e => e -> String
E.displayException (SomeException -> m ()) -> SomeException -> m ()
forall a b. (a -> b) -> a -> b
$ SomeException
e
SomeException -> m ()
forall (m :: * -> *) e a.
(HasCallStack, MonadThrow m, Exception e) =>
e -> m a
E.throwM SomeException
e
Maybe ExitCode
_ → do
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logError (Text -> m ()) -> (SomeException -> Text) -> SomeException -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
pack (String -> Text)
-> (SomeException -> String) -> SomeException -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String
"Application failed with: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<>) (String -> String)
-> (SomeException -> String) -> SomeException -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SomeException -> String
forall e. Exception e => e -> String
E.displayException (SomeException -> m ()) -> SomeException -> m ()
forall a b. (a -> b) -> a -> b
$ SomeException
e
SomeException -> m ()
forall (m :: * -> *) e a.
(HasCallStack, MonadThrow m, Exception e) =>
e -> m a
E.throwM SomeException
e
startApp ∷ (AppM m, ML.MonadLogger m) ⇒ LogStateHandle → m ()
startApp :: forall (m :: * -> *).
(AppM m, MonadLogger m) =>
LogStateHandle -> m ()
startApp LogStateHandle
logStateHandle = do
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug Text
"Starting the application…"
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug Text
"Parsing the command-line arguments…"
m AppCommand
forall (m :: * -> *). MonadIO m => m AppCommand
O.parseAppCommand m AppCommand -> (AppCommand -> m ()) -> m ()
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
O.AppCommandAuth AuthOptions
opts → do
LogStateHandle -> Maybe LogLevel -> m ()
forall (m :: * -> *).
(MonadUnliftIO m, MonadLogger m) =>
LogStateHandle -> Maybe LogLevel -> m ()
setLogLevel LogStateHandle
logStateHandle AuthOptions
opts.authOptionsLogLevel
AuthOptions -> m ()
forall (m :: * -> *).
(MonadIO m, MonadUnliftIO m, MonadFail m, MonadThrow m,
MonadLogger m) =>
AuthOptions -> m ()
runAuth AuthOptions
opts
O.AppCommandStart StartOptions
opts → do
LogStateHandle -> Maybe LogLevel -> m ()
forall (m :: * -> *).
(MonadUnliftIO m, MonadLogger m) =>
LogStateHandle -> Maybe LogLevel -> m ()
setLogLevel LogStateHandle
logStateHandle StartOptions
opts.startOptionsLogLevel
StartOptions -> m ()
forall (m :: * -> *).
(MonadIO m, MonadFail m, MonadMask m, MonadUnliftIO m,
MonadLogger m) =>
StartOptions -> m ()
runStart StartOptions
opts
O.AppCommandSendMessage SendMessageOptions
opts → do
LogStateHandle -> Maybe LogLevel -> m ()
forall (m :: * -> *).
(MonadUnliftIO m, MonadLogger m) =>
LogStateHandle -> Maybe LogLevel -> m ()
setLogLevel LogStateHandle
logStateHandle SendMessageOptions
opts.sendMessageOptionsLogLevel
SendMessageOptions -> m ()
forall (m :: * -> *).
(MonadIO m, MonadUnliftIO m, MonadFail m, MonadThrow m,
MonadLogger m) =>
SendMessageOptions -> m ()
runSendMessage SendMessageOptions
opts
O.AppCommandEditMessage EditMessageOptions
opts → do
LogStateHandle -> Maybe LogLevel -> m ()
forall (m :: * -> *).
(MonadUnliftIO m, MonadLogger m) =>
LogStateHandle -> Maybe LogLevel -> m ()
setLogLevel LogStateHandle
logStateHandle EditMessageOptions
opts.editMessageOptionsLogLevel
EditMessageOptions -> m ()
forall (m :: * -> *).
(MonadIO m, MonadUnliftIO m, MonadFail m, MonadThrow m,
MonadLogger m) =>
EditMessageOptions -> m ()
runEditMessage EditMessageOptions
opts
runAuth
∷ (MonadIO m, MonadUnliftIO m, MonadFail m, E.MonadThrow m, ML.MonadLogger m)
⇒ O.AuthOptions
→ m ()
runAuth :: forall (m :: * -> *).
(MonadIO m, MonadUnliftIO m, MonadFail m, MonadThrow m,
MonadLogger m) =>
AuthOptions -> m ()
runAuth AuthOptions
opts = do
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logInfo Text
"Running authentication…"
let quotedMxid :: Text
quotedMxid = Text -> Text
forall s. (IsString s, Show s) => s -> Text
quoted (Text -> Text) -> (AuthOptions -> Text) -> AuthOptions -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Mxid -> Text
T.printMxid (Mxid -> Text) -> (AuthOptions -> Mxid) -> AuthOptions -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AuthOptions -> Mxid
O.authOptionsMxid (AuthOptions -> Text) -> AuthOptions -> Text
forall a b. (a -> b) -> a -> b
$ AuthOptions
opts
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ Text
"MXID: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
quotedMxid
Password
password ←
case AuthOptions -> Either Password String
O.authOptionsPassword AuthOptions
opts of
Left Password
x →
Password
x Password -> m () -> m Password
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text
"Password for " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
quotedMxid Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" was provided as an option argument")
Right String
file → do
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ Text
"Reading password for " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
quotedMxid Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" from " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
forall s. (IsString s, Show s) => s -> Text
quoted String
file Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"…"
Handle
handle ← IO Handle -> m Handle
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Handle -> m Handle) -> IO Handle -> m Handle
forall a b. (a -> b) -> a -> b
$ String -> IOMode -> IO Handle
openFile String
file IOMode
ReadMode
IO Password -> m Password
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Password -> m Password) -> IO Password -> m Password
forall a b. (a -> b) -> a -> b
$ Text -> Password
T.Password (Text -> Password) -> IO Text -> IO Password
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Handle -> IO Text
TextIO.hGetLine Handle
handle
Credentials
credentials ← Mxid -> Password -> m Credentials
forall (m :: * -> *).
(MonadIO m, MonadFail m, MonadUnliftIO m, MonadThrow m,
MonadLogger m) =>
Mxid -> Password -> m Credentials
Auth.authenticate (AuthOptions -> Mxid
O.authOptionsMxid AuthOptions
opts) Password
password
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug Text
"Received credentials"
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ Text
"Saving credentials to " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (String -> Text
forall s. (IsString s, Show s) => s -> Text
quoted (String -> Text) -> (AuthOptions -> String) -> AuthOptions -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AuthOptions -> String
O.authOptionsOutputFile) AuthOptions
opts Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"…"
IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> (Credentials -> IO ()) -> Credentials -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text -> IO ()
TextIO.writeFile (AuthOptions -> String
O.authOptionsOutputFile AuthOptions
opts) (Text -> IO ()) -> (Credentials -> Text) -> Credentials -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LazyText -> Text
toStrict (LazyText -> Text)
-> (Credentials -> LazyText) -> Credentials -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Credentials -> LazyText
forall a. ToJSON a => a -> LazyText
encodeToLazyText (Credentials -> m ()) -> Credentials -> m ()
forall a b. (a -> b) -> a -> b
$ Credentials
credentials
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logInfo Text
"Success!"
runStart
∷ (MonadIO m, MonadFail m, E.MonadMask m, MonadUnliftIO m, ML.MonadLogger m)
⇒ O.StartOptions
→ m ()
runStart :: forall (m :: * -> *).
(MonadIO m, MonadFail m, MonadMask m, MonadUnliftIO m,
MonadLogger m) =>
StartOptions -> m ()
runStart StartOptions
opts = do
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logInfo Text
"Initializing the bot…"
let
retryLimit :: RetryLimit
retryLimit = StartOptions -> RetryLimit
O.startOptionsRetryLimit StartOptions
opts
retryDelay :: RetryDelay
retryDelay = StartOptions -> RetryDelay
O.startOptionsRetryDelay StartOptions
opts
eventTokenFile :: Maybe String
eventTokenFile = StartOptions -> Maybe String
O.startOptionsEventTokenFile StartOptions
opts
eventsTimeout :: EventsTimeout
eventsTimeout = StartOptions -> EventsTimeout
O.startOptionsEventsTimeout StartOptions
opts
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"Failed Matrix API call retry limit: "
, String -> Text
pack (String -> Text) -> (RetryLimit -> String) -> RetryLimit -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Natural -> String
forall a. Show a => a -> String
show (Natural -> String)
-> (RetryLimit -> Natural) -> RetryLimit -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RetryLimit -> Natural
T.unRetryLimit (RetryLimit -> Text) -> RetryLimit -> Text
forall a b. (a -> b) -> a -> b
$ RetryLimit
retryLimit
, Text
" (amount of retries before bot fails completely)"
]
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"Failed Matrix API call retry interval: "
, RetryDelay -> Text
forall s. IsString s => RetryDelay -> s
T.printRetryDelaySeconds RetryDelay
retryDelay
]
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"Matrix events listening timeout: "
, String -> Text
pack (String -> Text)
-> (EventsTimeout -> String) -> EventsTimeout -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> String
forall a. Show a => a -> String
show (Integer -> String)
-> (EventsTimeout -> Integer) -> EventsTimeout -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Seconds -> Integer
T.unSeconds (Seconds -> Integer)
-> (EventsTimeout -> Seconds) -> EventsTimeout -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EventsTimeout -> Seconds
T.unEventsTimeout (EventsTimeout -> Text) -> EventsTimeout -> Text
forall a b. (a -> b) -> a -> b
$ EventsTimeout
eventsTimeout
, Text
" second(s)"
]
case Maybe String
eventTokenFile of
Maybe String
Nothing →
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logWarn (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"There’s no event token file provided, "
, Text
"will start listening from next following events"
]
Just String
x →
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"Event token file where to read from and save to last event token that is used "
, Text
"as a starting point to get next events from: ", String -> Text
pack (String -> Text) -> (String -> String) -> String -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
forall a. Show a => a -> String
show (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ String
x
]
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"Reading and parsing credentials "
, String -> Text
forall s. (IsString s, Show s) => s -> Text
quoted (String -> Text)
-> (StartOptions -> String) -> StartOptions -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StartOptions -> String
O.startOptionsCredentialsFile (StartOptions -> Text) -> StartOptions -> Text
forall a b. (a -> b) -> a -> b
$ StartOptions
opts
, Text
" file…"
]
Credentials
credentials ←
(String -> m Credentials)
-> (Credentials -> m Credentials)
-> Either String Credentials
-> m Credentials
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> m Credentials
forall a. String -> m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail Credentials -> m Credentials
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either String Credentials -> m Credentials)
-> m (Either String Credentials) -> m Credentials
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO (Either String Credentials) -> m (Either String Credentials)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (String -> IO (Either String Credentials)
forall a. FromJSON a => String -> IO (Either String a)
eitherDecodeFileStrict (String -> IO (Either String Credentials))
-> (StartOptions -> String)
-> StartOptions
-> IO (Either String Credentials)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StartOptions -> String
O.startOptionsCredentialsFile (StartOptions -> IO (Either String Credentials))
-> StartOptions -> IO (Either String Credentials)
forall a b. (a -> b) -> a -> b
$ StartOptions
opts)
let
quotedMxid :: Text
quotedMxid
= Text -> Text
forall s. (IsString s, Show s) => s -> Text
quoted (Text -> Text) -> (Mxid -> Text) -> Mxid -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Mxid -> Text
T.printMxid
(Mxid -> Text) -> Mxid -> Text
forall a b. (a -> b) -> a -> b
$ Username -> HomeServer -> Mxid
T.Mxid (Credentials -> Username
Auth.credentialsUsername Credentials
credentials) (Credentials -> HomeServer
Auth.credentialsHomeServer Credentials
credentials)
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ Text
"MXID: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
quotedMxid
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"Reading and parsing bot configuration from "
, String -> Text
forall s. (IsString s, Show s) => s -> Text
quoted (String -> Text)
-> (StartOptions -> String) -> StartOptions -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StartOptions -> String
O.startOptionsBotConfigFile (StartOptions -> Text) -> StartOptions -> Text
forall a b. (a -> b) -> a -> b
$ StartOptions
opts
, Text
" file…"
]
BotConfig
botConfig ←
(String -> m BotConfig)
-> (BotConfig -> m BotConfig)
-> Either String BotConfig
-> m BotConfig
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> m BotConfig
forall a. String -> m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail BotConfig -> m BotConfig
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either String BotConfig -> m BotConfig)
-> m (Either String BotConfig) -> m BotConfig
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO (Either String BotConfig) -> m (Either String BotConfig)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (String -> IO (Either String BotConfig)
forall a. FromJSON a => String -> IO (Either String a)
eitherDecodeFileStrict (String -> IO (Either String BotConfig))
-> (StartOptions -> String)
-> StartOptions
-> IO (Either String BotConfig)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StartOptions -> String
O.startOptionsBotConfigFile (StartOptions -> IO (Either String BotConfig))
-> StartOptions -> IO (Either String BotConfig)
forall a b. (a -> b) -> a -> b
$ StartOptions
opts)
BotJobsQueue
botJobsQueue ← m BotJobsQueue
forall (m :: * -> *). MonadIO m => m BotJobsQueue
BotJobsQueue.mkBotJobsQueue
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logInfo Text
"Listening to events…"
Maybe String -> EventsTimeout -> BotConfig -> ReaderT BotEnv m ()
forall r (m :: * -> *).
(BotM r m, HasBotJobsReader r, HasBotJobsWriter r) =>
Maybe String -> EventsTimeout -> BotConfig -> m ()
Bot.startTheBot Maybe String
eventTokenFile EventsTimeout
eventsTimeout BotConfig
botConfig
ReaderT BotEnv m () -> BotEnv -> m ()
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
`MR.runReaderT` Credentials -> RetryLimit -> RetryDelay -> BotJobsQueue -> BotEnv
BotEnv Credentials
credentials RetryLimit
retryLimit RetryDelay
retryDelay BotJobsQueue
botJobsQueue
runSendMessage
∷ (MonadIO m, MonadUnliftIO m, MonadFail m, E.MonadThrow m, ML.MonadLogger m)
⇒ O.SendMessageOptions
→ m ()
runSendMessage :: forall (m :: * -> *).
(MonadIO m, MonadUnliftIO m, MonadFail m, MonadThrow m,
MonadLogger m) =>
SendMessageOptions -> m ()
runSendMessage SendMessageOptions
opts = do
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logInfo Text
"Running send message command…"
let roomId :: RoomId
roomId = SendMessageOptions -> RoomId
O.sendMessageOptionsRoomId SendMessageOptions
opts
Credentials
credentials ∷ Auth.Credentials ← do
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"Reading and parsing credentials "
, String -> Text
forall s. (IsString s, Show s) => s -> Text
quoted (String -> Text)
-> (SendMessageOptions -> String) -> SendMessageOptions -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SendMessageOptions -> String
O.sendMessageOptionsCredentialsFile (SendMessageOptions -> Text) -> SendMessageOptions -> Text
forall a b. (a -> b) -> a -> b
$ SendMessageOptions
opts
, Text
" file…"
]
(String -> m Credentials)
-> (Credentials -> m Credentials)
-> Either String Credentials
-> m Credentials
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> m Credentials
forall a. String -> m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail Credentials -> m Credentials
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either String Credentials -> m Credentials)
-> m (Either String Credentials) -> m Credentials
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO (Either String Credentials) -> m (Either String Credentials)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (String -> IO (Either String Credentials)
forall a. FromJSON a => String -> IO (Either String a)
eitherDecodeFileStrict (String -> IO (Either String Credentials))
-> (SendMessageOptions -> String)
-> SendMessageOptions
-> IO (Either String Credentials)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SendMessageOptions -> String
O.sendMessageOptionsCredentialsFile (SendMessageOptions -> IO (Either String Credentials))
-> SendMessageOptions -> IO (Either String Credentials)
forall a b. (a -> b) -> a -> b
$ SendMessageOptions
opts)
Text
message ←
case SendMessageOptions -> Either Text String
O.sendMessageOptionsMessage SendMessageOptions
opts of
Left Text
x →
(Text
x Text -> m () -> m Text
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$) (m () -> m Text) -> (Text -> m ()) -> Text -> m Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m Text) -> Text -> m Text
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"Message to send to ", String -> Text
pack (String -> Text) -> (RoomId -> String) -> RoomId -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
forall a. Show a => a -> String
show (Text -> String) -> (RoomId -> Text) -> RoomId -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RoomId -> Text
T.printRoomId (RoomId -> Text) -> RoomId -> Text
forall a b. (a -> b) -> a -> b
$ RoomId
roomId
, Text
" room was provided as an option argument"
]
Right String
file → do
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"Reading message to send to ", String -> Text
pack (String -> Text) -> (RoomId -> String) -> RoomId -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
forall a. Show a => a -> String
show (Text -> String) -> (RoomId -> Text) -> RoomId -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RoomId -> Text
T.printRoomId (RoomId -> Text) -> RoomId -> Text
forall a b. (a -> b) -> a -> b
$ RoomId
roomId
, Text
" room from ", String -> Text
pack (String -> Text) -> (String -> String) -> String -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
forall a. Show a => a -> String
show (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ String
file, Text
" file…"
]
IO Text -> m Text
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Text -> m Text) -> IO Text -> m Text
forall a b. (a -> b) -> a -> b
$ String -> IO Text
TextIO.readFile String
file
Maybe Text
htmlMessage ←
case SendMessageOptions -> Maybe (Either Text String)
O.sendMessageOptionsHtmlMessage SendMessageOptions
opts of
Maybe (Either Text String)
Nothing → Maybe Text -> m (Maybe Text)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Text
forall a. Maybe a
Nothing
Just (Left Text
x) →
(Text -> Maybe Text
forall a. a -> Maybe a
Just Text
x Maybe Text -> m () -> m (Maybe Text)
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$) (m () -> m (Maybe Text))
-> (Text -> m ()) -> Text -> m (Maybe Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m (Maybe Text)) -> Text -> m (Maybe Text)
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"HTML-formatted message to send to "
, (String -> Text
pack (String -> Text) -> (RoomId -> String) -> RoomId -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
forall a. Show a => a -> String
show (Text -> String) -> (RoomId -> Text) -> RoomId -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RoomId -> Text
T.printRoomId) RoomId
roomId
, Text
" room was provided as an option argument"
]
Just (Right String
file) → do
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"Reading HTML-formatted message to send to "
, (String -> Text
pack (String -> Text) -> (RoomId -> String) -> RoomId -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
forall a. Show a => a -> String
show (Text -> String) -> (RoomId -> Text) -> RoomId -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RoomId -> Text
T.printRoomId) RoomId
roomId
, Text
" room from "
, (String -> Text
pack (String -> Text) -> (String -> String) -> String -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
forall a. Show a => a -> String
show) String
file
, Text
" file…"
]
(Text -> Maybe Text) -> m Text -> m (Maybe Text)
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Maybe Text
forall a. a -> Maybe a
Just (m Text -> m (Maybe Text))
-> (IO Text -> m Text) -> IO Text -> m (Maybe Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO Text -> m Text
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Text -> m (Maybe Text)) -> IO Text -> m (Maybe Text)
forall a b. (a -> b) -> a -> b
$ String -> IO Text
TextIO.readFile String
file
Maybe EventId
replyTo ←
case SendMessageOptions -> Maybe EventId
O.sendMessageOptionsReplyTo SendMessageOptions
opts of
Maybe EventId
Nothing → Maybe EventId -> m (Maybe EventId)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe EventId
forall a. Maybe a
Nothing
Just EventId
x → (EventId -> Maybe EventId
forall a. a -> Maybe a
Just EventId
x Maybe EventId -> m () -> m (Maybe EventId)
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$) (m () -> m (Maybe EventId)) -> m () -> m (Maybe EventId)
forall a b. (a -> b) -> a -> b
$ Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat [Text
"Replying to ", (String -> Text
pack (String -> Text) -> (EventId -> String) -> EventId -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EventId -> String
forall a. Show a => a -> String
show) EventId
x]
(ReaderT Credentials m () -> Credentials -> m ())
-> Credentials -> ReaderT Credentials m () -> m ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip ReaderT Credentials m () -> Credentials -> m ()
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
MR.runReaderT Credentials
credentials (ReaderT Credentials m () -> m ())
-> ReaderT Credentials m () -> m ()
forall a b. (a -> b) -> a -> b
$
EventsTimeout
-> (MatrixApiClient
-> AuthenticatedRequest (AuthProtect "access-token")
-> ReaderT Credentials m ())
-> ReaderT Credentials m ()
forall (m :: * -> *) r a.
(MonadIO m, MonadUnliftIO m, MonadThrow m, MonadLogger m,
MonadReader r m, HasCredentials r) =>
EventsTimeout
-> (MatrixApiClient
-> AuthenticatedRequest (AuthProtect "access-token") -> m a)
-> m a
Bot.withReqAndAuth (Seconds -> EventsTimeout
T.EventsTimeout (Seconds -> EventsTimeout)
-> (Integer -> Seconds) -> Integer -> EventsTimeout
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Seconds
T.Seconds (Integer -> EventsTimeout) -> Integer -> EventsTimeout
forall a b. (a -> b) -> a -> b
$ Integer
30) ((MatrixApiClient
-> AuthenticatedRequest (AuthProtect "access-token")
-> ReaderT Credentials m ())
-> ReaderT Credentials m ())
-> (MatrixApiClient
-> AuthenticatedRequest (AuthProtect "access-token")
-> ReaderT Credentials m ())
-> ReaderT Credentials m ()
forall a b. (a -> b) -> a -> b
$ \MatrixApiClient
req AuthenticatedRequest (AuthProtect "access-token")
auth → do
TransactionId
transactionId ←
case SendMessageOptions -> Maybe TransactionId
O.sendMessageOptionsTransactionId SendMessageOptions
opts of
Maybe TransactionId
Nothing → do
TransactionId
txid ← ReaderT Credentials m TransactionId
forall (m :: * -> *). MonadIO m => m TransactionId
T.genTransactionId
(TransactionId
txid TransactionId
-> ReaderT Credentials m () -> ReaderT Credentials m TransactionId
forall a b. a -> ReaderT Credentials m b -> ReaderT Credentials m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$) (ReaderT Credentials m () -> ReaderT Credentials m TransactionId)
-> (Text -> ReaderT Credentials m ())
-> Text
-> ReaderT Credentials m TransactionId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ReaderT Credentials m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> ReaderT Credentials m TransactionId)
-> Text -> ReaderT Credentials m TransactionId
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"No transaction ID was provided in the command-line options, generated new one: "
, String -> Text
pack (String -> Text)
-> (TransactionId -> String) -> TransactionId -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UUID -> String
forall a. Show a => a -> String
show (UUID -> String)
-> (TransactionId -> UUID) -> TransactionId -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TransactionId -> UUID
T.unTransactionId (TransactionId -> Text) -> TransactionId -> Text
forall a b. (a -> b) -> a -> b
$ TransactionId
txid
]
Just TransactionId
txid → do
(TransactionId
txid TransactionId
-> ReaderT Credentials m () -> ReaderT Credentials m TransactionId
forall a b. a -> ReaderT Credentials m b -> ReaderT Credentials m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$) (ReaderT Credentials m () -> ReaderT Credentials m TransactionId)
-> (Text -> ReaderT Credentials m ())
-> Text
-> ReaderT Credentials m TransactionId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ReaderT Credentials m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> ReaderT Credentials m TransactionId)
-> Text -> ReaderT Credentials m TransactionId
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"Using transaction ID provided in the command-line options: "
, String -> Text
pack (String -> Text)
-> (TransactionId -> String) -> TransactionId -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UUID -> String
forall a. Show a => a -> String
show (UUID -> String)
-> (TransactionId -> UUID) -> TransactionId -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TransactionId -> UUID
T.unTransactionId (TransactionId -> Text) -> TransactionId -> Text
forall a b. (a -> b) -> a -> b
$ TransactionId
txid
]
EventResponse
response ← MatrixApiClient
-> AuthenticatedRequest (AuthProtect "access-token")
-> TransactionId
-> RoomId
-> Maybe EventId
-> Maybe Text
-> Text
-> Maybe MessageEdit
-> ReaderT Credentials m EventResponse
forall (m :: * -> *).
(MonadIO m, MonadFail m, MonadThrow m, MonadLogger m) =>
MatrixApiClient
-> AuthenticatedRequest (AuthProtect "access-token")
-> TransactionId
-> RoomId
-> Maybe EventId
-> Maybe Text
-> Text
-> Maybe MessageEdit
-> m EventResponse
sendMessage MatrixApiClient
req AuthenticatedRequest (AuthProtect "access-token")
auth TransactionId
transactionId RoomId
roomId Maybe EventId
replyTo Maybe Text
htmlMessage Text
message Maybe MessageEdit
forall a. Maybe a
Nothing
Text -> ReaderT Credentials m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug Text
"Printing response and transaction ID to stdout…"
IO () -> ReaderT Credentials m ()
forall a. IO a -> ReaderT Credentials m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ReaderT Credentials m ())
-> (SendMessageResponse -> IO ())
-> SendMessageResponse
-> ReaderT Credentials m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> IO ()
TextIO.putStrLn (Text -> IO ())
-> (SendMessageResponse -> Text) -> SendMessageResponse -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LazyText -> Text
toStrict (LazyText -> Text)
-> (SendMessageResponse -> LazyText) -> SendMessageResponse -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SendMessageResponse -> LazyText
forall a. ToJSON a => a -> LazyText
encodeToLazyText (SendMessageResponse -> ReaderT Credentials m ())
-> SendMessageResponse -> ReaderT Credentials m ()
forall a b. (a -> b) -> a -> b
$ SendMessageResponse
{ sendMessageResponseTransactionId :: TransactionId
sendMessageResponseTransactionId = TransactionId
transactionId
, sendMessageResponseResponse :: EventResponse
sendMessageResponseResponse = EventResponse
response
}
Text -> ReaderT Credentials m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logInfo Text
"Success!"
runEditMessage
∷ (MonadIO m, MonadUnliftIO m, MonadFail m, E.MonadThrow m, ML.MonadLogger m)
⇒ O.EditMessageOptions
→ m ()
runEditMessage :: forall (m :: * -> *).
(MonadIO m, MonadUnliftIO m, MonadFail m, MonadThrow m,
MonadLogger m) =>
EditMessageOptions -> m ()
runEditMessage EditMessageOptions
opts = do
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logInfo Text
"Running edit message command…"
let roomId :: RoomId
roomId = EditMessageOptions -> RoomId
O.editMessageOptionsRoomId EditMessageOptions
opts
Credentials
credentials ∷ Auth.Credentials ← do
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"Reading and parsing credentials "
, (String -> Text
forall s. (IsString s, Show s) => s -> Text
quoted (String -> Text)
-> (EditMessageOptions -> String) -> EditMessageOptions -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EditMessageOptions -> String
O.editMessageOptionsCredentialsFile) EditMessageOptions
opts
, Text
" file…"
]
(String -> m Credentials)
-> (Credentials -> m Credentials)
-> Either String Credentials
-> m Credentials
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> m Credentials
forall a. String -> m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail Credentials -> m Credentials
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either String Credentials -> m Credentials)
-> m (Either String Credentials) -> m Credentials
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO (Either String Credentials) -> m (Either String Credentials)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (String -> IO (Either String Credentials)
forall a. FromJSON a => String -> IO (Either String a)
eitherDecodeFileStrict (String -> IO (Either String Credentials))
-> (EditMessageOptions -> String)
-> EditMessageOptions
-> IO (Either String Credentials)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EditMessageOptions -> String
O.editMessageOptionsCredentialsFile (EditMessageOptions -> IO (Either String Credentials))
-> EditMessageOptions -> IO (Either String Credentials)
forall a b. (a -> b) -> a -> b
$ EditMessageOptions
opts)
Text
message ←
case EditMessageOptions -> Either Text String
O.editMessageOptionsMessage EditMessageOptions
opts of
Left Text
x →
(Text
x Text -> m () -> m Text
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$) (m () -> m Text) -> (Text -> m ()) -> Text -> m Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m Text) -> Text -> m Text
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"New message body for the message "
, (String -> Text
pack (String -> Text)
-> (EditMessageOptions -> String) -> EditMessageOptions -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EventId -> String
forall a. Show a => a -> String
show (EventId -> String)
-> (EditMessageOptions -> EventId) -> EditMessageOptions -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EditMessageOptions -> EventId
O.editMessageOptionsMessageId) EditMessageOptions
opts
, Text
" in the room "
, (Text -> Text
forall s. (IsString s, Show s) => s -> Text
quoted (Text -> Text) -> (RoomId -> Text) -> RoomId -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RoomId -> Text
T.printRoomId) RoomId
roomId
, Text
" was provided as an option argument"
]
Right String
file → do
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"Reading new message message body for the message "
, (String -> Text
pack (String -> Text)
-> (EditMessageOptions -> String) -> EditMessageOptions -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EventId -> String
forall a. Show a => a -> String
show (EventId -> String)
-> (EditMessageOptions -> EventId) -> EditMessageOptions -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EditMessageOptions -> EventId
O.editMessageOptionsMessageId) EditMessageOptions
opts
, Text
" in the room "
, (Text -> Text
forall s. (IsString s, Show s) => s -> Text
quoted (Text -> Text) -> (RoomId -> Text) -> RoomId -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RoomId -> Text
T.printRoomId) RoomId
roomId
, Text
" from ", String -> Text
forall s. (IsString s, Show s) => s -> Text
quoted String
file, Text
" file…"
]
IO Text -> m Text
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Text -> m Text) -> IO Text -> m Text
forall a b. (a -> b) -> a -> b
$ String -> IO Text
TextIO.readFile String
file
Maybe Text
htmlMessage ←
case EditMessageOptions -> Maybe (Either Text String)
O.editMessageOptionsHtmlMessage EditMessageOptions
opts of
Maybe (Either Text String)
Nothing → Maybe Text -> m (Maybe Text)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Text
forall a. Maybe a
Nothing
Just (Left Text
x) →
(Text -> Maybe Text
forall a. a -> Maybe a
Just Text
x Maybe Text -> m () -> m (Maybe Text)
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$) (m () -> m (Maybe Text))
-> (Text -> m ()) -> Text -> m (Maybe Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m (Maybe Text)) -> Text -> m (Maybe Text)
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"New HTML-formatted message body for the message "
, (String -> Text
pack (String -> Text)
-> (EditMessageOptions -> String) -> EditMessageOptions -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EventId -> String
forall a. Show a => a -> String
show (EventId -> String)
-> (EditMessageOptions -> EventId) -> EditMessageOptions -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EditMessageOptions -> EventId
O.editMessageOptionsMessageId) EditMessageOptions
opts
, Text
" in the room "
, (Text -> Text
forall s. (IsString s, Show s) => s -> Text
quoted (Text -> Text) -> (RoomId -> Text) -> RoomId -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RoomId -> Text
T.printRoomId) RoomId
roomId
, Text
" was provided as an option argument"
]
Just (Right String
file) → do
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"Reading new HTML-formatted message body for the message "
, (String -> Text
pack (String -> Text)
-> (EditMessageOptions -> String) -> EditMessageOptions -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EventId -> String
forall a. Show a => a -> String
show (EventId -> String)
-> (EditMessageOptions -> EventId) -> EditMessageOptions -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EditMessageOptions -> EventId
O.editMessageOptionsMessageId) EditMessageOptions
opts
, Text
" in the room "
, (Text -> Text
forall s. (IsString s, Show s) => s -> Text
quoted (Text -> Text) -> (RoomId -> Text) -> RoomId -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RoomId -> Text
T.printRoomId) RoomId
roomId
, Text
" from ", String -> Text
forall s. (IsString s, Show s) => s -> Text
quoted String
file, Text
" file…"
]
(Text -> Maybe Text) -> m Text -> m (Maybe Text)
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Maybe Text
forall a. a -> Maybe a
Just (m Text -> m (Maybe Text))
-> (IO Text -> m Text) -> IO Text -> m (Maybe Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO Text -> m Text
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Text -> m (Maybe Text)) -> IO Text -> m (Maybe Text)
forall a b. (a -> b) -> a -> b
$ String -> IO Text
TextIO.readFile String
file
Text
compatMessage ←
case EditMessageOptions -> Maybe (Either Text String)
O.editMessageOptionsMessageCompat EditMessageOptions
opts of
Maybe (Either Text String)
Nothing → Text -> m Text
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a
compatTextDefaultTemplate Text
message)
Just (Left Text
x) →
(Text
x Text -> m () -> m Text
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$) (m () -> m Text) -> (Text -> m ()) -> Text -> m Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m Text) -> Text -> m Text
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"New old API-compatible message body for the message "
, (String -> Text
pack (String -> Text)
-> (EditMessageOptions -> String) -> EditMessageOptions -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EventId -> String
forall a. Show a => a -> String
show (EventId -> String)
-> (EditMessageOptions -> EventId) -> EditMessageOptions -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EditMessageOptions -> EventId
O.editMessageOptionsMessageId) EditMessageOptions
opts
, Text
" in the room "
, (Text -> Text
forall s. (IsString s, Show s) => s -> Text
quoted (Text -> Text) -> (RoomId -> Text) -> RoomId -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RoomId -> Text
T.printRoomId) RoomId
roomId
, Text
" was provided as an option argument"
]
Just (Right String
file) → do
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"Reading new old API-compatible message message body for the message "
, (String -> Text
pack (String -> Text)
-> (EditMessageOptions -> String) -> EditMessageOptions -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EventId -> String
forall a. Show a => a -> String
show (EventId -> String)
-> (EditMessageOptions -> EventId) -> EditMessageOptions -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EditMessageOptions -> EventId
O.editMessageOptionsMessageId) EditMessageOptions
opts
, Text
" in the room "
, (Text -> Text
forall s. (IsString s, Show s) => s -> Text
quoted (Text -> Text) -> (RoomId -> Text) -> RoomId -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RoomId -> Text
T.printRoomId) RoomId
roomId
, Text
" from ", String -> Text
forall s. (IsString s, Show s) => s -> Text
quoted String
file, Text
" file…"
]
IO Text -> m Text
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Text -> m Text) -> IO Text -> m Text
forall a b. (a -> b) -> a -> b
$ String -> IO Text
TextIO.readFile String
file
Maybe Text
compatHtmlMessage ←
case (EditMessageOptions -> Maybe (Either Text String)
O.editMessageOptionsHtmlMessageCompat EditMessageOptions
opts, Maybe Text
htmlMessage) of
(Maybe (Either Text String)
Nothing, Maybe Text
Nothing) → Maybe Text -> m (Maybe Text)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Text
forall a. Maybe a
Nothing
(Maybe (Either Text String)
Nothing, Just Text
newHtmlBody) → (Maybe Text -> m (Maybe Text)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Text -> m (Maybe Text))
-> (Text -> Maybe Text) -> Text -> m (Maybe Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe Text
forall a. a -> Maybe a
Just (Text -> Maybe Text) -> (Text -> Text) -> Text -> Maybe Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a
compatHtmlDefaultTemplate) Text
newHtmlBody
(Just (Left Text
x), Maybe Text
_) →
(Text -> Maybe Text
forall a. a -> Maybe a
Just Text
x Maybe Text -> m () -> m (Maybe Text)
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$) (m () -> m (Maybe Text))
-> (Text -> m ()) -> Text -> m (Maybe Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m (Maybe Text)) -> Text -> m (Maybe Text)
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"New old API-compatible HTML-formatted message body for the message "
, (String -> Text
pack (String -> Text)
-> (EditMessageOptions -> String) -> EditMessageOptions -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EventId -> String
forall a. Show a => a -> String
show (EventId -> String)
-> (EditMessageOptions -> EventId) -> EditMessageOptions -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EditMessageOptions -> EventId
O.editMessageOptionsMessageId) EditMessageOptions
opts
, Text
" in the room "
, (Text -> Text
forall s. (IsString s, Show s) => s -> Text
quoted (Text -> Text) -> (RoomId -> Text) -> RoomId -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RoomId -> Text
T.printRoomId) RoomId
roomId
, Text
" was provided as an option argument"
]
(Just (Right String
file), Maybe Text
_) → do
Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"Reading new old API-compatible HTML-formatted message body for the message "
, (String -> Text
pack (String -> Text)
-> (EditMessageOptions -> String) -> EditMessageOptions -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EventId -> String
forall a. Show a => a -> String
show (EventId -> String)
-> (EditMessageOptions -> EventId) -> EditMessageOptions -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EditMessageOptions -> EventId
O.editMessageOptionsMessageId) EditMessageOptions
opts
, Text
" in the room "
, (Text -> Text
forall s. (IsString s, Show s) => s -> Text
quoted (Text -> Text) -> (RoomId -> Text) -> RoomId -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RoomId -> Text
T.printRoomId) RoomId
roomId
, Text
" from ", String -> Text
forall s. (IsString s, Show s) => s -> Text
quoted String
file, Text
" file…"
]
(Text -> Maybe Text) -> m Text -> m (Maybe Text)
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Maybe Text
forall a. a -> Maybe a
Just (m Text -> m (Maybe Text))
-> (IO Text -> m Text) -> IO Text -> m (Maybe Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO Text -> m Text
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Text -> m (Maybe Text)) -> IO Text -> m (Maybe Text)
forall a b. (a -> b) -> a -> b
$ String -> IO Text
TextIO.readFile String
file
Maybe EventId
replyTo ←
case EditMessageOptions -> Maybe EventId
O.editMessageOptionsReplyTo EditMessageOptions
opts of
Maybe EventId
Nothing → Maybe EventId -> m (Maybe EventId)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe EventId
forall a. Maybe a
Nothing
Just EventId
x → (EventId -> Maybe EventId
forall a. a -> Maybe a
Just EventId
x Maybe EventId -> m () -> m (Maybe EventId)
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$) (m () -> m (Maybe EventId)) -> m () -> m (Maybe EventId)
forall a b. (a -> b) -> a -> b
$ Text -> m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat [Text
"Replying to ", (String -> Text
pack (String -> Text) -> (EventId -> String) -> EventId -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EventId -> String
forall a. Show a => a -> String
show) EventId
x]
(ReaderT Credentials m () -> Credentials -> m ())
-> Credentials -> ReaderT Credentials m () -> m ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip ReaderT Credentials m () -> Credentials -> m ()
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
MR.runReaderT Credentials
credentials (ReaderT Credentials m () -> m ())
-> ReaderT Credentials m () -> m ()
forall a b. (a -> b) -> a -> b
$
EventsTimeout
-> (MatrixApiClient
-> AuthenticatedRequest (AuthProtect "access-token")
-> ReaderT Credentials m ())
-> ReaderT Credentials m ()
forall (m :: * -> *) r a.
(MonadIO m, MonadUnliftIO m, MonadThrow m, MonadLogger m,
MonadReader r m, HasCredentials r) =>
EventsTimeout
-> (MatrixApiClient
-> AuthenticatedRequest (AuthProtect "access-token") -> m a)
-> m a
Bot.withReqAndAuth (Seconds -> EventsTimeout
T.EventsTimeout (Seconds -> EventsTimeout)
-> (Integer -> Seconds) -> Integer -> EventsTimeout
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Seconds
T.Seconds (Integer -> EventsTimeout) -> Integer -> EventsTimeout
forall a b. (a -> b) -> a -> b
$ Integer
30) ((MatrixApiClient
-> AuthenticatedRequest (AuthProtect "access-token")
-> ReaderT Credentials m ())
-> ReaderT Credentials m ())
-> (MatrixApiClient
-> AuthenticatedRequest (AuthProtect "access-token")
-> ReaderT Credentials m ())
-> ReaderT Credentials m ()
forall a b. (a -> b) -> a -> b
$ \MatrixApiClient
req AuthenticatedRequest (AuthProtect "access-token")
auth → do
TransactionId
transactionId ←
case EditMessageOptions -> Maybe TransactionId
O.editMessageOptionsTransactionId EditMessageOptions
opts of
Maybe TransactionId
Nothing → do
TransactionId
txid ← ReaderT Credentials m TransactionId
forall (m :: * -> *). MonadIO m => m TransactionId
T.genTransactionId
(TransactionId
txid TransactionId
-> ReaderT Credentials m () -> ReaderT Credentials m TransactionId
forall a b. a -> ReaderT Credentials m b -> ReaderT Credentials m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$) (ReaderT Credentials m () -> ReaderT Credentials m TransactionId)
-> (Text -> ReaderT Credentials m ())
-> Text
-> ReaderT Credentials m TransactionId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ReaderT Credentials m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> ReaderT Credentials m TransactionId)
-> Text -> ReaderT Credentials m TransactionId
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"No transaction ID was provided in the command-line options, generated new one: "
, (String -> Text
pack (String -> Text)
-> (TransactionId -> String) -> TransactionId -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UUID -> String
forall a. Show a => a -> String
show (UUID -> String)
-> (TransactionId -> UUID) -> TransactionId -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TransactionId -> UUID
T.unTransactionId) TransactionId
txid
]
Just TransactionId
txid → do
(TransactionId
txid TransactionId
-> ReaderT Credentials m () -> ReaderT Credentials m TransactionId
forall a b. a -> ReaderT Credentials m b -> ReaderT Credentials m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$) (ReaderT Credentials m () -> ReaderT Credentials m TransactionId)
-> (Text -> ReaderT Credentials m ())
-> Text
-> ReaderT Credentials m TransactionId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ReaderT Credentials m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug (Text -> ReaderT Credentials m TransactionId)
-> Text -> ReaderT Credentials m TransactionId
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
[ Text
"Using transaction ID provided in the command-line options: "
, (String -> Text
pack (String -> Text)
-> (TransactionId -> String) -> TransactionId -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UUID -> String
forall a. Show a => a -> String
show (UUID -> String)
-> (TransactionId -> UUID) -> TransactionId -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TransactionId -> UUID
T.unTransactionId) TransactionId
txid
]
EventResponse
response ←
MatrixApiClient
-> AuthenticatedRequest (AuthProtect "access-token")
-> TransactionId
-> RoomId
-> Maybe EventId
-> Maybe Text
-> Text
-> Maybe MessageEdit
-> ReaderT Credentials m EventResponse
forall (m :: * -> *).
(MonadIO m, MonadFail m, MonadThrow m, MonadLogger m) =>
MatrixApiClient
-> AuthenticatedRequest (AuthProtect "access-token")
-> TransactionId
-> RoomId
-> Maybe EventId
-> Maybe Text
-> Text
-> Maybe MessageEdit
-> m EventResponse
sendMessage MatrixApiClient
req AuthenticatedRequest (AuthProtect "access-token")
auth TransactionId
transactionId RoomId
roomId Maybe EventId
replyTo Maybe Text
compatHtmlMessage Text
compatMessage (Maybe MessageEdit -> ReaderT Credentials m EventResponse)
-> Maybe MessageEdit -> ReaderT Credentials m EventResponse
forall a b. (a -> b) -> a -> b
$
MessageEdit -> Maybe MessageEdit
forall a. a -> Maybe a
Just MessageEdit
{ messageEditMessageId :: EventId
messageEditMessageId = EditMessageOptions -> EventId
O.editMessageOptionsMessageId EditMessageOptions
opts
, messageEditNewText :: Text
messageEditNewText = Text
message
, messageEditNewHtml :: Maybe Text
messageEditNewHtml = Maybe Text
htmlMessage
}
Text -> ReaderT Credentials m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logDebug Text
"Printing response and transaction ID to stdout…"
IO () -> ReaderT Credentials m ()
forall a. IO a -> ReaderT Credentials m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ReaderT Credentials m ())
-> (SendMessageResponse -> IO ())
-> SendMessageResponse
-> ReaderT Credentials m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> IO ()
TextIO.putStrLn (Text -> IO ())
-> (SendMessageResponse -> Text) -> SendMessageResponse -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LazyText -> Text
toStrict (LazyText -> Text)
-> (SendMessageResponse -> LazyText) -> SendMessageResponse -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SendMessageResponse -> LazyText
forall a. ToJSON a => a -> LazyText
encodeToLazyText (SendMessageResponse -> ReaderT Credentials m ())
-> SendMessageResponse -> ReaderT Credentials m ()
forall a b. (a -> b) -> a -> b
$ SendMessageResponse
{ sendMessageResponseTransactionId :: TransactionId
sendMessageResponseTransactionId = TransactionId
transactionId
, sendMessageResponseResponse :: EventResponse
sendMessageResponseResponse = EventResponse
response
}
Text -> ReaderT Credentials m ()
forall (m :: * -> *). (MonadLogger m, HasCallStack) => Text -> m ()
logInfo Text
"Success!"
where
compatTextDefaultTemplate :: a -> a
compatTextDefaultTemplate = (a
"EDIT: " a -> a -> a
forall a. Semigroup a => a -> a -> a
<>)
compatHtmlDefaultTemplate :: a -> a
compatHtmlDefaultTemplate = (a
"<b>EDIT:</b> " a -> a -> a
forall a. Semigroup a => a -> a -> a
<>)
data BotEnv = BotEnv
{ BotEnv -> Credentials
botEnvCredentials ∷ Auth.Credentials
, BotEnv -> RetryLimit
botEnvRetryLimit ∷ T.RetryLimit
, BotEnv -> RetryDelay
botEnvRetryDelay ∷ T.RetryDelay
, BotEnv -> BotJobsQueue
botEnvJobsQueue ∷ BotJobsQueue.BotJobsQueue
}
instance Auth.HasCredentials BotEnv where
credentials :: Lens' BotEnv Credentials
credentials = (BotEnv -> Credentials)
-> (BotEnv -> Credentials -> BotEnv) -> Lens' BotEnv Credentials
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens BotEnv -> Credentials
botEnvCredentials ((BotEnv -> Credentials -> BotEnv) -> Lens' BotEnv Credentials)
-> (BotEnv -> Credentials -> BotEnv) -> Lens' BotEnv Credentials
forall a b. (a -> b) -> a -> b
$ \BotEnv
x Credentials
v → BotEnv
x { botEnvCredentials = v }
instance T.HasRetryParams BotEnv where
retryLimit :: Lens' BotEnv RetryLimit
retryLimit = (BotEnv -> RetryLimit)
-> (BotEnv -> RetryLimit -> BotEnv) -> Lens' BotEnv RetryLimit
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens BotEnv -> RetryLimit
botEnvRetryLimit ((BotEnv -> RetryLimit -> BotEnv) -> Lens' BotEnv RetryLimit)
-> (BotEnv -> RetryLimit -> BotEnv) -> Lens' BotEnv RetryLimit
forall a b. (a -> b) -> a -> b
$ \BotEnv
x RetryLimit
v → BotEnv
x { botEnvRetryLimit = v }
retryDelay :: Lens' BotEnv RetryDelay
retryDelay = (BotEnv -> RetryDelay)
-> (BotEnv -> RetryDelay -> BotEnv) -> Lens' BotEnv RetryDelay
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens BotEnv -> RetryDelay
botEnvRetryDelay ((BotEnv -> RetryDelay -> BotEnv) -> Lens' BotEnv RetryDelay)
-> (BotEnv -> RetryDelay -> BotEnv) -> Lens' BotEnv RetryDelay
forall a b. (a -> b) -> a -> b
$ \BotEnv
x RetryDelay
v → BotEnv
x { botEnvRetryDelay = v }
instance BotJobsQueue.HasBotJobsReader BotEnv where
botJobsReader :: Getter BotEnv (STM BotJob)
botJobsReader = (BotEnv -> BotJobsQueue)
-> (BotJobsQueue -> f BotJobsQueue) -> BotEnv -> f BotEnv
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
Lens.to BotEnv -> BotJobsQueue
botEnvJobsQueue ((BotJobsQueue -> f BotJobsQueue) -> BotEnv -> f BotEnv)
-> ((STM BotJob -> f (STM BotJob))
-> BotJobsQueue -> f BotJobsQueue)
-> (STM BotJob -> f (STM BotJob))
-> BotEnv
-> f BotEnv
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (STM BotJob -> f (STM BotJob)) -> BotJobsQueue -> f BotJobsQueue
forall r. HasBotJobsReader r => Getter r (STM BotJob)
Getter BotJobsQueue (STM BotJob)
BotJobsQueue.botJobsReader
instance BotJobsQueue.HasBotJobsWriter BotEnv where
botJobsWriter :: Getter BotEnv (BotJob -> STM ())
botJobsWriter = (BotEnv -> BotJobsQueue)
-> (BotJobsQueue -> f BotJobsQueue) -> BotEnv -> f BotEnv
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
Lens.to BotEnv -> BotJobsQueue
botEnvJobsQueue ((BotJobsQueue -> f BotJobsQueue) -> BotEnv -> f BotEnv)
-> (((BotJob -> STM ()) -> f (BotJob -> STM ()))
-> BotJobsQueue -> f BotJobsQueue)
-> ((BotJob -> STM ()) -> f (BotJob -> STM ()))
-> BotEnv
-> f BotEnv
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((BotJob -> STM ()) -> f (BotJob -> STM ()))
-> BotJobsQueue -> f BotJobsQueue
forall r. HasBotJobsWriter r => Getter r (BotJob -> STM ())
Getter BotJobsQueue (BotJob -> STM ())
BotJobsQueue.botJobsWriter
data SendMessageResponse = SendMessageResponse
{ SendMessageResponse -> TransactionId
sendMessageResponseTransactionId ∷ T.TransactionId
, SendMessageResponse -> EventResponse
sendMessageResponseResponse ∷ EventResponse
}
deriving stock ((forall x. SendMessageResponse -> Rep SendMessageResponse x)
-> (forall x. Rep SendMessageResponse x -> SendMessageResponse)
-> Generic SendMessageResponse
forall x. Rep SendMessageResponse x -> SendMessageResponse
forall x. SendMessageResponse -> Rep SendMessageResponse x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. SendMessageResponse -> Rep SendMessageResponse x
from :: forall x. SendMessageResponse -> Rep SendMessageResponse x
$cto :: forall x. Rep SendMessageResponse x -> SendMessageResponse
to :: forall x. Rep SendMessageResponse x -> SendMessageResponse
Generic, SendMessageResponse -> SendMessageResponse -> Bool
(SendMessageResponse -> SendMessageResponse -> Bool)
-> (SendMessageResponse -> SendMessageResponse -> Bool)
-> Eq SendMessageResponse
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SendMessageResponse -> SendMessageResponse -> Bool
== :: SendMessageResponse -> SendMessageResponse -> Bool
$c/= :: SendMessageResponse -> SendMessageResponse -> Bool
/= :: SendMessageResponse -> SendMessageResponse -> Bool
Eq, Int -> SendMessageResponse -> String -> String
[SendMessageResponse] -> String -> String
SendMessageResponse -> String
(Int -> SendMessageResponse -> String -> String)
-> (SendMessageResponse -> String)
-> ([SendMessageResponse] -> String -> String)
-> Show SendMessageResponse
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> SendMessageResponse -> String -> String
showsPrec :: Int -> SendMessageResponse -> String -> String
$cshow :: SendMessageResponse -> String
show :: SendMessageResponse -> String
$cshowList :: [SendMessageResponse] -> String -> String
showList :: [SendMessageResponse] -> String -> String
Show)
instance ToJSON SendMessageResponse where toJSON :: SendMessageResponse -> Value
toJSON = SendMessageResponse -> Value
forall a.
(Generic a, Typeable a, GToJSON' Value Zero (Rep a)) =>
a -> Value
myGenericToJSON
instance FromJSON SendMessageResponse where parseJSON :: Value -> Parser SendMessageResponse
parseJSON = Value -> Parser SendMessageResponse
forall a.
(Generic a, Typeable a, GFromJSON Zero (Rep a)) =>
Value -> Parser a
myGenericParseJSON
quoted ∷ (IsString s, Show s) ⇒ s → Text
quoted :: forall s. (IsString s, Show s) => s -> Text
quoted = String -> Text
pack (String -> Text) -> (s -> String) -> s -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> String
forall a. Show a => a -> String
show