discorb 0.0.1

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 (66) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +56 -0
  3. data/.yardopts +6 -0
  4. data/Changelog.md +5 -0
  5. data/Gemfile +23 -0
  6. data/Gemfile.lock +70 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +53 -0
  9. data/Rakefile +46 -0
  10. data/bin/console +15 -0
  11. data/bin/setup +8 -0
  12. data/discorb.gemspec +37 -0
  13. data/docs/Examples.md +26 -0
  14. data/docs/events.md +480 -0
  15. data/docs/voice_events.md +283 -0
  16. data/examples/components/authorization_button.rb +43 -0
  17. data/examples/components/select_menu.rb +61 -0
  18. data/examples/extension/main.rb +12 -0
  19. data/examples/extension/message_expander.rb +41 -0
  20. data/examples/simple/eval.rb +32 -0
  21. data/examples/simple/ping_pong.rb +16 -0
  22. data/examples/simple/rolepanel.rb +65 -0
  23. data/examples/simple/wait_for_message.rb +30 -0
  24. data/lib/discorb/application.rb +157 -0
  25. data/lib/discorb/asset.rb +57 -0
  26. data/lib/discorb/audit_logs.rb +323 -0
  27. data/lib/discorb/channel.rb +1101 -0
  28. data/lib/discorb/client.rb +363 -0
  29. data/lib/discorb/color.rb +173 -0
  30. data/lib/discorb/common.rb +123 -0
  31. data/lib/discorb/components.rb +290 -0
  32. data/lib/discorb/dictionary.rb +119 -0
  33. data/lib/discorb/embed.rb +345 -0
  34. data/lib/discorb/emoji.rb +218 -0
  35. data/lib/discorb/emoji_table.rb +3799 -0
  36. data/lib/discorb/error.rb +98 -0
  37. data/lib/discorb/event.rb +35 -0
  38. data/lib/discorb/extend.rb +18 -0
  39. data/lib/discorb/extension.rb +54 -0
  40. data/lib/discorb/file.rb +69 -0
  41. data/lib/discorb/flag.rb +109 -0
  42. data/lib/discorb/gateway.rb +967 -0
  43. data/lib/discorb/gateway_requests.rb +47 -0
  44. data/lib/discorb/guild.rb +1244 -0
  45. data/lib/discorb/guild_template.rb +211 -0
  46. data/lib/discorb/image.rb +43 -0
  47. data/lib/discorb/integration.rb +111 -0
  48. data/lib/discorb/intents.rb +137 -0
  49. data/lib/discorb/interaction.rb +333 -0
  50. data/lib/discorb/internet.rb +285 -0
  51. data/lib/discorb/invite.rb +145 -0
  52. data/lib/discorb/log.rb +70 -0
  53. data/lib/discorb/member.rb +232 -0
  54. data/lib/discorb/message.rb +583 -0
  55. data/lib/discorb/modules.rb +138 -0
  56. data/lib/discorb/permission.rb +270 -0
  57. data/lib/discorb/presence.rb +308 -0
  58. data/lib/discorb/reaction.rb +48 -0
  59. data/lib/discorb/role.rb +189 -0
  60. data/lib/discorb/sticker.rb +157 -0
  61. data/lib/discorb/user.rb +163 -0
  62. data/lib/discorb/utils.rb +16 -0
  63. data/lib/discorb/voice_state.rb +251 -0
  64. data/lib/discorb/webhook.rb +420 -0
  65. data/lib/discorb.rb +51 -0
  66. metadata +120 -0
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ API_BASE_URL = "https://discord.com/api/v9"
5
+ VERSION = "0.0.1"
6
+ USER_AGENT = "DiscordBot (https://github.com/discorb-lib/discorb #{VERSION}) Ruby/#{RUBY_VERSION}"
7
+
8
+ #
9
+ # @abstract
10
+ # Represents Discord model.
11
+ #
12
+ class DiscordModel
13
+ def eql?(other)
14
+ self == other
15
+ end
16
+
17
+ def ==(other)
18
+ if respond_to?(:id) && other.respond_to?(:id)
19
+ id == other.id
20
+ else
21
+ super
22
+ end
23
+ end
24
+
25
+ # @!visibility private
26
+ def inspect
27
+ super
28
+ end
29
+
30
+ def hash
31
+ @id.hash
32
+ end
33
+ end
34
+
35
+ #
36
+ # Represents Snowflake of Discord.
37
+ #
38
+ # @see https://discord.com/developers/docs/reference#snowflakes Official Discord API docs
39
+ class Snowflake < DiscordModel
40
+ # @!visibility private
41
+ def initialize(value)
42
+ @value = value.to_i
43
+ end
44
+
45
+ # @!attribute [r] timestamp
46
+ # Timestamp of snowflake.
47
+ #
48
+ # @return [Time] Timestamp of snowflake.
49
+ #
50
+ # @!attribute [r] worker_id
51
+ # Worker ID of snowflake.
52
+ #
53
+ # @return [Integer] Worker ID of snowflake.
54
+ #
55
+ # @!attribute [r] process_id
56
+ # Process ID of snowflake.
57
+ #
58
+ # @return [Integer] Process ID of snowflake.
59
+ # @!attribute [r] increment
60
+ # Increment of snowflake.
61
+ #
62
+ # @return [Integer] Increment of snowflake.
63
+
64
+ #
65
+ # Stringify snowflake.
66
+ #
67
+ # @return [String] Stringified snowflake.
68
+ #
69
+ def to_s
70
+ @value.to_s
71
+ end
72
+
73
+ #
74
+ # Integerize snowflake.
75
+ #
76
+ # @return [Integer] Integerized snowflake.
77
+ #
78
+ def to_i
79
+ @value.to_i
80
+ end
81
+
82
+ #
83
+ # Compares snowflake with other object.
84
+ #
85
+ # @param [#to_s] other Object to compare with.
86
+ #
87
+ # @return [Boolean] True if snowflake is equal to other object.
88
+ #
89
+ def ==(other)
90
+ return false unless other.respond_to?(:to_s)
91
+
92
+ to_s == other.to_s
93
+ end
94
+
95
+ #
96
+ # Alias of {#==}.
97
+ #
98
+ def eql?(other)
99
+ self == other
100
+ end
101
+
102
+ # Return hash of snowflake.
103
+ def hash
104
+ to_s.hash
105
+ end
106
+
107
+ def timestamp
108
+ Time.at(((sf >> 22) + 1_420_070_400_000) / 1000)
109
+ end
110
+
111
+ def worker_id
112
+ (snowflake & 0x3E0000) >> 17
113
+ end
114
+
115
+ def process_id
116
+ (snowflake & 0x1F000) >> 12
117
+ end
118
+
119
+ def increment
120
+ snowflake & 0xFFF
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,290 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # @abstract
6
+ # Represents a Discord component.
7
+ #
8
+ class Component
9
+ class << self
10
+ #
11
+ # Create a new component from hash data.
12
+ #
13
+ # @see https://discord.com/developers/docs/interactions/message-components Official Discord API documentation
14
+ # @param [Hash] data Hash data.
15
+ #
16
+ # @return [Component] A new component.
17
+ #
18
+ def from_hash(data)
19
+ case data[:type]
20
+ when 2
21
+ Button.new(
22
+ data[:label],
23
+ data[:style],
24
+ emoji: data[:emoji],
25
+ custom_id: data[:custom_id],
26
+ url: data[:url],
27
+ disabled: data[:disabled],
28
+ )
29
+ when 3
30
+ SelectMenu.new(
31
+ data[:custom_id],
32
+ data[:options].map { |o| SelectMenu::Option.from_hash(o) },
33
+ placeholder: data[:placeholder],
34
+ min_values: data[:min_values],
35
+ max_values: data[:max_values],
36
+ )
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ #
43
+ # Represents a button component.
44
+ #
45
+ class Button < Component
46
+ # @return [String] The label of the button.
47
+ attr_accessor :label
48
+ # @return [:primary, :secondary, :success, :danger, :link] The style of the button.
49
+ attr_accessor :style
50
+ # @return [Discorb::Emoji] The emoji of the button.
51
+ attr_accessor :emoji
52
+ # @return [String] The custom ID of the button.
53
+ # Won't be used if the style is `:link`.
54
+ attr_accessor :custom_id
55
+ # @return [String] The URL of the button.
56
+ # Only used when the style is `:link`.
57
+ attr_accessor :url
58
+ # @return [Boolean] Whether the button is disabled.
59
+ attr_accessor :disabled
60
+ alias disabled? disabled
61
+
62
+ @styles = {
63
+ primary: 1,
64
+ secondary: 2,
65
+ success: 3,
66
+ danger: 4,
67
+ link: 5,
68
+ }.freeze
69
+
70
+ #
71
+ # Initialize a new button.
72
+ #
73
+ # @param [String] label The label of the button.
74
+ # @param [:primary, :secondary, :success, :danger, :link] style The style of the button.
75
+ # @param [Discorb::Emoji] emoji The emoji of the button.
76
+ # @param [String] custom_id The custom ID of the button.
77
+ # @param [String] url The URL of the button.
78
+ # @param [Boolean] disabled Whether the button is disabled.
79
+ #
80
+ def initialize(label, style = :primary, emoji: nil, custom_id: nil, url: nil, disabled: false)
81
+ @label = label
82
+ @style = style
83
+ @emoji = emoji
84
+ @custom_id = custom_id
85
+ @url = url
86
+ @disabled = disabled
87
+ end
88
+
89
+ #
90
+ # Converts the button to a hash.
91
+ #
92
+ # @see https://discord.com/developers/docs/interactions/message-components#button-object-button-structure Official Discord API docs
93
+ # @return [Hash] A hash representation of the button.
94
+ #
95
+ def to_hash
96
+ if @style == :link
97
+ {
98
+ type: 2,
99
+ label: @label,
100
+ style: self.class.styles[@style],
101
+ url: @url,
102
+ emoji: hash_emoji(@emoji),
103
+ disabled: @disabled,
104
+ }
105
+ else
106
+ {
107
+ type: 2,
108
+ label: @label,
109
+ style: self.class.styles[@style],
110
+ custom_id: @custom_id,
111
+ emoji: hash_emoji(@emoji),
112
+ disabled: @disabled,
113
+ }
114
+ end
115
+ end
116
+
117
+ class << self
118
+ # @!visibility private
119
+ attr_reader :styles
120
+ end
121
+
122
+ private
123
+
124
+ def hash_emoji(emoji)
125
+ case emoji
126
+ when UnicodeEmoji
127
+ {
128
+ id: nil,
129
+ name: emoji.to_s,
130
+ animated: false,
131
+ }
132
+ when CustomEmoji
133
+ {
134
+ id: emoji.id,
135
+ name: emoji.name,
136
+ animated: emoji.animated?,
137
+ }
138
+ end
139
+ end
140
+ end
141
+
142
+ #
143
+ # Represents a select menu component.
144
+ #
145
+ class SelectMenu < Component
146
+ # @return [String] The custom ID of the select menu.
147
+ attr_accessor :custom_id
148
+ # @return [Array<SelectMenu::Option>] The options of the select menu.
149
+ attr_accessor :options
150
+ # @return [Integer] The minimum number of values.
151
+ attr_accessor :min_values
152
+ # @return [Integer] The maximum number of values.
153
+ attr_accessor :max_values
154
+ # @return [Boolean] Whether the select menu is disabled.
155
+ attr_reader :disabled
156
+ alias disabled? disabled
157
+
158
+ #
159
+ # Initialize a new select menu.
160
+ #
161
+ # @param [String, Symbol] custom_id Custom ID of the select menu.
162
+ # @param [Array<Discorb::SelectMenu::Option>] options The options of the select menu.
163
+ # @param [String] placeholder The placeholder of the select menu.
164
+ # @param [Integer] min_values The minimum number of values.
165
+ # @param [Integer] max_values The maximum number of values.
166
+ #
167
+ def initialize(custom_id, options, placeholder: nil, min_values: 1, max_values: 1)
168
+ @custom_id = custom_id
169
+ @options = options
170
+ @placeholder = placeholder
171
+ @min_values = min_values
172
+ @max_values = max_values
173
+ end
174
+
175
+ #
176
+ # Converts the select menu to a hash.
177
+ #
178
+ # @see https://discord.com/developers/docs/interactions/message-components#select-menu-object-select-menu-structure Official Discord API docs
179
+ # @return [Hash] A hash representation of the select menu.
180
+ #
181
+ def to_hash
182
+ {
183
+ type: 3,
184
+ custom_id: @custom_id,
185
+ options: @options.map(&:to_hash),
186
+ placeholder: @placeholder,
187
+ min_values: @min_values,
188
+ max_values: @max_values,
189
+ }
190
+ end
191
+
192
+ #
193
+ # Represents an option of a select menu.
194
+ #
195
+ class Option
196
+ # @return [String] The label of the option.
197
+ attr_accessor :label
198
+ # @return [String] The value of the option.
199
+ attr_accessor :value
200
+ # @return [String] The description of the option.
201
+ attr_accessor :description
202
+ # @return [Discorb::Emoji] The emoji of the option.
203
+ attr_accessor :emoji
204
+ # @return [Boolean] Whether the option is default.
205
+ attr_accessor :default
206
+
207
+ #
208
+ # Initialize a new option.
209
+ #
210
+ # @param [String] label The label of the option.
211
+ # @param [String] value The value of the option.
212
+ # @param [String] description The description of the option.
213
+ # @param [Discorb::Emoji] emoji The emoji of the option.
214
+ # @param [Boolean] default Whether the option is default.
215
+ def initialize(label, value, description: nil, emoji: nil, default: false)
216
+ @label = label
217
+ @value = value
218
+ @description = description
219
+ @emoji = emoji
220
+ @default = default
221
+ end
222
+
223
+ #
224
+ # Converts the option to a hash.
225
+ #
226
+ # @see https://discord.com/developers/docs/interactions/message-components#select-menu-object-select-option-structure Official Discord API docs
227
+ # @return [Hash] Hash representation of the option.
228
+ #
229
+ def to_hash
230
+ {
231
+ label: @label,
232
+ value: @value,
233
+ description: @description,
234
+ emoji: hash_emoji(@emoji),
235
+ default: @default,
236
+ }
237
+ end
238
+
239
+ # @!visibility private
240
+ def hash_emoji(emoji)
241
+ case emoji
242
+ when UnicodeEmoji
243
+ {
244
+ id: nil,
245
+ name: emoji.to_s,
246
+ animated: false,
247
+ }
248
+ when CustomEmoji
249
+ {
250
+ id: emoji.id,
251
+ name: emoji.name,
252
+ animated: emoji.animated?,
253
+ }
254
+ end
255
+ end
256
+
257
+ class << self
258
+ #
259
+ # Creates a new option from a hash.
260
+ #
261
+ # @param [Hash] data A hash representing the option.
262
+ #
263
+ # @return [Discorb::SelectMenu::Option] A new option.
264
+ #
265
+ def from_hash(data)
266
+ new(data[:label], data[:value], description: data[:description], emoji: data[:emoji], default: data[:default])
267
+ end
268
+ end
269
+ end
270
+
271
+ private
272
+
273
+ def hash_emoji(emoji)
274
+ case emoji
275
+ when UnicodeEmoji
276
+ {
277
+ id: nil,
278
+ name: emoji.to_s,
279
+ animated: false,
280
+ }
281
+ when CustomEmoji
282
+ {
283
+ id: emoji.id,
284
+ name: emoji.name,
285
+ animated: emoji.animated?,
286
+ }
287
+ end
288
+ end
289
+ end
290
+ end
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ class Dictionary
5
+ # @return [Integer] The maximum number of items in the dictionary.
6
+ attr_accessor :limit
7
+
8
+ #
9
+ # Initialize a new Dictionary.
10
+ #
11
+ # @param [Hash] hash A hash of items to add to the dictionary.
12
+ # @param [Integer] limit The maximum number of items in the dictionary.
13
+ # @param [false, Proc] sort Whether to sort the items in the dictionary.
14
+ #
15
+ def initialize(hash = {}, limit: nil, sort: false)
16
+ @cache = hash.transform_keys(&:to_s)
17
+ @limit = limit
18
+ @sort = sort
19
+ end
20
+
21
+ #
22
+ # Registers a new item in the dictionary.
23
+ #
24
+ # @param [#to_s] id The ID of the item.
25
+ # @param [Object] body The item to register.
26
+ #
27
+ # @return [self] The dictionary.
28
+ #
29
+ def register(id, body)
30
+ @cache[id.to_s] = body
31
+ @cache = @cache.sort_by(&@sort).to_h if @sort
32
+ @cache.remove(@cache.values[-1]) if !@limit.nil? && @cache.size > @limit
33
+ body
34
+ end
35
+
36
+ #
37
+ # Merges another dictionary into this one.
38
+ #
39
+ # @param [Discorb::Dictionary] other The dictionary to merge.
40
+ #
41
+ def merge(other)
42
+ @cache.merge!(other)
43
+ end
44
+
45
+ #
46
+ # Removes an item from the dictionary.
47
+ #
48
+ # @param [#to_s] id The ID of the item to remove.
49
+ #
50
+ def remove(id)
51
+ @cache.remove(id.to_s)
52
+ end
53
+
54
+ #
55
+ # Get an item from the dictionary.
56
+ #
57
+ # @param [#to_s] id The ID of the item.
58
+ # @return [Object] The item.
59
+ # @return [nil] if the item was not found.
60
+ #
61
+ # @overload get(index)
62
+ # @param [Integer] index The index of the item.
63
+ #
64
+ # @return [Object] The item.
65
+ # @return [nil] if the item is not found.
66
+ #
67
+ def get(id)
68
+ res = @cache[id.to_s]
69
+ if res.nil? && id.is_a?(Integer) && id < @cache.length
70
+ @cache.values[id]
71
+ else
72
+ res
73
+ end
74
+ end
75
+
76
+ #
77
+ # Returns the values of the dictionary.
78
+ #
79
+ # @return [Array] The values of the dictionary.
80
+ #
81
+ def values
82
+ @cache.values
83
+ end
84
+
85
+ #
86
+ # Checks if the dictionary has an ID.
87
+ #
88
+ # @param [#to_s] id The ID to check.
89
+ #
90
+ # @return [Boolean] `true` if the dictionary has the ID, `false` otherwise.
91
+ #
92
+ def has?(id)
93
+ !self[id].nil?
94
+ end
95
+
96
+ def method_missing(name, ...)
97
+ if values.respond_to?(name)
98
+ values.send(name, ...)
99
+ else
100
+ super
101
+ end
102
+ end
103
+
104
+ def respond_to_missing?(name, args, kwargs)
105
+ if values.respond_to?(name)
106
+ true
107
+ else
108
+ super
109
+ end
110
+ end
111
+
112
+ alias [] get
113
+ alias []= register
114
+
115
+ def inspect
116
+ "#<#{self.class} #{values.length} items>"
117
+ end
118
+ end
119
+ end