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.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -0
  3. data/.github/workflows/codeql-analysis.yml +70 -0
  4. data/.github/workflows/lint-push.yml +18 -0
  5. data/.github/workflows/lint.yml +16 -0
  6. data/.rubocop.yml +70 -0
  7. data/Changelog.md +12 -0
  8. data/Gemfile +7 -3
  9. data/Rakefile +22 -22
  10. data/discorb.gemspec +1 -0
  11. data/examples/commands/bookmarker.rb +2 -1
  12. data/examples/commands/hello.rb +1 -0
  13. data/examples/commands/inspect.rb +3 -2
  14. data/examples/components/authorization_button.rb +2 -1
  15. data/examples/components/select_menu.rb +2 -1
  16. data/examples/extension/main.rb +1 -0
  17. data/examples/extension/message_expander.rb +1 -0
  18. data/examples/simple/eval.rb +3 -2
  19. data/examples/simple/ping_pong.rb +1 -0
  20. data/examples/simple/rolepanel.rb +1 -0
  21. data/examples/simple/wait_for_message.rb +4 -3
  22. data/exe/discorb +8 -7
  23. data/lib/discorb/allowed_mentions.rb +64 -0
  24. data/lib/discorb/app_command/command.rb +274 -0
  25. data/lib/discorb/app_command/handler.rb +168 -0
  26. data/lib/discorb/app_command.rb +2 -426
  27. data/lib/discorb/asset.rb +2 -0
  28. data/lib/discorb/audit_logs.rb +3 -3
  29. data/lib/discorb/channel.rb +19 -4
  30. data/lib/discorb/client.rb +30 -27
  31. data/lib/discorb/common.rb +4 -26
  32. data/lib/discorb/components/button.rb +106 -0
  33. data/lib/discorb/components/select_menu.rb +157 -0
  34. data/lib/discorb/components/text_input.rb +96 -0
  35. data/lib/discorb/components.rb +11 -276
  36. data/lib/discorb/dictionary.rb +3 -0
  37. data/lib/discorb/embed.rb +2 -2
  38. data/lib/discorb/emoji.rb +19 -3
  39. data/lib/discorb/emoji_table.rb +1 -1
  40. data/lib/discorb/error.rb +4 -6
  41. data/lib/discorb/event.rb +9 -7
  42. data/lib/discorb/exe/about.rb +1 -0
  43. data/lib/discorb/exe/irb.rb +4 -3
  44. data/lib/discorb/exe/new.rb +6 -7
  45. data/lib/discorb/exe/run.rb +2 -1
  46. data/lib/discorb/exe/setup.rb +8 -5
  47. data/lib/discorb/exe/show.rb +1 -0
  48. data/lib/discorb/extend.rb +19 -14
  49. data/lib/discorb/extension.rb +5 -1
  50. data/lib/discorb/gateway.rb +28 -30
  51. data/lib/discorb/guild.rb +11 -13
  52. data/lib/discorb/guild_template.rb +2 -2
  53. data/lib/discorb/http.rb +15 -17
  54. data/lib/discorb/integration.rb +1 -1
  55. data/lib/discorb/intents.rb +1 -1
  56. data/lib/discorb/interaction/autocomplete.rb +4 -3
  57. data/lib/discorb/interaction/command.rb +34 -9
  58. data/lib/discorb/interaction/components.rb +5 -2
  59. data/lib/discorb/interaction/modal.rb +33 -0
  60. data/lib/discorb/interaction/response.rb +33 -4
  61. data/lib/discorb/interaction/root.rb +1 -0
  62. data/lib/discorb/interaction.rb +2 -1
  63. data/lib/discorb/log.rb +1 -1
  64. data/lib/discorb/member.rb +1 -3
  65. data/lib/discorb/message.rb +26 -277
  66. data/lib/discorb/message_meta.rb +205 -0
  67. data/lib/discorb/modules.rb +1 -1
  68. data/lib/discorb/permission.rb +2 -2
  69. data/lib/discorb/presence.rb +4 -1
  70. data/lib/discorb/rate_limit.rb +2 -4
  71. data/lib/discorb/user.rb +1 -1
  72. data/lib/discorb/utils/colored_puts.rb +1 -0
  73. data/lib/discorb/voice_state.rb +3 -0
  74. data/lib/discorb/webhook.rb +1 -1
  75. data/lib/discorb.rb +1 -0
  76. data/template-replace/scripts/arrow.rb +1 -0
  77. data/template-replace/scripts/favicon.rb +1 -0
  78. data/template-replace/scripts/index.rb +2 -1
  79. data/template-replace/scripts/locale_ja.rb +5 -4
  80. data/template-replace/scripts/sidebar.rb +1 -0
  81. data/template-replace/scripts/version.rb +7 -10
  82. data/template-replace/scripts/yard_replace.rb +5 -4
  83. metadata +16 -2
