discorb 0.13.4 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitattributes +2 -0
- data/.github/workflows/codeql-analysis.yml +70 -0
- data/.github/workflows/lint-push.yml +18 -0
- data/.github/workflows/lint.yml +16 -0
- data/.rubocop.yml +70 -0
- data/Changelog.md +12 -0
- data/Gemfile +7 -3
- data/Rakefile +22 -22
- data/discorb.gemspec +1 -0
- data/examples/commands/bookmarker.rb +2 -1
- data/examples/commands/hello.rb +1 -0
- data/examples/commands/inspect.rb +3 -2
- data/examples/components/authorization_button.rb +2 -1
- data/examples/components/select_menu.rb +2 -1
- data/examples/extension/main.rb +1 -0
- data/examples/extension/message_expander.rb +1 -0
- data/examples/simple/eval.rb +3 -2
- data/examples/simple/ping_pong.rb +1 -0
- data/examples/simple/rolepanel.rb +1 -0
- data/examples/simple/wait_for_message.rb +4 -3
- data/exe/discorb +8 -7
- data/lib/discorb/allowed_mentions.rb +64 -0
- data/lib/discorb/app_command/command.rb +274 -0
- data/lib/discorb/app_command/handler.rb +168 -0
- data/lib/discorb/app_command.rb +2 -426
- data/lib/discorb/asset.rb +2 -0
- data/lib/discorb/audit_logs.rb +3 -3
- data/lib/discorb/channel.rb +19 -4
- data/lib/discorb/client.rb +30 -27
- data/lib/discorb/common.rb +4 -26
- data/lib/discorb/components/button.rb +106 -0
- data/lib/discorb/components/select_menu.rb +157 -0
- data/lib/discorb/components/text_input.rb +96 -0
- data/lib/discorb/components.rb +11 -276
- data/lib/discorb/dictionary.rb +3 -0
- data/lib/discorb/embed.rb +2 -2
- data/lib/discorb/emoji.rb +19 -3
- data/lib/discorb/emoji_table.rb +1 -1
- data/lib/discorb/error.rb +4 -6
- data/lib/discorb/event.rb +9 -7
- data/lib/discorb/exe/about.rb +1 -0
- data/lib/discorb/exe/irb.rb +4 -3
- data/lib/discorb/exe/new.rb +6 -7
- data/lib/discorb/exe/run.rb +2 -1
- data/lib/discorb/exe/setup.rb +8 -5
- data/lib/discorb/exe/show.rb +1 -0
- data/lib/discorb/extend.rb +19 -14
- data/lib/discorb/extension.rb +5 -1
- data/lib/discorb/gateway.rb +28 -30
- data/lib/discorb/guild.rb +11 -13
- data/lib/discorb/guild_template.rb +2 -2
- data/lib/discorb/http.rb +15 -17
- data/lib/discorb/integration.rb +1 -1
- data/lib/discorb/intents.rb +1 -1
- data/lib/discorb/interaction/autocomplete.rb +4 -3
- data/lib/discorb/interaction/command.rb +34 -9
- data/lib/discorb/interaction/components.rb +5 -2
- data/lib/discorb/interaction/modal.rb +33 -0
- data/lib/discorb/interaction/response.rb +33 -4
- data/lib/discorb/interaction/root.rb +1 -0
- data/lib/discorb/interaction.rb +2 -1
- data/lib/discorb/log.rb +1 -1
- data/lib/discorb/member.rb +1 -3
- data/lib/discorb/message.rb +26 -277
- data/lib/discorb/message_meta.rb +205 -0
- data/lib/discorb/modules.rb +1 -1
- data/lib/discorb/permission.rb +2 -2
- data/lib/discorb/presence.rb +4 -1
- data/lib/discorb/rate_limit.rb +2 -4
- data/lib/discorb/user.rb +1 -1
- data/lib/discorb/utils/colored_puts.rb +1 -0
- data/lib/discorb/voice_state.rb +3 -0
- data/lib/discorb/webhook.rb +1 -1
- data/lib/discorb.rb +1 -0
- data/template-replace/scripts/arrow.rb +1 -0
- data/template-replace/scripts/favicon.rb +1 -0
- data/template-replace/scripts/index.rb +2 -1
- data/template-replace/scripts/locale_ja.rb +5 -4
- data/template-replace/scripts/sidebar.rb +1 -0
- data/template-replace/scripts/version.rb +7 -10
- data/template-replace/scripts/yard_replace.rb +5 -4
- metadata +16 -2
    
        data/lib/discorb/components.rb
    CHANGED
    
    | @@ -22,23 +22,12 @@ module Discorb | |
| 22 22 | 
             
                  def from_hash(data)
         | 
| 23 23 | 
             
                    case data[:type]
         | 
| 24 24 | 
             
                    when 2
         | 
| 25 | 
            -
                      Button | 
| 26 | 
            -
                        data[:label],
         | 
| 27 | 
            -
                        data[:style],
         | 
| 28 | 
            -
                        emoji: data[:emoji],
         | 
| 29 | 
            -
                        custom_id: data[:custom_id],
         | 
| 30 | 
            -
                        url: data[:url],
         | 
| 31 | 
            -
                        disabled: data[:disabled],
         | 
| 32 | 
            -
                      )
         | 
| 25 | 
            +
                      Button
         | 
| 33 26 | 
             
                    when 3
         | 
| 34 | 
            -
                      SelectMenu | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
                        min_values: data[:min_values],
         | 
