calamity-0.8.0.0: A library for writing discord bots in haskell
Safe HaskellSafe-Inferred
LanguageHaskell2010

Calamity.Commands.Dsl

Contents

Description

A DSL for generating commands and groups

This is effectively just a re-export of CalamityCommands.Dsl but with documentation more tuned for usage with Calamity.

Synopsis

Commands DSL

This module provides a way of constructing bot commands in a declarative way.

The main component of this is the command function, which takes a type-level list of command parameters, the name, and the callback and produces a command. There are also the alternatives command', commandA and commandA', for when you want to handle parsing of the input yourself, and/or want aliases of the command.

The functions: hide, help, requires, and group can be used to change attributes of any commands declared inside the monadic action passed to them, for example:

hide $ do
  command @'[] "test" \ctx -> pure ()

In the above block, any command declared inside hide will have its 'hidden' flag set and will not be shown by the default help command: helpCommand

The helpCommand function can be used to create a help command for the commands DSL action it is used in, read its doc page for more information on how it functions.

The addCommands function creates the command handler for the commands registered in the passed action, it is what reads a message to determine what command was invoked. It should be used to register the commands with the bot by using it inside the setup action, for example:

runBotIO (BotToken token)
  $ addCommands $ do
    helpCommand
    command @'[] "test" \ctx ->
      void $ tell @Text ctx "hi"

The above block will create a command with no parameters named 'test', along with a help command.

command Source #

Arguments

:: forall ps c r. (Member (Final IO) r, DSLC c r, CommandContext IO c (), TypedCommandC ps c () r) 
=> Text

The name of the command

-> (c -> CommandForParsers ps r ())

The callback for this command

-> Sem r (Command c) 

Given the name of a command and a callback, and a type level list of the parameters, build and register a command.

The parent group, visibility, checks, and command help are drawn from the reader context.

Command parameters are parsed by first invoking parse for the first ParameterParser, then running the next parser on the remaining input, and so on.

Examples

Building a command that bans a user by id.

command @'[Named "user" (Snowflake User),
               Named "reason" (KleeneStarConcat Text)]
   "ban" $ \ctx uid r -> case (ctx ^. #guild) of
     Just guild -> do
       void . invoke $ CreateGuildBan guild uid (CreateGuildBanData Nothing $ Just r)
       void $ tell ctx ("Banned user `" <> showt uid <> "` with reason: " <> r)
     Nothing -> void $ tell @Text ctx "Can only ban users from guilds."

command' Source #

Arguments

:: (Member (Final IO) r, DSLC c r) 
=> Text

The name of the command

-> [ParameterInfo]

The command's parameters

-> (c -> Sem r (Either CommandError a))

The parser for this command

-> ((c, a) -> Sem (Fail ': r) ())

The callback for this command

-> Sem r (Command c) 

Given the command name and parameter names, parser and callback for a command in the Sem monad, build a command by transforming the Polysemy actions into IO actions. Then register the command.

The parent group, visibility, checks, and command help are drawn from the reader context.

commandA Source #

Arguments

:: forall ps c r. (Member (Final IO) r, DSLC c r, CommandContext IO c (), TypedCommandC ps c () r) 
=> Text

The name of the command

-> [Text]

The aliases for the command

-> (c -> CommandForParsers ps r ())

The callback for this command

-> Sem r (Command c) 

Given the name and aliases of a command and a callback, and a type level list of the parameters, build and register a command.

The parent group, visibility, checks, and command help are drawn from the reader context.

Examples

Building a command that bans a user by id.

commandA @'[Named "user" (Snowflake User),
               Named "reason" (KleeneStarConcat Text)]
   "ban" [] $ \ctx uid r -> case (ctx ^. #guild) of
     Just guild -> do
       void . invoke $ CreateGuildBan guild uid (CreateGuildBanData Nothing $ Just r)
       void $ tell ctx ("Banned user `" <> showt uid <> "` with reason: " <> r)
     Nothing -> void $ tell @Text ctx "Can only ban users from guilds."

commandA' Source #

Arguments

:: (Member (Final IO) r, DSLC c r) 
=> Text

The name of the command

-> [Text]

The aliases for the command

-> [ParameterInfo]

The command's parameters

-> (c -> Sem r (Either CommandError a))

The parser for this command

-> ((c, a) -> Sem (Fail ': r) ())

The callback for this command

-> Sem r (Command c) 

Given the command name, aliases, and parameter names, parser and callback for a command in the Sem monad, build a command by transforming the Polysemy actions into IO actions. Then register the command.

The parent group, visibility, checks, and command help are drawn from the reader context.

hide :: Member (Tagged "hidden" (Reader Bool)) r => Sem r a -> Sem r a Source #

Set the visibility of any groups or commands registered inside the given action to hidden.

help :: Member (Reader (c -> Text)) r => (c -> Text) -> Sem r a -> Sem r a Source #

Set the help for any groups or commands registered inside the given action.

requires :: DSLC c r => [Check c] -> Sem r a -> Sem r a Source #

Add to the list of checks for any commands registered inside the given action.

requires' Source #

Arguments

:: (Member (Final IO) r, DSLC c r) 
=> Text

The name of the check

-> (c -> Sem r (Maybe Text))

The callback for the check

-> Sem r a 
-> Sem r a 

Construct a check and add it to the list of checks for any commands registered inside the given action.

Refer to Check for more info on checks.

requiresPure :: DSLC c r => [(Text, c -> Maybe Text)] -> Sem r a -> Sem r a Source #

Construct some pure checks and add them to the list of checks for any commands registered inside the given action.

Refer to Check for more info on checks.

group Source #

Arguments

:: (Member (Final IO) r, DSLC c r) 
=> Text

The name of the group

-> Sem r a 
-> Sem r a 

Construct a group and place any commands registered in the given action into the new group.

This also resets the help function back to its original value, use group' if you don't want that (i.e. your help function is context aware).

group' Source #

Arguments

:: (Member (Final IO) r, DSLC c r) 
=> Text

The name of the group

-> Sem r a 
-> Sem r a 

Construct a group and place any commands registered in the given action into the new group.

The parent group, visibility, checks, and command help are drawn from the reader context.

Unlike help this doesn't reset the help function back to its original value.

groupA Source #

Arguments

:: (Member (Final IO) r, DSLC c r) 
=> Text

The name of the group

-> [Text]

The aliases of the group

-> Sem r a 
-> Sem r a 

Construct a group with aliases and place any commands registered in the given action into the new group.

The parent group, visibility, checks, and command help are drawn from the reader context.

This also resets the help function back to its original value, use group' if you don't want that (i.e. your help function is context aware).

groupA' Source #

Arguments

:: (Member (Final IO) r, DSLC c r) 
=> Text

The name of the group

-> [Text]

The aliases of the group

-> Sem r a 
-> Sem r a 

Construct a group with aliases and place any commands registered in the given action into the new group.

The parent group, visibility, checks, and command help are drawn from the reader context.

Unlike help this doesn't reset the help function back to its original value.

type DSLState c r = DSLState IO c () r Source #

fetchHandler :: DSLC c r => Sem r (CommandHandler c) Source #

Retrieve the final command handler for this block