Method: Discordrb::Commands::CommandBot#initialize

Defined in:
lib/discordrb/commands/command_bot.rb

#initialize(**attributes) ⇒ CommandBot

Creates a new CommandBot and logs in to Discord.

Parameters:

  • attributes (Hash)

    The attributes to initialize the CommandBot with.

Options Hash (**attributes):

  • :prefix (String, Array<String>, #call)

    The prefix that should trigger this bot's commands. It can be:

    • Any string (including the empty string). This has the effect that if a message starts with the prefix, the prefix will be stripped and the rest of the chain will be parsed as a command chain. Note that it will be literal - if the prefix is "hi" then the corresponding trigger string for a command called "test" would be "hitest". Don't forget to put spaces in if you need them!
    • An array of prefixes. Those will behave similarly to setting one string as a prefix, but instead of only one string, any of the strings in the array can be used.
    • Something Proc-like (responds to :call) that takes a Message object as an argument and returns either the command chain in raw form or nil if the given message shouldn't be parsed. This can be used to make more complicated dynamic prefixes (e. g. based on server), or even something else entirely (suffixes, or most adventurous, infixes).
  • :advanced_functionality (true, false)

    Whether to enable advanced functionality (very powerful way to nest commands into chains, see https://github.com/shardlab/discordrb/wiki/Commands#command-chain-syntax for info. Default is false.

  • :help_command (Symbol, Array<Symbol>, false)

    The name of the command that displays info for other commands. Use an array if you want to have aliases. Default is "help". If none should be created, use false as the value.

  • :command_doesnt_exist_message (String, #call)

    The message that should be displayed if a user attempts to use a command that does not exist. If none is specified, no message will be displayed. In the message, you can use the string '%command%' that will be replaced with the name of the command. Anything responding to call such as a proc will be called with the event, and is expected to return a String or nil.

  • :no_permission_message (String)

    The message to be displayed when NoPermission error is raised.

  • :spaces_allowed (true, false)

    Whether spaces are allowed to occur between the prefix and the command. Default is false.

  • :webhook_commands (true, false)

    Whether messages sent by webhooks are allowed to trigger commands. Default is true.

  • :channels (Array<String, Integer, Channel>)

    The channels this command bot accepts commands on. Superseded if a command has a 'channels' attribute.

  • :previous (String)

    Character that should designate the result of the previous command in a command chain (see :advanced_functionality). Default is '~'. Set to an empty string to disable.

  • :chain_delimiter (String)

    Character that should designate that a new command begins in the command chain (see :advanced_functionality). Default is '>'. Set to an empty string to disable.

  • :chain_args_delim (String)

    Character that should separate the command chain arguments from the chain itself (see :advanced_functionality). Default is ':'. Set to an empty string to disable.

  • :sub_chain_start (String)

    Character that should start a sub-chain (see :advanced_functionality). Default is '['. Set to an empty string to disable.

  • :sub_chain_end (String)

    Character that should end a sub-chain (see :advanced_functionality). Default is ']'. Set to an empty string to disable.

  • :quote_start (String)

    Character that should start a quoted string (see :advanced_functionality). Default is '"'. Set to an empty string to disable.

  • :quote_end (String)

    Character that should end a quoted string (see :advanced_functionality). Default is '"' or the same as :quote_start. Set to an empty string to disable.

  • :ignore_bots (true, false)

    Whether the bot should ignore bot accounts or not. Default is false.

See Also:



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/discordrb/commands/command_bot.rb', line 73

def initialize(**attributes)
  # TODO: This needs to be revisited. undefined attributes are treated
  # as explicitly passed nils.
  super(
    log_mode: attributes[:log_mode],
    token: attributes[:token],
    client_id: attributes[:client_id],
    type: attributes[:type],
    name: attributes[:name],
    fancy_log: attributes[:fancy_log],
    suppress_ready: attributes[:suppress_ready],
    parse_self: attributes[:parse_self],
    shard_id: attributes[:shard_id],
    num_shards: attributes[:num_shards],
    redact_token: attributes.key?(:redact_token) ? attributes[:redact_token] : true,
    ignore_bots: attributes[:ignore_bots],
    compress_mode: attributes[:compress_mode],
    intents: attributes[:intents] || :all
  )

  @prefix = attributes[:prefix]
  @attributes = {
    # Whether advanced functionality such as command chains are enabled
    advanced_functionality: attributes[:advanced_functionality].nil? ? false : attributes[:advanced_functionality],

    # The name of the help command (that displays information to other commands). False if none should exist
    help_command: attributes[:help_command].is_a?(FalseClass) ? nil : (attributes[:help_command] || :help),

    # The message to display for when a command doesn't exist, %command% to get the command name in question and nil for no message
    # No default value here because it may not be desired behaviour
    command_doesnt_exist_message: attributes[:command_doesnt_exist_message],

    # The message to be displayed when `NoPermission` error is raised.
    no_permission_message: attributes[:no_permission_message],

    # Spaces allowed between prefix and command
    spaces_allowed: attributes[:spaces_allowed].nil? ? false : attributes[:spaces_allowed],

    # Webhooks allowed to trigger commands
    webhook_commands: attributes[:webhook_commands].nil? || attributes[:webhook_commands],

    channels: attributes[:channels] || [],

    # All of the following need to be one character
    # String to designate previous result in command chain
    previous: attributes[:previous] || '~',

    # Command chain delimiter
    chain_delimiter: attributes[:chain_delimiter] || '>',

    # Chain argument delimiter
    chain_args_delim: attributes[:chain_args_delim] || ':',

    # Sub-chain starting character
    sub_chain_start: attributes[:sub_chain_start] || '[',

    # Sub-chain ending character
    sub_chain_end: attributes[:sub_chain_end] || ']',

    # Quoted mode starting character
    quote_start: attributes[:quote_start] || '"',

    # Quoted mode ending character
    quote_end: attributes[:quote_end] || attributes[:quote_start] || '"',

    # Default block for handling internal exceptions, or a string to respond with
    rescue: attributes[:rescue]
  }

  @permissions = {
    roles: {},
    users: {}
  }

  return unless @attributes[:help_command]

  command(@attributes[:help_command], max_args: 1, description: 'Shows a list of all the commands available or displays help for a specific command.', usage: 'help [command name]') do |event, command_name|
    if command_name
      command = @commands[command_name.to_sym]
      if command.is_a?(CommandAlias)
        command = command.aliased_command
        command_name = command.name
      end
      # rubocop:disable Lint/ReturnInVoidContext
      return "The command `#{command_name}` does not exist!" unless command
      # rubocop:enable Lint/ReturnInVoidContext

      desc = command.attributes[:description] || '*No description available*'
      usage = command.attributes[:usage]
      parameters = command.attributes[:parameters]
      result = "**`#{command_name}`**: #{desc}"
      aliases = command_aliases(command_name.to_sym)
      unless aliases.empty?
        result += "\nAliases: "
        result += aliases.map { |a| "`#{a.name}`" }.join(', ')
      end
      result += "\nUsage: `#{usage}`" if usage
      if parameters
        result += "\nAccepted Parameters:\n```"
        parameters.each { |p| result += "\n#{p}" }
        result += '```'
      end
      result
    else
      available_commands = @commands.values.reject do |c|
        c.is_a?(CommandAlias) || !c.attributes[:help_available] || !required_roles?(event.user, c.attributes[:required_roles]) || !allowed_roles?(event.user, c.attributes[:allowed_roles]) || !required_permissions?(event.user, c.attributes[:required_permissions], event.channel)
      end
      case available_commands.length
      when 0..5
        available_commands.reduce "**List of commands:**\n" do |memo, c|
          memo + "**`#{c.name}`**: #{c.attributes[:description] || '*No description available*'}\n"
        end
      when 5..50
        (available_commands.reduce "**List of commands:**\n" do |memo, c|
          memo + "`#{c.name}`, "
        end)[0..-3]
      else
        event.user.pm(available_commands.reduce("**List of commands:**\n") { |m, e| m + "`#{e.name}`, " }[0..-3])
        event.channel.pm? ? '' : 'Sending list in PM!'
      end
    end
  end
end