| 39 | 
            -
                        max_values: data[:max_values],
         | 
| 40 | 
            -
                      )
         | 
| 41 | 
            -
                    end
         | 
| 27 | 
            +
                      SelectMenu
         | 
| 28 | 
            +
                    when 4
         | 
| 29 | 
            +
                      TextInput
         | 
| 30 | 
            +
                    end.from_hash(data)
         | 
| 42 31 | 
             
                  end
         | 
| 43 32 |  | 
| 44 33 | 
             
                  #
         | 
| @@ -57,7 +46,7 @@ module Discorb | |
| 57 46 | 
             
                        tmp_components << tmp_row
         | 
| 58 47 | 
             
                        tmp_row = []
         | 
| 59 48 | 
             
                        tmp_components << c
         | 
| 60 | 
            -
                      when SelectMenu
         | 
| 49 | 
            +
                      when SelectMenu, TextInput
         | 
| 61 50 | 
             
                        tmp_components << tmp_row
         | 
| 62 51 | 
             
                        tmp_row = []
         | 
| 63 52 | 
             
                        tmp_components << [c]
         | 
| @@ -66,266 +55,12 @@ module Discorb | |
| 66 55 | 
             
                      end
         | 
| 67 56 | 
             
                    end
         | 
| 68 57 | 
             
                    tmp_components << tmp_row
         | 
| 69 | 
            -
                     | 
| 70 | 
            -
                  end
         | 
| 71 | 
            -
                end
         | 
| 72 | 
            -
              end
         | 
| 73 | 
            -
             | 
| 74 | 
            -
              #
         | 
| 75 | 
            -
              # Represents a button component.
         | 
| 76 | 
            -
              #
         | 
| 77 | 
            -
              class Button < Component
         | 
| 78 | 
            -
                # @return [String] The label of the button.
         | 
| 79 | 
            -
                attr_accessor :label
         | 
| 80 | 
            -
                # @return [:primary, :secondary, :success, :danger, :link] The style of the button.
         | 
| 81 | 
            -
                attr_accessor :style
         | 
| 82 | 
            -
                # @return [Discorb::Emoji] The emoji of the button.
         | 
| 83 | 
            -
                attr_accessor :emoji
         | 
| 84 | 
            -
                # @return [String] The custom ID of the button.
         | 
| 85 | 
            -
                #   Won't be used if the style is `:link`.
         | 
| 86 | 
            -
                attr_accessor :custom_id
         | 
| 87 | 
            -
                # @return [String] The URL of the button.
         | 
| 88 | 
            -
                #   Only used when the style is `:link`.
         | 
| 89 | 
            -
                attr_accessor :url
         | 
| 90 | 
            -
                # @return [Boolean] Whether the button is disabled.
         | 
| 91 | 
            -
                attr_accessor :disabled
         | 
| 92 | 
            -
                alias disabled? disabled
         | 
| 93 | 
            -
             | 
| 94 | 
            -
                @styles = {
         | 
| 95 | 
            -
                  primary: 1,
         | 
| 96 | 
            -
                  secondary: 2,
         | 
| 97 | 
            -
                  success: 3,
         | 
| 98 | 
            -
                  danger: 4,
         | 
| 99 | 
            -
                  link: 5,
         | 
| 100 | 
            -
                }.freeze
         | 
| 101 | 
            -
             | 
| 102 | 
            -
                #
         | 
| 103 | 
            -
                # Initialize a new button.
         | 
| 104 | 
            -
                #
         | 
| 105 | 
            -
                # @param [String] label The label of the button.
         | 
| 106 | 
            -
                # @param [:primary, :secondary, :success, :danger, :link] style The style of the button.
         | 
| 107 | 
            -
                # @param [Discorb::Emoji] emoji The emoji of the button.
         | 
| 108 | 
            -
                # @param [String] custom_id The custom ID of the button.
         | 
| 109 | 
            -
                # @param [String] url The URL of the button.
         | 
| 110 | 
            -
                # @param [Boolean] disabled Whether the button is disabled.
         | 
| 111 | 
            -
                #
         | 
| 112 | 
            -
                def initialize(label, style = :primary, emoji: nil, custom_id: nil, url: nil, disabled: false)
         | 
| 113 | 
            -
                  @label = label
         | 
| 114 | 
            -
                  @style = style
         | 
| 115 | 
            -
                  @emoji = emoji
         | 
| 116 | 
            -
                  @custom_id = custom_id
         | 
| 117 | 
            -
                  @url = url
         | 
| 118 | 
            -
                  @disabled = disabled
         | 
| 119 | 
            -
                end
         | 
| 120 | 
            -
             | 
| 121 | 
            -
                #
         | 
| 122 | 
            -
                # Converts the button to a hash.
         | 
| 123 | 
            -
                #
         | 
| 124 | 
            -
                # @see https://discord.com/developers/docs/interactions/message-components#button-object-button-structure Official Discord API docs
         | 
| 125 | 
            -
                # @return [Hash] A hash representation of the button.
         | 
| 126 | 
            -
                #
         | 
| 127 | 
            -
                def to_hash
         | 
| 128 | 
            -
                  if @style == :link
         | 
| 129 | 
            -
                    {
         | 
| 130 | 
            -
                      type: 2,
         | 
| 131 | 
            -
                      label: @label,
         | 
| 132 | 
            -
                      style: self.class.styles[@style],
         | 
| 133 | 
            -
                      url: @url,
         | 
| 134 | 
            -
                      emoji: hash_emoji(@emoji),
         | 
| 135 | 
            -
                      disabled: @disabled,
         | 
| 136 | 
            -
                    }
         | 