@@ -4,9 +4,9 @@ module Discorb
4
4
  # @return [String] The API base URL.
5
5
  API_BASE_URL = "https://discord.com/api/v9"
6
6
  # @return [String] The version of discorb.
7
- VERSION = "0.13.4"
7
+ VERSION = "0.14.0"
8
8
  # @return [String] The user agent for the bot.
9
- USER_AGENT = "DiscordBot (https://discorb-lib.github.io #{VERSION}) Ruby/#{RUBY_VERSION}"
9
+ USER_AGENT = "DiscordBot (https://discorb-lib.github.io #{VERSION}) Ruby/#{RUBY_VERSION}".freeze
10
10
 
11
11
  #
12
12
  # @abstract
@@ -26,9 +26,6 @@ module Discorb
26
26
  end
27
27
 
28
28
  # @private
29
- def inspect
30
- super
31
- end
32
29
 
33
30
  def hash
34
31
  @id.hash
@@ -111,7 +108,7 @@ module Discorb
111
108
  end
112
109
 
113
110
  def inspect
114
- "#<#{self.class} #{to_s}>"
111
+ "#<#{self.class} #{self}>"
115
112
  end
116
113
 
117
114
  alias id to_s
@@ -146,26 +143,7 @@ module Discorb
146
143
  end
147
144
  end
148
145
 
149
- # @return [Object] Object that represents nil.
146
+ # @return [Object] Object that represents unspecified value.
150
147
  # This is used as a default value for optional parameters.
151
148
  Unset = Object.new
152
- class << Unset
153
- def method_missing(*)
154
- self
155
- end
156
-
157
- def or(other)
158
- other
159
- end
160
- end
161
-
162
- module DefineOr
163
- refine Object do
164
- def or(other)
165
- self
166
- end
167
- end
168
- end
169
-
170
- using DefineOr
171
149
  end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # Represents a button component.