| 137 | 
            -
                  else
         | 
| 138 | 
            -
                    {
         | 
| 139 | 
            -
                      type: 2,
         | 
| 140 | 
            -
                      label: @label,
         | 
| 141 | 
            -
                      style: self.class.styles[@style],
         | 
| 142 | 
            -
                      custom_id: @custom_id,
         | 
| 143 | 
            -
                      emoji: hash_emoji(@emoji),
         | 
| 144 | 
            -
                      disabled: @disabled,
         | 
| 145 | 
            -
                    }
         | 
| 146 | 
            -
                  end
         | 
| 147 | 
            -
                end
         | 
| 148 | 
            -
             | 
| 149 | 
            -
                def inspect
         | 
| 150 | 
            -
                  "#<#{self.class}: #{@custom_id || @url}>"
         | 
| 151 | 
            -
                end
         | 
| 152 | 
            -
             | 
| 153 | 
            -
                class << self
         | 
| 154 | 
            -
                  # @private
         | 
| 155 | 
            -
                  attr_reader :styles
         | 
| 156 | 
            -
                end
         | 
| 157 | 
            -
             | 
| 158 | 
            -
                private
         | 
| 159 | 
            -
             | 
| 160 | 
            -
                def hash_emoji(emoji)
         | 
| 161 | 
            -
                  case emoji
         | 
| 162 | 
            -
                  when UnicodeEmoji
         | 
| 163 | 
            -
                    {
         | 
| 164 | 
            -
                      id: nil,
         | 
| 165 | 
            -
                      name: emoji.to_s,
         | 
| 166 | 
            -
                      animated: false,
         | 
| 167 | 
            -
                    }
         | 
| 168 | 
            -
                  when CustomEmoji
         | 
| 169 | 
            -
                    {
         | 
| 170 | 
            -
                      id: emoji.id,
         | 
| 171 | 
            -
                      name: emoji.name,
         | 
| 172 | 
            -
                      animated: emoji.animated?,
         | 
| 173 | 
            -
                    }
         | 
| 174 | 
            -
                  end
         | 
| 175 | 
            -
                end
         | 
| 176 | 
            -
              end
         | 
| 177 | 
            -
             | 
| 178 | 
            -
              #
         | 
| 179 | 
            -
              # Represents a select menu component.
         | 
| 180 | 
            -
              #
         | 
| 181 | 
            -
              class SelectMenu < Component
         | 
| 182 | 
            -
                # @return [String] The custom ID of the select menu.
         | 
| 183 | 
            -
                attr_accessor :custom_id
         | 
| 184 | 
            -
                # @return [Array<SelectMenu::Option>] The options of the select menu.
         | 
| 185 | 
            -
                attr_accessor :options
         | 
| 186 | 
            -
                # @return [Integer] The minimum number of values.
         | 
| 187 | 
            -
                attr_accessor :min_values
         | 
| 188 | 
            -
                # @return [Integer] The maximum number of values.
         | 
| 189 | 
            -
                attr_accessor :max_values
         | 
| 190 | 
            -
                # @return [Boolean] Whether the select menu is disabled.
         | 
| 191 | 
            -
                attr_accessor :disabled
         | 
| 192 | 
            -
                alias disabled? disabled
         | 
| 193 | 
            -
             | 
| 194 | 
            -
                #
         | 
| 195 | 
            -
                # Initialize a new select menu.
         | 
| 196 | 
            -
                #
         | 
| 197 | 
            -
                # @param [String, Symbol] custom_id Custom ID of the select menu.
         | 
| 198 | 
            -
                # @param [Array<Discorb::SelectMenu::Option>] options The options of the select menu.
         | 
| 199 | 
            -
                # @param [String] placeholder The placeholder of the select menu.
         | 
| 200 | 
            -
                # @param [Integer] min_values The minimum number of values.
         | 
| 201 | 
            -
                # @param [Integer] max_values The maximum number of values.
         | 
| 202 | 
            -
                #
         | 
| 203 | 
            -
                def initialize(custom_id, options, placeholder: nil, min_values: 1, max_values: 1)
         | 
| 204 | 
            -
                  @custom_id = custom_id
         | 
| 205 | 
            -
                  @options = options
         | 
| 206 | 
            -
                  @placeholder = placeholder
         | 
| 207 | 
            -
                  @min_values = min_values
         | 
| 208 | 
            -
                  @max_values = max_values
         | 
| 209 | 
            -
                end
         | 
| 210 | 
            -
             | 
| 211 | 
            -
                #
         | 
| 212 | 
            -
                # Converts the select menu to a hash.
         | 
| 213 | 
            -
                #
         | 
| 214 | 
            -
                # @see https://discord.com/developers/docs/interactions/message-components#select-menu-object-select-menu-structure Official Discord API docs
         | 
| 215 | 
            -
                # @return [Hash] A hash representation of the select menu.
         | 
| 216 | 
            -
                #
         | 
| 217 | 
            -
                def to_hash
         | 
| 218 | 
            -
                  {
         | 
| 219 | 
            -
                    type: 3,
         | 
| 220 | 
            -
                    custom_id: @custom_id,
         | 
| 221 | 
            -
                    options: @options.map(&:to_hash),
         | 
| 222 | 
            -
                    placeholder: @placeholder,
         | 
| 223 | 
            -
                    min_values: @min_values,
         | 
| 224 | 
            -
                    max_values: @max_values,
         | 
| 225 | 
            -
                    disabled: @disabled,
         | 
| 226 | 
            -
                  }
         | 
| 227 | 
            -
                end
         | 
| 228 | 
            -
             | 
| 229 | 
            -
                def inspect
         | 
| 230 | 
            -
                  "#<#{self.class}: #{@custom_id}>"
         | 
| 231 | 
            -
                end
         | 
| 232 | 
            -
             | 
| 233 | 
            -
                #
         | 
| 234 | 
            -
                # Represents an option of a select menu.
         | 
| 235 | 
            -
                #
         | 
| 236 | 
            -
                class Option
         | 
| 237 | 
            -
                  # @return [String] The label of the option.
         | 
| 238 | 
            -
                  attr_accessor :label
         | 
| 239 | 
            -
                  # @return [String] The value of the option.
         | 
| 240 | 
            -
                  attr_accessor :value
         | 
| 241 | 
            -
                  # @return [String] The description of the option.
         | 
| 242 | 
            -
                  attr_accessor :description
         | 
| 243 | 
            -
                  # @return [Discorb::Emoji] The emoji of the option.
         | 
| 244 | 
            -
                  attr_accessor :emoji
         | 
| 245 | 
            -
                  # @return [Boolean] Whether the option is default.
         | 
| 246 | 
            -
                  attr_accessor :default
         | 
| 247 | 
            -
             | 
| 248 | 
            -
                  #
         | 
| 249 | 
            -
                  # Initialize a new option.
         | 
| 250 | 
            -
                  #
         | 
| 251 | 
            -
                  # @param [String] label The label of the option.
         | 
| 252 | 
            -
                  # @param [String] value The value of the option.
         | 
| 253 | 
            -
                  # @param [String] description The description of the option.
         | 
| 254 | 
            -
                  # @param [Discorb::Emoji] emoji The emoji of the option.
         | 
| 255 | 
            -
                  # @param [Boolean] default Whether the option is default.
         | 
| 256 | 
            -
                  def initialize(label, value, description: nil, emoji: nil, default: false)
         | 
| 257 | 
            -
                    @label = label
         | 
| 258 | 
            -
                    @value = value
         | 
| 259 | 
            -
                    @description = description
         | 
| 260 | 
            -
                    @emoji = emoji
         | 
| 261 | 
            -
                    @default = default
         | 
| 262 | 
            -
                  end
         | 
| 263 | 
            -
             | 
| 264 | 
            -
                  #
         | 
| 265 | 
            -
                  # Converts the option to a hash.
         | 
| 266 | 
            -
                  #
         | 
| 267 | 
            -
                  # @see https://discord.com/developers/docs/interactions/message-components#select-menu-object-select-option-structure Official Discord API docs
         | 
| 268 | 
            -
                  # @return [Hash] Hash representation of the option.
         | 
| 269 | 
            -
                  #
         | 
| 270 | 
            -
                  def to_hash
         | 
| 271 | 
            -
                    {
         | 
| 272 | 
            -
                      label: @label,
         | 
| 273 | 
            -
                      value: @value,
         | 
| 274 | 
            -
                      description: @description,
         | 
| 275 | 
            -
                      emoji: hash_emoji(@emoji),
         | 
| 276 | 
            -
                      default: @default,
         | 
| 277 | 
            -
                    }
         | 
| 278 | 
            -
                  end
         | 
| 279 | 
            -
             | 
| 280 | 
            -
                  # @private
         | 
| 281 | 
            -
                  def hash_emoji(emoji)
         | 
| 282 | 
            -
                    case emoji
         | 
| 283 | 
            -
                    when UnicodeEmoji
         | 
| 284 | 
            -
                      {
         | 
| 285 | 
            -
                        id: nil,
         | 
| 286 | 
            -
                        name: emoji.to_s,
         | 
| 287 | 
            -
                        animated: false,
         | 
| 288 | 
            -
                      }
         | 
| 289 | 
            -
                    when CustomEmoji
         | 
| 290 | 
            -
                      {
         | 
| 291 | 
            -
                        id: emoji.id,
         | 
| 292 | 
            -
                        name: emoji.name,
         | 
| 293 | 
            -
                        animated: emoji.animated?,
         | 
| 294 | 
            -
                      }
         | 
| 295 | 
            -
                    end
         | 
| 296 | 
            -
                  end
         | 
| 297 | 
            -
             | 
| 298 | 
            -
                  class << self
         | 
| 299 | 
            -
                    #
         | 
| 300 | 
            -
                    # Creates a new option from a hash.
         | 
| 301 | 
            -
                    #
         | 
| 302 | 
            -
                    # @param [Hash] data A hash representing the option.
         | 
| 303 | 
            -
                    #
         | 
| 304 | 
            -
                    # @return [Discorb::SelectMenu::Option] A new option.
         | 
| 305 | 
            -
                    #
         | 
| 306 | 
            -
                    def from_hash(data)
         | 
| 307 | 
            -
                      new(data[:label], data[:value], description: data[:description], emoji: data[:emoji], default: data[:default])
         | 
| 308 | 
            -
                    end
         | 
| 309 | 
            -
                  end
         | 
| 310 | 
            -
                end
         | 
| 311 | 
            -
             | 
| 312 | 
            -
                private
         | 
| 313 | 
            -
             | 
| 314 | 
            -
                def hash_emoji(emoji)
         | 
| 315 | 
            -
                  case emoji
         | 