6
+ #
7
+ class Button < Component
8
+ # @return [String] The label of the button.
9
+ attr_accessor :label
10
+ # @return [:primary, :secondary, :success, :danger, :link] The style of the button.
11
+ attr_accessor :style
12
+ # @return [Discorb::Emoji] The emoji of the button.
13
+ attr_accessor :emoji
14
+ # @return [String] The custom ID of the button.
15
+ # Won't be used if the style is `:link`.
16
+ attr_accessor :custom_id
17
+ # @return [String] The URL of the button.
18
+ # Only used when the style is `:link`.
19
+ attr_accessor :url
20
+ # @return [Boolean] Whether the button is disabled.
21
+ attr_accessor :disabled
22
+ alias disabled? disabled
23
+
24
+ @styles = {
25
+ primary: 1,
26
+ secondary: 2,
27
+ success: 3,
28
+ danger: 4,
29
+ link: 5,
30
+ }.freeze
31
+
32
+ #
33
+ # Initialize a new button.
34
+ #
35
+ # @param [String] label The label of the button.
36
+ # @param [:primary, :secondary, :success, :danger, :link] style The style of the button.
37
+ # @param [Discorb::Emoji] emoji The emoji of the button.
38
+ # @param [String] custom_id The custom ID of the button.
39
+ # @param [String] url The URL of the button.
40
+ # @param [Boolean] disabled Whether the button is disabled.
41
+ #
42
+ def initialize(label, style = :primary, emoji: nil, custom_id: nil, url: nil, disabled: false)
43
+ @label = label
44
+ @style = style
45
+ @emoji = emoji
46
+ @custom_id = custom_id
47
+ @url = url
48
+ @disabled = disabled
49
+ end
50
+
51
+ #
52
+ # Converts the button to a hash.
53
+ #
54
+ # @see https://discord.com/developers/docs/interactions/message-components#button-object-button-structure Official Discord API docs
55
+ # @return [Hash] A hash representation of the button.
56
+ #
57
+ def to_hash
58
+ if @style == :link
59
+ {
60
+ type: 2,
61
+ label: @label,
62
+ style: self.class.styles[@style],
63
+ url: @url,
64
+ emoji: @emoji&.to_hash,
65
+ disabled: @disabled,
66
+ }
67
+ else
68
+ {
69
+ type: 2,
70
+ label: @label,
71
+ style: self.class.styles[@style],
72
+ custom_id: @custom_id,
73
+ emoji: @emoji&.to_hash,
74
+ disabled: @disabled,
75
+ }
76
+ end
77
+ end
78
+
79
+ def inspect
80
+ "#<#{self.class}: #{@custom_id || @url}>"
81
+ end
82
+
83
+ class << self
84
+ # @private
85
+ attr_reader :styles
86
+
87
+ #
88
+ # Creates a new button from a hash.
89
+ #
90
+ # @param [Hash] data The hash to create the button from.
91
+ #
92
+ # @return [Discorb::Button] The created button.
93
+ #
94
+ def from_hash(data)
95
+ new(
96
+ data[:label],
97
+ data[:style],
98
+ emoji: data[:emoji],
99
+ custom_id: data[:custom_id],
100
+ url: data[:url],
101
+ disabled: data[:disabled],
102
+ )
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,157 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # Represents a select menu component.
6
+ #
7
+ class SelectMenu < Component
8
+ # @return [String] The custom ID of the select menu.
9
+ attr_accessor :custom_id
10
+ # @return [Array<SelectMenu::Option>] The options of the select menu.
11
+ attr_accessor :options
12
+ # @return [Integer] The minimum number of values.
13
+ attr_accessor :min_values
14
+ # @return [Integer] The maximum number of values.
15
+ attr_accessor :max_values
16
+ # @return [Boolean] Whether the select menu is disabled.
17
+ attr_accessor :disabled
18
+ alias disabled? disabled
19
+
20
+ #
21
+ # Initialize a new select menu.
22
+ #
23
+ # @param [String, Symbol] custom_id Custom ID of the select menu.
24
+ # @param [Array<Discorb::SelectMenu::Option>] options The options of the select menu.
25
+ # @param [String] placeholder The placeholder of the select menu.
26
+ # @param [Integer] min_values The minimum number of values.
27
+ # @param [Integer] max_values The maximum number of values.
28
+ #
29
+ def initialize(custom_id, options, placeholder: nil, min_values: 1, max_values: 1)
30
+ @custom_id = custom_id
31
+ @options = options
32
+ @placeholder = placeholder
33
+ @min_values = min_values
34
+ @max_values = max_values
35
+ end
36
+
37
+ #
38
+ # Converts the select menu to a hash.
39
+ #
40
+ # @see https://discord.com/developers/docs/interactions/message-components#select-menu-object-select-menu-structure Official Discord API docs
41
+ # @return [Hash] A hash representation of the select menu.
42
+ #
43
+ def to_hash
44
+ {
45
+ type: 3,
46
+ custom_id: @custom_id,
47
+ options: @options.map(&:to_hash),
48
+ placeholder: @placeholder,
49
+ min_values: @min_values,
50
+ max_values: @max_values,
51
+ disabled: @disabled,
52
+ }
53
+ end
54
+
55
+ def inspect
56
+ "#<#{self.class}: #{@custom_id}>"
57
+ end
58
+
59
+ class << self
60
+ #
61
+ # Creates a new select menu from a hash.
62
+ #
63
+ # @param [Hash] data The hash to create the select menu from.
64
+ #
65
+ # @return [Discorb::SelectMenu] The created select menu.
66
+ #
67
+ def from_hash(data)
68
+ new(
69
+ data[:custom_id],
70
+ data[:options].map { |o| SelectMenu::Option.from_hash(o) },
71
+ placeholder: data[:placeholder],
72
+ min_values: data[:min_values],
73
+ max_values: data[:max_values],
74
+ )
75
+ end
76
+ end
77
+
78
+ #
79
+ # Represents an option of a select menu.
80
+ #
81
+ class Option
82
+ # @return [String] The label of the option.
83
+ attr_accessor :label
84
+ # @return [String] The value of the option.
85
+ attr_accessor :value
86
+ # @return [String] The description of the option.
87
+ attr_accessor :description
88
+ # @return [Discorb::Emoji] The emoji of the option.
89
+ attr_accessor :emoji
90
+ # @return [Boolean] Whether the option is default.
91
+ attr_accessor :default
92
+
93
+ #
94
+ # Initialize a new option.
95
+ #
96
+ # @param [String] label The label of the option.
97
+ # @param [String] value The value of the option.
98
+ # @param [String] description The description of the option.
99
+ # @param [Discorb::Emoji] emoji The emoji of the option.
100
+ # @param [Boolean] default Whether the option is default.
101
+ def initialize(label, value, description: nil, emoji: nil, default: false)
102
+ @label = label
103
+ @value = value
104
+ @description = description
105
+ @emoji = emoji
106
+ @default = default
107
+ end
108
+
109
+ #
110
+ # Converts the option to a hash.
111
+ #
112
+ # @see https://discord.com/developers/docs/interactions/message-components#select-menu-object-select-option-structure Official Discord API docs
113
+ # @return [Hash] Hash representation of the option.
114
+ #
115
+ def to_hash
116
+ {
117
+ label: @label,
118
+ value: @value,
119
+ description: @description,
120
+ emoji: @emoji&.to_hash,
121
+ default: @default,
122
+ }
123
+ end
124
+
125
+ # @private
126
+ def hash_emoji(emoji)
127
+ case emoji
128
+ when UnicodeEmoji
129
+ {
130
+ id: nil,
131
+ name: emoji.to_s,
132
+ animated: false,
133
+ }
134
+ when CustomEmoji
135
+ {
136
+ id: emoji.id,
137
+ name: emoji.name,
138
+ animated: emoji.animated?,
139
+ }
140
+ end
141
+ end
142
+
143
+ class << self
144
+ #
145
+ # Creates a new option from a hash.
146
+ #
147
+ # @param [Hash] data A hash representing the option.
148
+ #
149
+ # @return [Discorb::SelectMenu::Option] A new option.
150
+ #
151
+ def from_hash(data)
152
+ new(data[:label], data[:value], description: data[:description], emoji: data[:emoji], default: data[:default])
153
+ end
154
+ end
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # Represents a text input component.
6
+ #
7
+ class TextInput < Component
8
+ # @private
9
+ STYLES = {
10
+ short: 1,
11
+ paragraph: 2,
12
+ }.freeze
13
+
14
+ # @return [String] The label of the text input.
15
+ attr_accessor :label
16
+ # @return [String] The custom id of the text input.
17
+ attr_accessor :custom_id
18
+ # @return [:short, :paragraph] The style of the text input.
19
+ attr_accessor :style
20
+ # @return [Integer, nil] The minimum length of the text input.
21
+ attr_accessor :min_length
22
+ # @return [Integer, nil] The maximum length of the text input.
23
+ attr_accessor :max_length
24
+ # @return [Boolean] Whether the text input is required.
25
+ attr_accessor :required
26
+ # @return [String, nil] The prefilled value of the text input.
27
+ attr_accessor :value
28
+ # @return [String, nil] The placeholder of the text input.
29
+ attr_accessor :placeholder
30
+
31
+ #
32
+ # Initialize a new text input component.
33
+ #
34
+ # @param [String] label The label of the text input.
35
+ # @param [String] custom_id The custom id of the text input.
36
+ # @param [:short, :paragraph] style The style of the text input.
37
+ # @param [Integer, nil] min_length The minimum length of the text input.
38
+ # @param [Integer, nil] max_length The maximum length of the text input.
39
+ # @param [Boolean] required Whether the text input is required.
40
+ # @param [String, nil] value The prefilled value of the text input.
41
+ # @param [String, nil] placeholder The placeholder of the text input.
42
+ #
43
+ def initialize(label, custom_id, style, min_length: nil, max_length: nil, required: false, value: nil, placeholder: nil)
44
+ @label = label
45
+ @custom_id = custom_id
46
+ @style = style
47
+ @min_length = min_length
48
+ @max_length = max_length
49
+ @required = required
50
+ @value = value
51
+ @placeholder = placeholder
52
+ end
53
+
54
+ #
55
+ # Converts the select menu to a hash.
56
+ #
57
+ # @see https://discord.com/developers/docs/interactions/message-components#text-inputs-text-input-structure Official Discord API docs
58
+ # @return [Hash] A hash representation of the text input.
59
+ #
60
+ def to_hash
61
+ {
62
+ type: 4,
63
+ label: @label,
64
+ style: STYLES[@style],
65
+ custom_id: @custom_id,
66
+ min_length: @min_length,
67
+ max_length: @max_length,
68
+ required: @required,
69
+ value: @value,
70
+ placeholder: @placeholder,
71
+ }
72
+ end
73
+
74
+ class << self
75
+ #
76
+ # Creates a new text input from a hash.
77
+ #
78
+ # @param [Hash] data The hash to create the text input from.
79
+ #
80
+ # @return [Discorb::TextInput] The created text input.
81
+ #
82
+ def from_hash(data)
83
+ new(
84
+ data[:label],
85
+ data[:custom_id],
86
+ STYLES.key(data[:style]),
87
+ min_length: data[:min_length],
88
+ max_length: data[:max_length],
89
+ required: data[:required],
90
+ value: data[:value],
91
+ placeholder: data[:placeholder],
92
+ )
93
+ end
94
+ end
95
+ end
96
+ end