| 316 | 
            -
                  when UnicodeEmoji
         | 
| 317 | 
            -
                    {
         | 
| 318 | 
            -
                      id: nil,
         | 
| 319 | 
            -
                      name: emoji.to_s,
         | 
| 320 | 
            -
                      animated: false,
         | 
| 321 | 
            -
                    }
         | 
| 322 | 
            -
                  when CustomEmoji
         | 
| 323 | 
            -
                    {
         | 
| 324 | 
            -
                      id: emoji.id,
         | 
| 325 | 
            -
                      name: emoji.name,
         | 
| 326 | 
            -
                      animated: emoji.animated?,
         | 
| 327 | 
            -
                    }
         | 
| 58 | 
            +
                    tmp_components.filter { |c| c.length.positive? }.map { |c| { type: 1, components: c.map(&:to_hash) } }
         | 
| 328 59 | 
             
                  end
         | 
| 329 60 | 
             
                end
         | 
| 330 61 | 
             
              end
         | 
| 331 62 | 
             
            end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
            %w[button text_input select_menu].each do |name|
         | 
| 65 | 
            +
              require_relative "components/#{name}"
         | 
| 66 | 
            +
            end
         | 
    
        data/lib/discorb/dictionary.rb
    CHANGED
    
    
    
        data/lib/discorb/embed.rb
    CHANGED
    
    | @@ -79,11 +79,11 @@ module Discorb | |
| 79 79 | 
             
                end
         | 
| 80 80 |  | 
| 81 81 | 
             
                def image=(value)
         | 
| 82 | 
            -
                  @image =  | 
| 82 | 
            +
                  @image = value.is_a?(String) ? Image.new(value) : value
         | 
| 83 83 | 
             
                end
         | 
| 84 84 |  | 
| 85 85 | 
             
                def thumbnail=(value)
         | 
| 86 | 
            -
                  @thumbnail =  | 
| 86 | 
            +
                  @thumbnail = value.is_a?(String) ? Thumbnail.new(value) : value
         | 
| 87 87 | 
             
                end
         | 
| 88 88 |  | 
| 89 89 | 
             
                def inspect
         | 
    
        data/lib/discorb/emoji.rb
    CHANGED
    
    | @@ -121,6 +121,15 @@ module Discorb | |
| 121 121 |  | 
| 122 122 | 
             
                alias destroy! delete!
         | 
| 123 123 |  | 
| 124 | 
            +
                # @private
         | 
| 125 | 
            +
                def to_hash
         | 
| 126 | 
            +
                  {
         | 
| 127 | 
            +
                    name: @name,
         | 
| 128 | 
            +
                    id: @id,
         | 
| 129 | 
            +
                    animated: @animated,
         | 
| 130 | 
            +
                  }
         | 
| 131 | 
            +
                end
         | 
| 132 | 
            +
             | 
| 124 133 | 
             
                private
         | 
| 125 134 |  | 
| 126 135 | 
             
                def _set_data(data)
         | 
| @@ -202,9 +211,7 @@ module Discorb | |
| 202 211 | 
             
                  else
         | 
| 203 212 | 
             
                    raise ArgumentError, "No such emoji: #{name}"
         | 
| 204 213 | 
             
                  end
         | 
| 205 | 
            -
                   | 
| 206 | 
            -
                    @value += EmojiTable::SKIN_TONES[tone]
         | 
| 207 | 
            -
                  end
         | 
| 214 | 
            +
                  @value += EmojiTable::SKIN_TONES[tone] if tone.positive?
         | 
| 208 215 | 
             
                end
         | 
| 209 216 |  | 
| 210 217 | 
             
                # @return [String] The unicode string of the emoji.
         | 
| @@ -225,6 +232,15 @@ module Discorb | |
| 225 232 | 
             
                  "#<#{self.class} :#{@name}:>"
         | 
| 226 233 | 
             
                end
         | 
| 227 234 |  | 
| 235 | 
            +
                # @private
         | 
| 236 | 
            +
                def to_hash
         | 
| 237 | 
            +
                  {
         | 
| 238 | 
            +
                    name: @value,
         | 
| 239 | 
            +
                    id: nil,
         | 
| 240 | 
            +
                    animated: false,
         | 
| 241 | 
            +
                  }
         | 
| 242 | 
            +
                end
         | 
| 243 | 
            +
             | 
| 228 244 | 
             
                class << self
         | 
| 229 245 | 
             
                  alias [] new
         | 
| 230 246 | 
             
                end
         | 
    
        data/lib/discorb/emoji_table.rb
    CHANGED
    
    
    
        data/lib/discorb/error.rb
    CHANGED
    
    | @@ -11,9 +11,7 @@ module Discorb | |
| 11 11 | 
             
                def enumerate_errors(hash)
         | 
| 12 12 | 
             
                  res = {}
         | 
| 13 13 | 
             
                  _recr_items([], hash, res)
         | 
| 14 | 
            -
                  if res == { "" => nil }
         | 
| 15 | 
            -
                    res = {}
         | 
| 16 | 
            -
                  end
         | 
| 14 | 
            +
                  res = {} if res == { "" => nil }
         | 
| 17 15 | 
             
                  res
         | 
| 18 16 | 
             
                end
         | 
| 19 17 |  | 
| @@ -64,7 +62,7 @@ module Discorb | |
| 64 62 | 
             
                    [
         | 
| 65 63 | 
             
                      data[:message] + " (#{@code})", enumerate_errors(data[:errors])
         | 
| 66 64 | 
             
                        .map { |ek, ev| "#{ek}=>#{ev}" }
         | 
| 67 | 
            -
                        .join("\n") | 
| 65 | 
            +
                        .join("\n")
         | 
| 68 66 | 
             
                    ].join("\n")
         | 
| 69 67 | 
             
                  )
         | 
| 70 68 | 
             
                end
         | 
| @@ -92,14 +90,14 @@ module Discorb | |
| 92 90 | 
             
              # Represents a error because of a cloudflare ban.
         | 
| 93 91 | 
             
              #
         | 
| 94 92 | 
             
              class CloudFlareBanError < HTTPError
         | 
| 95 | 
            -
                def initialize( | 
| 93 | 
            +
                def initialize(_resp, client)
         | 
| 96 94 | 
             
                  @client = client
         | 
| 97 95 | 
             
                  @client.close!
         | 
| 98 96 | 
             
                  message = <<~MESSAGE
         | 
| 99 97 | 
             
                    The client is banned from CloudFlare.
         | 
| 100 98 | 
             
                    Hint: Try to decrease the number of requests per second, e.g. Use sleep in between requests.
         | 
| 101 99 | 
             
                  MESSAGE
         | 
| 102 | 
            -
                   | 
| 100 | 
            +
                  warn message
         | 
| 103 101 | 
             
                  DiscorbError.instance_method(:initialize).bind(self).call(message)
         | 
| 104 102 | 
             
                end
         | 
| 105 103 | 
             
              end
         | 
    
        data/lib/discorb/event.rb
    CHANGED
    
    | @@ -1,4 +1,8 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 1 2 | 
             
            module Discorb
         | 
| 3 | 
            +
              #
         | 
| 4 | 
            +
              # Represents an event in guild.
         | 
| 5 | 
            +
              #
         | 
| 2 6 | 
             
              class ScheduledEvent < DiscordModel
         | 
| 3 7 | 
             
                @privacy_level = {
         | 
| 4 8 | 
             
                  2 => :guild_only,
         | 
| @@ -120,7 +124,7 @@ module Discorb | |
| 120 124 | 
             
                  status: Discorb::Unset
         | 
| 121 125 | 
             
                )
         | 
| 122 126 | 
             
                  Async do
         | 
| 123 | 
            -
                    payload = case  | 
| 127 | 
            +
                    payload = case type == Discorb::Unset ? @entity_type : type
         | 
| 124 128 | 
             
                      when :stage_instance
         | 
| 125 129 | 
             
                        raise ArgumentError, "channel must be provided for stage_instance events" unless channel
         | 
| 126 130 | 
             
                        {
         | 
| @@ -226,11 +230,9 @@ module Discorb | |
| 226 230 | 
             
                    if limit.nil?
         | 
| 227 231 | 
             
                      after = 0
         | 
| 228 232 | 
             
                      res = []
         | 
| 229 | 
            -
                       | 
| 233 | 
            +
                      loop do
         | 
| 230 234 | 
             
                        _resp, users = @client.http.request(Route.new("/guilds/#{@guild_id}/scheduled-events/#{@id}/users?limit=100&after=#{after}&with_member=true", "//guilds/:guild_id/scheduled-events/:scheduled_event_id/users", :get)).wait
         | 
| 231 | 
            -
                        if users.empty?
         | 
| 232 | 
            -
                          break
         | 
| 233 | 
            -
                        end
         | 
| 235 | 
            +
                        break if users.empty?
         | 
| 234 236 | 
             
                        res += users.map { |u| Member.new(@client, @guild_id, u[:user], u[:member]) }
         | 
| 235 237 | 
             
                        after = users.last[:user][:id]
         | 
| 236 238 | 
             
                      end
         | 
| @@ -238,8 +240,8 @@ module Discorb | |
| 238 240 | 
             
                    else
         | 
| 239 241 | 
             
                      params = {
         | 
| 240 242 | 
             
                        limit: limit,
         | 
| 241 | 
            -
                        before: Discorb::Utils.try( | 
| 242 | 
            -
                        after: Discorb::Utils.try( | 
| 243 | 
            +
                        before: Discorb::Utils.try(before, :id),
         | 
| 244 | 
            +
                        after: Discorb::Utils.try(after, :id),
         | 
| 243 245 | 
             
                        with_member: with_member,
         | 
| 244 246 | 
             
                      }.filter { |_k, v| !v.nil? }.to_h
         | 
| 245 247 | 
             
                      _resp, messages = @client.http.request(Route.new("/channels/#{channel_id.wait}/messages?#{URI.encode_www_form(params)}", "//channels/:channel_id/messages", :get)).wait
         | 
    
        data/lib/discorb/exe/about.rb
    CHANGED
    
    
    
        data/lib/discorb/exe/irb.rb
    CHANGED
    
    | @@ -1,4 +1,5 @@ | |
| 1 1 | 
             
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
            # frozen_string_literal: true
         | 
| 2 3 |  | 
| 3 4 | 
             
            # description: Connect to discord and start IRB.
         | 
| 4 5 |  | 
| @@ -31,13 +32,13 @@ client.on :standby do | |
| 31 32 | 
             
              end
         | 
| 32 33 |  | 
| 33 34 | 
             
              def dirb_help
         | 
| 34 | 
            -
                puts <<~ | 
| 35 | 
            +
                puts <<~MESSAGE
         | 
| 35 36 | 
             
                       \e[96mDiscord-IRB\e[m
         | 
| 36 37 | 
             
                       This is a debug client for Discord.
         | 
| 37 38 | 
             
                       \e[90mmessage\e[m to get latest message.
         | 
| 38 39 |  | 
| 39 40 | 
             
                       \e[36mhttps://discorb-lib.github.io/#{Discorb::VERSION}/file.irb.html\e[m for more information.
         | 
| 40 | 
            -
                      | 
| 41 | 
            +
                     MESSAGE
         | 
| 41 42 | 
             
              end
         | 
| 42 43 |  | 
| 43 44 | 
             
              puts <<~FIRST_MESSAGE
         | 
| @@ -56,7 +57,7 @@ end | |
| 56 57 |  | 
| 57 58 | 
             
            token = ENV["DISCORD_BOT_TOKEN"] || ENV["DISCORD_TOKEN"]
         | 
| 58 59 | 
             
            if token.nil?
         | 
| 59 | 
            -
              if File. | 
| 60 | 
            +
              if File.exist?(token_file)
         | 
| 60 61 | 
             
                token = File.read(token_file)
         | 
| 61 62 | 
             
              else
         | 
| 62 63 | 
             
                print "\e[90mToken?\e[m : "
         | 
    
        data/lib/discorb/exe/new.rb
    CHANGED
    
    | @@ -1,3 +1,4 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 1 2 | 
             
            # description: Make files for the discorb project.
         | 
| 2 3 |  | 
| 3 4 | 
             
            require "optparse"
         | 
| @@ -131,7 +132,7 @@ FILES = { | |
| 131 132 | 
             
                  https://rubygems.org/gems/license-cli may be useful.
         | 
| 132 133 |  | 
| 133 134 | 
             
              MARKDOWN
         | 
| 134 | 
            -
            }
         | 
| 135 | 
            +
            }.freeze
         | 
| 135 136 |  | 
| 136 137 | 
             
            # @private
         | 
| 137 138 | 
             
            def create_file(name)
         | 
| @@ -162,8 +163,8 @@ def git_init | |
| 162 163 | 
             
              system "git init"
         | 
| 163 164 | 
             
              system "git add ."
         | 
| 164 165 | 
             
              system "git commit -m \"Initial commit\""
         | 
| 165 | 
            -
              sputs "Initialized repository, use "  | 
| 166 | 
            -
                      "\e[32mgit commit --amend -m '...'\e[92m"  | 
| 166 | 
            +
              sputs "Initialized repository, use " \
         | 
| 167 | 
            +
                      "\e[32mgit commit --amend -m '...'\e[92m" \
         | 
| 167 168 | 
             
                      " to change commit message of initial commit.\n"
         | 
| 168 169 | 
             
            end
         | 
| 169 170 |  | 
| @@ -225,13 +226,11 @@ if (dir = ARGV[0]) | |
| 225 226 | 
             
              if Dir.exist?($path)
         | 
| 226 227 | 
             
                if Dir.empty?($path)
         | 
| 227 228 | 
             
                  iputs "Found \e[30m#{dir}\e[90m and empty, using this directory."
         | 
| 228 | 
            -
                 | 
| 229 | 
            -
                   | 
| 230 | 
            -
                    iputs "Found \e[30m#{dir}\e[90m and not empty, but force is on, using this directory."
         | 
| 229 | 
            +
                elsif $values[:force]
         | 
| 230 | 
            +
                  iputs "Found \e[30m#{dir}\e[90m and not empty, but force is on, using this directory."
         | 
| 231 231 | 
             
                  else
         | 
| 232 232 | 
             
                    eputs "Directory \e[31m#{dir}\e[91m already exists and not empty. Use \e[31m-f\e[91m to force."
         | 
| 233 233 | 
             
                    exit
         | 
| 234 | 
            -
                  end
         | 
| 235 234 | 
             
                end
         | 
| 236 235 | 
             
              else
         | 
| 237 236 | 
             
                Dir.mkdir($path)
         | 
    
        data/lib/discorb/exe/run.rb
    CHANGED
    
    | @@ -1,3 +1,4 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 1 2 | 
             
            # description: Run a client.
         | 
| 2 3 | 
             
            require "optparse"
         | 
| 3 4 | 
             
            require "json"
         | 
| @@ -6,7 +7,7 @@ require "io/console" | |
| 6 7 |  | 
| 7 8 | 
             
            ARGV.delete_at 0
         | 
| 8 9 | 
             
            # @private
         | 
| 9 | 
            -
            LOG_LEVELS = %w[none debug info warn error fatal]
         | 
| 10 | 
            +
            LOG_LEVELS = %w[none debug info warn error fatal].freeze
         | 
| 10 11 |  | 
| 11 12 | 
             
            opt = OptionParser.new <<~BANNER
         | 
| 12 13 | 
             
                                     This command will run a client.
         | 
    
        data/lib/discorb/exe/setup.rb
    CHANGED
    
    | @@ -1,3 +1,4 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 1 2 | 
             
            # description: Setup application commands.
         | 
| 2 3 | 
             
            require "optparse"
         | 
| 3 4 | 
             
            require "discorb/utils/colored_puts"
         | 
| @@ -6,6 +7,7 @@ ARGV.delete_at 0 | |
| 6 7 |  | 
| 7 8 | 
             
            options = {
         | 
| 8 9 | 
             
              guilds: nil,
         | 
| 10 | 
            +
              script: true,
         | 
| 9 11 | 
             
            }
         | 
| 10 12 |  | 
| 11 13 | 
             
            opt = OptionParser.new <<~BANNER
         | 
| @@ -16,20 +18,21 @@ opt = OptionParser.new <<~BANNER | |
| 16 18 | 
             
                                               script                     The script to setup.
         | 
| 17 19 | 
             
                                   BANNER
         | 
| 18 20 | 
             
            opt.on("-g", "--guild ID", Array, "The guild ID to setup, use comma for setup commands in multiple guilds, or `global` for setup global commands.") { |v| options[:guilds] = v }
         | 
| 21 | 
            +
            opt.on("-s", "--[no-]script", "Whether to run `:setup` event. This may be useful if setup script includes operation that shouldn't run twice. Default to true.") { |v| options[:script] = v }
         | 
| 19 22 | 
             
            opt.parse!(ARGV)
         | 
| 20 23 |  | 
| 21 24 | 
             
            script = ARGV[0]
         | 
| 22 25 | 
             
            script ||= "main.rb"
         | 
| 23 26 | 
             
            ENV["DISCORB_CLI_FLAG"] = "setup"
         | 
| 24 27 |  | 
| 25 | 
            -
            if options[:guilds] == ["global"]
         | 
| 26 | 
            -
               | 
| 28 | 
            +
            ENV["DISCORB_SETUP_GUILDS"] = if options[:guilds] == ["global"]
         | 
| 29 | 
            +
              "global"
         | 
| 27 30 | 
             
            elsif options[:guilds]
         | 
| 28 | 
            -
               | 
| 29 | 
            -
            else
         | 
| 30 | 
            -
              ENV["DISCORB_SETUP_GUILDS"] = nil
         | 
| 31 | 
            +
              options[:guilds].join(",")
         | 
| 31 32 | 
             
            end
         | 
| 32 33 |  | 
| 34 | 
            +
            ENV["DISCORB_SETUP_SCRIPT"] = options[:script].to_s if options[:script]
         | 
| 35 | 
            +
             | 
| 33 36 | 
             
            begin
         | 
| 34 37 | 
             
              load script
         | 
| 35 38 | 
             
            rescue LoadError
         | 
    
        data/lib/discorb/exe/show.rb
    CHANGED
    
    
    
        data/lib/discorb/extend.rb
    CHANGED
    
    | @@ -1,4 +1,5 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 | 
            +
            # rubocop: disable Style/Documentation
         | 
| 2 3 |  | 
| 3 4 | 
             
            class Time
         | 
| 4 5 | 
             
              #
         | 
| @@ -18,22 +19,26 @@ class Time | |
| 18 19 | 
             
            end
         | 
| 19 20 |  | 
| 20 21 | 
             
            # @private
         | 
| 21 | 
            -
             | 
| 22 | 
            -
               | 
| 23 | 
            -
                 | 
| 22 | 
            +
            module Async
         | 
| 23 | 
            +
              class Node
         | 
| 24 | 
            +
                def description
         | 
| 25 | 
            +
                  @object_name ||= "#{self.class}:0x#{object_id.to_s(16)}#{@transient ? " transient" : nil}"
         | 
| 24 26 |  | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 27 | 
            +
                  if @annotation
         | 
| 28 | 
            +
                    "#{@object_name} #{@annotation}"
         | 
| 29 | 
            +
                  elsif line = self.backtrace(0, 1)&.first
         | 
| 30 | 
            +
                    "#{@object_name} #{line}"
         | 
| 31 | 
            +
                  else
         | 
| 32 | 
            +
                    @object_name
         | 
| 33 | 
            +
                  end
         | 
| 31 34 | 
             
                end
         | 
| 32 | 
            -
              end
         | 
| 33 35 |  | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 36 | 
            +
                def to_s
         | 
| 37 | 
            +
                  "\#<#{self.description}>"
         | 
| 38 | 
            +
                end
         | 
| 37 39 |  | 
| 38 | 
            -
             | 
| 40 | 
            +
                alias inspect to_s
         | 
| 41 | 
            +
              end
         | 
| 39 42 | 
             
            end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            # rubocop: enable Style/Documentation
         | 
    
        data/lib/discorb/extension.rb
    CHANGED
    
    | @@ -17,7 +17,7 @@ module Discorb | |
| 17 17 | 
             
                  ret = {}
         | 
| 18 18 | 
             
                  self.class.events.each do |event, handlers|
         | 
| 19 19 | 
             
                    ret[event] = handlers.map do |handler|
         | 
| 20 | 
            -
                      Discorb::EventHandler.new( | 
| 20 | 
            +
                      Discorb::EventHandler.new(proc { |*args, **kwargs| instance_exec(*args, **kwargs, &handler[2]) }, handler[0], handler[1])
         | 
| 21 21 | 
             
                    end
         | 
| 22 22 | 
             
                  end
         | 
| 23 23 | 
             
                  @events = ret
         | 
| @@ -27,6 +27,10 @@ module Discorb | |
| 27 27 | 
             
                  base.extend(ClassMethods)
         | 
| 28 28 | 
             
                end
         | 
| 29 29 |  | 
| 30 | 
            +
                #
         | 
| 31 | 
            +
                # @private
         | 
| 32 | 
            +
                # Module for adding class methods to the extension class.
         | 
| 33 | 
            +
                #
         | 
| 30 34 | 
             
                module ClassMethods
         | 
| 31 35 | 
             
                  include Discorb::ApplicationCommand::Handler
         | 
| 32 36 | 
             
                  undef setup_commands
         |