discorb 0.13.2 → 0.15.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 (92) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -0
  3. data/.github/workflows/build_version.yml +1 -1
  4. data/.github/workflows/codeql-analysis.yml +70 -0
  5. data/.github/workflows/lint-push.yml +20 -0
  6. data/.github/workflows/lint.yml +16 -0
  7. data/.rubocop.yml +70 -0
  8. data/CODE_OF_CONDUCT.md +128 -0
  9. data/Changelog.md +34 -0
  10. data/Gemfile +7 -3
  11. data/README.md +1 -1
  12. data/Rakefile +22 -22
  13. data/discorb.gemspec +13 -1
  14. data/docs/faq.md +8 -8
  15. data/examples/commands/bookmarker.rb +2 -1
  16. data/examples/commands/hello.rb +1 -0
  17. data/examples/commands/inspect.rb +3 -2
  18. data/examples/components/authorization_button.rb +2 -1
  19. data/examples/components/select_menu.rb +2 -1
  20. data/examples/extension/main.rb +1 -0
  21. data/examples/extension/message_expander.rb +1 -0
  22. data/examples/simple/eval.rb +3 -2
  23. data/examples/simple/ping_pong.rb +1 -0
  24. data/examples/simple/rolepanel.rb +1 -0
  25. data/examples/simple/wait_for_message.rb +4 -3
  26. data/exe/discorb +8 -7
  27. data/lib/discorb/allowed_mentions.rb +64 -0
  28. data/lib/discorb/app_command/command.rb +274 -0
  29. data/lib/discorb/app_command/handler.rb +168 -0
  30. data/lib/discorb/app_command.rb +2 -404
  31. data/lib/discorb/asset.rb +3 -1
  32. data/lib/discorb/{file.rb → attachment.rb} +42 -35
  33. data/lib/discorb/audit_logs.rb +3 -3
  34. data/lib/discorb/channel.rb +65 -61
  35. data/lib/discorb/client.rb +36 -33
  36. data/lib/discorb/common.rb +29 -22
  37. data/lib/discorb/components/button.rb +106 -0
  38. data/lib/discorb/components/select_menu.rb +157 -0
  39. data/lib/discorb/components/text_input.rb +96 -0
  40. data/lib/discorb/components.rb +11 -276
  41. data/lib/discorb/dictionary.rb +13 -2
  42. data/lib/discorb/embed.rb +40 -33
  43. data/lib/discorb/emoji.rb +21 -5
  44. data/lib/discorb/emoji_table.rb +1 -1
  45. data/lib/discorb/error.rb +4 -6
  46. data/lib/discorb/event.rb +13 -11
  47. data/lib/discorb/exe/about.rb +1 -0
  48. data/lib/discorb/exe/irb.rb +4 -3
  49. data/lib/discorb/exe/new.rb +6 -7
  50. data/lib/discorb/exe/run.rb +2 -1
  51. data/lib/discorb/exe/setup.rb +8 -5
  52. data/lib/discorb/exe/show.rb +1 -0
  53. data/lib/discorb/extend.rb +19 -14
  54. data/lib/discorb/extension.rb +5 -1
  55. data/lib/discorb/gateway.rb +82 -29
  56. data/lib/discorb/guild.rb +58 -80
  57. data/lib/discorb/guild_template.rb +5 -5
  58. data/lib/discorb/http.rb +52 -170
  59. data/lib/discorb/integration.rb +32 -3
  60. data/lib/discorb/intents.rb +9 -4
  61. data/lib/discorb/interaction/autocomplete.rb +5 -4
  62. data/lib/discorb/interaction/command.rb +34 -9
  63. data/lib/discorb/interaction/components.rb +5 -2
  64. data/lib/discorb/interaction/modal.rb +33 -0
  65. data/lib/discorb/interaction/response.rb +41 -12
  66. data/lib/discorb/interaction/root.rb +1 -0
  67. data/lib/discorb/interaction.rb +2 -1
  68. data/lib/discorb/invite.rb +1 -1
  69. data/lib/discorb/log.rb +4 -3
  70. data/lib/discorb/member.rb +4 -6
  71. data/lib/discorb/message.rb +38 -241
  72. data/lib/discorb/message_meta.rb +157 -0
  73. data/lib/discorb/modules.rb +47 -23
  74. data/lib/discorb/permission.rb +2 -2
  75. data/lib/discorb/presence.rb +6 -3
  76. data/lib/discorb/rate_limit.rb +15 -21
  77. data/lib/discorb/role.rb +3 -3
  78. data/lib/discorb/sticker.rb +2 -2
  79. data/lib/discorb/user.rb +3 -3
  80. data/lib/discorb/utils/colored_puts.rb +1 -0
  81. data/lib/discorb/voice_state.rb +7 -2
  82. data/lib/discorb/webhook.rb +9 -6
  83. data/lib/discorb.rb +2 -1
  84. data/sig/discorb.rbs +5836 -6714
  85. data/template-replace/scripts/arrow.rb +1 -0
  86. data/template-replace/scripts/favicon.rb +1 -0
  87. data/template-replace/scripts/index.rb +2 -1
  88. data/template-replace/scripts/locale_ja.rb +5 -4
  89. data/template-replace/scripts/sidebar.rb +1 -0
  90. data/template-replace/scripts/version.rb +7 -10
  91. data/template-replace/scripts/yard_replace.rb +5 -4
  92. metadata +30 -5
@@ -0,0 +1,157 @@
1
+ # frozen_string_literal: true
2
+ module Discorb
3
+ #
4
+ # Represents a message in Discord.
5
+ #
6
+ class Message < DiscordModel
7
+ #
8
+ # Represents message flag.
9
+ # ## Flag fields
10
+ # |Field|Value|
11
+ # |-|-|
12
+ # |`1 << 0`|`:crossposted`|
13
+ # |`1 << 1`|`:crosspost`|
14
+ # |`1 << 2`|`:supress_embeds`|
15
+ # |`1 << 3`|`:source_message_deleted`|
16
+ # |`1 << 4`|`:urgent`|
17
+ # |`1 << 5`|`:has_thread`|
18
+ # |`1 << 6`|`:ephemeral`|
19
+ # |`1 << 7`|`:loading`|
20
+ #
21
+ class Flag < Discorb::Flag
22
+ @bits = {
23
+ crossposted: 0,
24
+ crosspost: 1,
25
+ supress_embeds: 2,
26
+ source_message_deleted: 3,
27
+ urgent: 4,
28
+ has_thread: 5,
29
+ ephemeral: 6,
30
+ loading: 7,
31
+ }.freeze
32
+ end
33
+
34
+ #
35
+ # Represents reference of message.
36
+ #
37
+ class Reference
38
+ # @return [Discorb::Snowflake] The guild ID.
39
+ attr_accessor :guild_id
40
+ # @return [Discorb::Snowflake] The channel ID.
41
+ attr_accessor :channel_id
42
+ # @return [Discorb::Snowflake] The message ID.
43
+ attr_accessor :message_id
44
+ # @return [Boolean] Whether fail the request if the message is not found.
45
+ attr_accessor :fail_if_not_exists
46
+
47
+ alias fail_if_not_exists? fail_if_not_exists
48
+
49
+ #
50
+ # Initialize a new reference.
51
+ #
52
+ # @param [Discorb::Snowflake] guild_id The guild ID.
53
+ # @param [Discorb::Snowflake] channel_id The channel ID.
54
+ # @param [Discorb::Snowflake] message_id The message ID.
55
+ # @param [Boolean] fail_if_not_exists Whether fail the request if the message is not found.
56
+ #
57
+ def initialize(guild_id, channel_id, message_id, fail_if_not_exists: true)
58
+ @guild_id = guild_id
59
+ @channel_id = channel_id
60
+ @message_id = message_id
61
+ @fail_if_not_exists = fail_if_not_exists
62
+ end
63
+
64
+ #
65
+ # Convert the reference to a hash.
66
+ #
67
+ # @return [Hash] The hash.
68
+ #
69
+ def to_hash
70
+ {
71
+ message_id: @message_id,
72
+ channel_id: @channel_id,
73
+ guild_id: @guild_id,
74
+ fail_if_not_exists: @fail_if_not_exists,
75
+ }
76
+ end
77
+
78
+ alias to_reference to_hash
79
+
80
+ #
81
+ # Initialize a new reference from a hash.
82
+ #
83
+ # @param [Hash] data The hash.
84
+ #
85
+ # @return [Discorb::Message::Reference] The reference.
86
+ # @see https://discord.com/developers/docs/resources/channel#message-reference-object
87
+ #
88
+ def self.from_hash(data)
89
+ new(data[:guild_id], data[:channel_id], data[:message_id], fail_if_not_exists: data[:fail_if_not_exists])
90
+ end
91
+ end
92
+
93
+ #
94
+ # Represents a sticker.
95
+ #
96
+ class Sticker
97
+ attr_reader :id, :name, :format
98
+
99
+ def initialize(data)
100
+ @id = Snowflake.new(data[:id])
101
+ @name = data[:name]
102
+ @format = Discorb::Sticker.sticker_format[data[:format]]
103
+ end
104
+ end
105
+
106
+ #
107
+ # Represents a interaction of message.
108
+ #
109
+ class Interaction < DiscordModel
110
+ # @return [Discorb::Snowflake] The user ID.
111
+ attr_reader :id
112
+ # @return [String] The name of command.
113
+ # @return [nil] If the message is not a command.
114
+ attr_reader :name
115
+ # @return [Class] The type of interaction.
116
+ attr_reader :type
117
+ # @return [Discorb::User] The user.
118
+ attr_reader :user
119
+
120
+ # @private
121
+ def initialize(client, data)
122
+ @id = Snowflake.new(data[:id])
123
+ @name = data[:name]
124
+ @type = Discorb::Interaction.descendants.find { |c| c.interaction_type == data[:type] }
125
+ @user = client.users[data[:user][:id]] || User.new(client, data[:user])
126
+ end
127
+ end
128
+
129
+ #
130
+ # Represents a activity of message.
131
+ #
132
+ class Activity < DiscordModel
133
+ # @return [String] The name of activity.
134
+ attr_reader :name
135
+ # @return [Symbol] The type of activity.
136
+ attr_reader :type
137
+
138
+ @type = {
139
+ 1 => :join,
140
+ 2 => :spectate,
141
+ 3 => :listen,
142
+ 5 => :join_request,
143
+ }
144
+
145
+ # @private
146
+ def initialize(data)
147
+ @name = data[:name]
148
+ @type = self.class.type(data[:type])
149
+ end
150
+
151
+ class << self
152
+ # @private
153
+ attr_reader :type
154
+ end
155
+ end
156
+ end
157
+ end
@@ -16,13 +16,13 @@ module Discorb
16
16
  # @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions.
17
17
  # @param [Discorb::Message, Discorb::Message::Reference] reference The message to reply to.
18
18
  # @param [Array<Discorb::Component>, Array<Array<Discorb::Component>>] components The components to send.
19
- # @param [Discorb::File] file The file to send.
20
- # @param [Array<Discorb::File>] files The files to send.
19
+ # @param [Discorb::Attachment] attachment The attachment to send.
20
+ # @param [Array<Discorb::Attachment>] attachments The attachments to send.
21
21
  #
22
22
  # @return [Async::Task<Discorb::Message>] The message sent.
23
23
  #
24
24
  def post(content = nil, tts: false, embed: nil, embeds: nil, allowed_mentions: nil,
25
- reference: nil, components: nil, file: nil, files: nil)
25
+ reference: nil, components: nil, attachment: nil, attachments: nil)
26
26
  Async do
27
27
  payload = {}
28
28
  payload[:content] = content if content
@@ -37,8 +37,17 @@ module Discorb
37
37
  allowed_mentions ? allowed_mentions.to_hash(@client.allowed_mentions) : @client.allowed_mentions.to_hash
38
38
  payload[:message_reference] = reference.to_reference if reference
39
39
  payload[:components] = Component.to_payload(components) if components
40
- files = [file]
41
- _resp, data = @client.http.multipart_post("/channels/#{channel_id.wait}/messages", payload, files).wait
40
+ attachments ||= attachment ? [attachment] : []
41
+
42
+ payload[:attachments] = attachments.map.with_index do |a, i|
43
+ {
44
+ id: i,
45
+ filename: a.filename,
46
+ description: a.description,
47
+ }
48
+ end
49
+
50
+ _resp, data = @client.http.multipart_request(Route.new("/channels/#{channel_id.wait}/messages", "//channels/:channel_id/messages", :post), payload, attachments).wait
42
51
  Message.new(@client, data.merge({ guild_id: @guild_id.to_s }))
43
52
  end
44
53
  end
@@ -48,33 +57,48 @@ module Discorb
48
57
  #
49
58
  # Edit a message.
50
59
  # @async
60
+ # @!macro edit
51
61
  #
52
62
  # @param [#to_s] message_id The message id.
53
63
  # @param [String] content The message content.
54
64
  # @param [Discorb::Embed] embed The embed to send.
55
65
  # @param [Array<Discorb::Embed>] embeds The embeds to send.
56
66
  # @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions.
67
+ # @param [Array<Discorb::Attachment>] attachments The new attachments.
57
68
  # @param [Array<Discorb::Component>, Array<Array<Discorb::Component>>] components The components to send.
58
69
  # @param [Boolean] supress Whether to supress embeds.
59
70
  #
60
71
  # @return [Async::Task<void>] The task.
61
72
  #
62
- def edit_message(message_id, content = nil, embed: nil, embeds: nil, allowed_mentions: nil,
63
- components: nil, supress: nil)
73
+ def edit_message(message_id, content = Discorb::Unset, embed: Discorb::Unset, embeds: Discorb::Unset, allowed_mentions: Discorb::Unset,
74
+ attachments: Discorb::Unset, components: Discorb::Unset, supress: Discorb::Unset)
64
75
  Async do
65
76
  payload = {}
66
- payload[:content] = content if content
67
- tmp_embed = if embed
77
+ payload[:content] = content if content != Discorb::Unset
78
+ tmp_embed = if embed != Discorb::Unset
68
79
  [embed]
69
- elsif embeds
80
+ elsif embeds != Discorb::Unset
70
81
  embeds
71
82
  end
72
83
  payload[:embeds] = tmp_embed.map(&:to_hash) if tmp_embed
73
84
  payload[:allowed_mentions] =
74
- allowed_mentions ? allowed_mentions.to_hash(@client.allowed_mentions) : @client.allowed_mentions.to_hash
75
- payload[:components] = Component.to_payload(components) if components
76
- payload[:flags] = (supress ? 1 << 2 : 0) unless supress.nil?
77
- @client.http.patch("/channels/#{channel_id.wait}/messages/#{message_id}", payload).wait
85
+ allowed_mentions == Discorb::Unset ? @client.allowed_mentions.to_hash : allowed_mentions.to_hash(@client.allowed_mentions)
86
+ payload[:components] = Component.to_payload(components) if components != Discorb::Unset
87
+ payload[:flags] = (supress ? 1 << 2 : 0) if supress != Discorb::Unset
88
+ if attachments != Discorb::Unset
89
+ payload[:attachments] = attachments.map.with_index do |a, i|
90
+ {
91
+ id: i,
92
+ filename: a.filename,
93
+ description: a.description,
94
+ }
95
+ end
96
+ end
97
+ @client.http.multipart_request(
98
+ Route.new("/channels/#{channel_id.wait}/messages/#{message_id}", "//channels/:channel_id/messages/:message_id", :patch),
99
+ payload,
100
+ attachments == Discorb::Unset ? [] : attachments
101
+ ).wait
78
102
  end
79
103
  end
80
104
 
@@ -89,7 +113,7 @@ module Discorb
89
113
  #
90
114
  def delete_message!(message_id, reason: nil)
91
115
  Async do
92
- @client.http.delete("/channels/#{channel_id.wait}/messages/#{message_id}", audit_log_reason: reason).wait
116
+ @client.http.request(Route.new("/channels/#{channel_id.wait}/messages/#{message_id}", "//channels/:channel_id/messages/:message_id", :delete), audit_log_reason: reason).wait
93
117
  end
94
118
  end
95
119
 
@@ -106,7 +130,7 @@ module Discorb
106
130
  #
107
131
  def fetch_message(id)
108
132
  Async do
109
- _resp, data = @client.http.get("/channels/#{channel_id.wait}/messages/#{id}").wait
133
+ _resp, data = @client.http.request(Route.new("/channels/#{channel_id.wait}/messages/#{id}", "//channels/:channel_id/messages/:message_id", :get)).wait
110
134
  Message.new(@client, data.merge({ guild_id: @guild_id.to_s }))
111
135
  end
112
136
  end
@@ -130,7 +154,7 @@ module Discorb
130
154
  after: Discorb::Utils.try(around, :id),
131
155
  around: Discorb::Utils.try(before, :id),
132
156
  }.filter { |_k, v| !v.nil? }.to_h
133
- _resp, messages = @client.http.get("/channels/#{channel_id.wait}/messages?#{URI.encode_www_form(params)}").wait
157
+ _resp, messages = @client.http.request(Route.new("/channels/#{channel_id.wait}/messages?#{URI.encode_www_form(params)}", "//channels/:channel_id/messages", :get)).wait
134
158
  messages.map { |m| Message.new(@client, m.merge({ guild_id: @guild_id.to_s })) }
135
159
  end
136
160
  end
@@ -143,7 +167,7 @@ module Discorb
143
167
  #
144
168
  def fetch_pins
145
169
  Async do
146
- _resp, data = @client.http.get("/channels/#{channel_id.wait}/pins").wait
170
+ _resp, data = @client.http.request(Route.new("/channels/#{channel_id.wait}/pins", "//channels/:channel_id/pins", :get)).wait
147
171
  data.map { |pin| Message.new(@client, pin) }
148
172
  end
149
173
  end
@@ -159,7 +183,7 @@ module Discorb
159
183
  #
160
184
  def pin_message(message, reason: nil)
161
185
  Async do
162
- @client.http.put("/channels/#{channel_id.wait}/pins/#{message.id}", {}, audit_log_reason: reason).wait
186
+ @client.http.request(Route.new("/channels/#{channel_id.wait}/pins/#{message.id}", "//channels/:channel_id/pins/:message_id", :put), {}, audit_log_reason: reason).wait
163
187
  end
164
188
  end
165
189
 
@@ -174,7 +198,7 @@ module Discorb
174
198
  #
175
199
  def unpin_message(message, reason: nil)
176
200
  Async do
177
- @client.http.delete("/channels/#{channel_id.wait}/pins/#{message.id}", audit_log_reason: reason).wait
201
+ @client.http.request(Route.new("/channels/#{channel_id.wait}/pins/#{message.id}", "//channels/:channel_id/pins/:message_id", :delete), audit_log_reason: reason).wait
178
202
  end
179
203
  end
180
204
 
@@ -195,7 +219,7 @@ module Discorb
195
219
  begin
196
220
  post_task = Async do
197
221
  loop do
198
- @client.http.post("/channels/#{@id}/typing", {})
222
+ @client.http.request(Route.new("/channels/#{@id}/typing", "//channels/:channel_id/typing", :post), {})
199
223
  sleep(5)
200
224
  end
201
225
  end
@@ -204,8 +228,8 @@ module Discorb
204
228
  post_task.stop
205
229
  end
206
230
  else
207
- Async do |task|
208
- @client.http.post("/channels/#{@id}/typing", {})
231
+ Async do |_task|
232
+ @client.http.request(Route.new("/channels/#{@id}/typing", "//channels/:channel_id/typing", :post), {})
209
233
  end
210
234
  end
211
235
  end
@@ -174,13 +174,13 @@ module Discorb
174
174
  # @return [Hash] The permission overwrite as a hash.
175
175
  #
176
176
  def to_hash
177
- self.class.bits.keys.map do |field|
177
+ self.class.bits.keys.to_h do |field|
178
178
  [field, if @allow & self.class.bits[field] != 0
179
179
  true
180
180
  elsif @deny & self.class.bits[method] != 0
181
181
  false
182
182
  end]
183
- end.to_h
183
+ end
184
184
  end
185
185
 
186
186
  #
@@ -105,7 +105,7 @@ module Discorb
105
105
  @party = data[:party] && Party.new(data[:party])
106
106
  @assets = data[:assets] && Asset.new(data[:assets])
107
107
  @instance = data[:instance]
108
- @buttons = data[:buttons] && data[:buttons].map { |b| Button.new(b) }
108
+ @buttons = data[:buttons]&.map { |b| Button.new(b) }
109
109
  @flags = data[:flags] && Flag.new(data[:flags])
110
110
  end
111
111
 
@@ -147,6 +147,9 @@ module Discorb
147
147
  end
148
148
  end
149
149
 
150
+ #
151
+ # Represents the party of an activity.
152
+ #
150
153
  class Party < DiscordModel
151
154
  # @return [String] The id of the party.
152
155
  attr_reader :id
@@ -175,12 +178,12 @@ module Discorb
175
178
  # Represents the assets of an activity.
176
179
  #
177
180
  class Asset < DiscordModel
178
- # @return [String] The large image ID of the asset.
181
+ # @return [String] The large image ID or URL of the asset.
179
182
  attr_reader :large_image
180
183
  alias large_id large_image
181
184
  # @return [String] The large text of the activity.
182
185
  attr_reader :large_text
183
- # @return [String] The small image ID of the activity.
186
+ # @return [String] The small image ID or URL of the activity.
184
187
  attr_reader :small_image
185
188
  alias small_id small_image
186
189
  # @return [String] The small text of the activity.
@@ -9,8 +9,8 @@ module Discorb
9
9
  # @private
10
10
  def initialize(client)
11
11
  @client = client
12
- @current_ratelimits = {}
13
12
  @path_ratelimit_bucket = {}
13
+ @path_ratelimit_hash = {}
14
14
  @global = false
15
15
  end
16
16
 
@@ -21,12 +21,10 @@ module Discorb
21
21
  #
22
22
  # Wait for the rate limit to reset.
23
23
  #
24
- # @param [String] method The HTTP method.
25
- # @param [String] path The path.
24
+ # @param [Discorb::Route] path The path.
26
25
  #
27
- def wait(method, path)
28
- return if path.start_with?("https://")
29
-
26
+ def wait(path)
27
+ # return if path.url.start_with?("https://")
30
28
  if @global && @global > Time.now.to_f
31
29
  time = @global - Time.now.to_f
32
30
  @client.log.info("global rate limit reached, waiting #{time} seconds")
@@ -34,36 +32,32 @@ module Discorb
34
32
  @global = false
35
33
  end
36
34
 
37
- return unless hash = @path_ratelimit_bucket[method + path]
35
+ return unless hash = @path_ratelimit_hash[path.identifier]
38
36
 
39
- return unless b = @current_ratelimits[hash]
37
+ return unless bucket = @path_ratelimit_bucket[hash + path.major_param]
40
38
 
41
- if b[:reset_at] < Time.now.to_f
42
- @current_ratelimits.delete(hash)
39
+ if bucket[:reset_at] < Time.now.to_f
40
+ @path_ratelimit_bucket.delete(path.identifier + path.major_param)
43
41
  return
44
42
  end
45
- return if b[:remaining] > 0
43
+ return if (bucket[:remaining]).positive?
46
44
 
47
- time = b[:reset_at] - Time.now.to_f
48
- @client.log.info("rate limit for #{method} #{path} reached, waiting #{time} seconds")
45
+ time = bucket[:reset_at] - Time.now.to_f
46
+ @client.log.info("rate limit for #{path.identifier} with #{path.major_param} reached, waiting #{time.round(4)} seconds")
49
47
  sleep(time)
50
48
  end
51
49
 
52
50
  #
53
51
  # Save the rate limit.
54
52
  #
55
- # @param [String] method The HTTP method.
56
53
  # @param [String] path The path.
57
54
  # @param [Net::HTTPResponse] resp The response.
58
55
  #
59
- def save(method, path, resp)
60
- if resp["X-Ratelimit-Global"] == "true"
61
- @global = Time.now.to_f + JSON.parse(resp.body, symbolize_names: true)[:retry_after]
62
- end
56
+ def save(path, resp)
57
+ @global = Time.now.to_f + JSON.parse(resp.body, symbolize_names: true)[:retry_after] if resp["X-Ratelimit-Global"] == "true"
63
58
  return unless resp["X-RateLimit-Remaining"]
64
-
65
- @path_ratelimit_bucket[method + path] = resp["X-RateLimit-Bucket"]
66
- @current_ratelimits[resp["X-RateLimit-Bucket"]] = {
59
+ @path_ratelimit_hash[path.identifier] = resp["X-Ratelimit-Bucket"]
60
+ @path_ratelimit_bucket[resp["X-Ratelimit-Bucket"] + path.major_param] = {
67
61
  remaining: resp["X-RateLimit-Remaining"].to_i,
68
62
  reset_at: Time.now.to_f + resp["X-RateLimit-Reset-After"].to_f,
69
63
  }
data/lib/discorb/role.rb CHANGED
@@ -99,7 +99,7 @@ module Discorb
99
99
  #
100
100
  def move(position, reason: nil)
101
101
  Async do
102
- @client.http.patch("/guilds/#{@guild.id}/roles", { id: @id, position: position }, audit_log_reason: reason).wait
102
+ @client.http.request(Route.new("/guilds/#{@guild.id}/roles", "//guilds/:guild_id/roles", :patch), { id: @id, position: position }, audit_log_reason: reason).wait
103
103
  end
104
104
  end
105
105
 
@@ -133,7 +133,7 @@ module Discorb
133
133
  payload[:unicode_emoji] = icon.to_s
134
134
  end
135
135
  end
136
- @client.http.patch("/guilds/#{@guild.id}/roles/#{@id}", payload, audit_log_reason: reason).wait
136
+ @client.http.request(Route.new("/guilds/#{@guild.id}/roles/#{@id}", "//guilds/:guild_id/roles/:role_id", :patch), payload, audit_log_reason: reason).wait
137
137
  end
138
138
  end
139
139
 
@@ -148,7 +148,7 @@ module Discorb
148
148
  #
149
149
  def delete!(reason: nil)
150
150
  Async do
151
- @client.http.delete("/guilds/#{@guild.id}/roles/#{@id}", audit_log_reason: reason).wait
151
+ @client.http.request(Route.new("/guilds/#{@guild.id}/roles/#{@id}", "//guilds/:guild_id/roles/:role_id", :delete), audit_log_reason: reason).wait
152
152
  end
153
153
  end
154
154
 
@@ -83,7 +83,7 @@ module Discorb
83
83
  payload[:name] = name unless name == Discorb::Unset
84
84
  payload[:description] = description unless description == Discorb::Unset
85
85
  payload[:tags] = tag.name unless tag == Discorb::Unset
86
- @client.http.patch("/guilds/#{@guild_id}/stickers/#{@id}", payload, audit_log_reason: reason).wait
86
+ @client.http.request(Route.new("/guilds/#{@guild_id}/stickers/#{@id}", "//guilds/:guild_id/stickers/:sticker_id", :patch), payload, audit_log_reason: reason).wait
87
87
  end
88
88
  end
89
89
 
@@ -97,7 +97,7 @@ module Discorb
97
97
  #
98
98
  def delete!(reason: nil)
99
99
  Async do
100
- @client.http.delete("/guilds/#{@guild_id}/stickers/#{@id}", audit_log_reason: reason).wait
100
+ @client.http.request(Route.new("/guilds/#{@guild_id}/stickers/#{@id}", "//guilds/:guild_id/stickers/:sticker_id", :delete), audit_log_reason: reason).wait
101
101
  end
102
102
  end
103
103
 
data/lib/discorb/user.rb CHANGED
@@ -84,7 +84,7 @@ module Discorb
84
84
  Async do
85
85
  next @dm_channel_id if @dm_channel_id
86
86
 
87
- _resp, dm_channel = @client.http.post("/users/@me/channels", { recipient_id: @id }).wait
87
+ _resp, dm_channel = @client.http.request(Route.new("/users/@me/channels", "//users/@me/channels", :post), { recipient_id: @id }).wait
88
88
  @dm_channel_id = dm_channel[:id]
89
89
  @dm_channel_id
90
90
  end
@@ -137,7 +137,7 @@ module Discorb
137
137
  @avatar = data[:avatar] ? Asset.new(self, data[:avatar]) : DefaultAvatar.new(data[:discriminator])
138
138
  @bot = data[:bot]
139
139
  @raw_data = data
140
- @client.users[@id] = self if !data[:no_cache] && data.is_a?(User)
140
+ @client.users[@id] = self unless data[:no_cache]
141
141
  @created_at = @id.timestamp
142
142
  @data.update(data)
143
143
  end
@@ -168,7 +168,7 @@ module Discorb
168
168
  else
169
169
  payload[:avatar] = avatar.to_s
170
170
  end
171
- @client.http.patch("/users/@me", payload).wait
171
+ @client.http.request(Route.new("/users/@me", "//users/@me", :patch), payload).wait
172
172
  self
173
173
  end
174
174
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # @private
2
3
  def sputs(text)
3
4
  puts "\e[92m#{text}\e[m"
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Discorb
4
+ #
5
+ # Represents a state of user in voice channel.
6
+ #
4
7
  class VoiceState < DiscordModel
5
8
  # @return [Discorb::Member] The member associated with this voice state.
6
9
  attr_reader :member
@@ -180,7 +183,9 @@ module Discorb
180
183
  payload = {}
181
184
  payload[:topic] = topic if topic != Discorb::Unset
182
185
  payload[:privacy_level] = self.class.privacy_level.key(privacy_level) if privacy_level != Discorb::Unset
183
- @client.http.edit("/stage-instances/#{@channel_id}", payload, audit_log_reason: reason).wait
186
+ @client.http.request(
187
+ Route.new("/stage-instances/#{@channel_id}", "//stage-instances/:channel_id", :patch), payload, audit_log_reason: reason,
188
+ ).wait
184
189
  self
185
190
  end
186
191
  end
@@ -196,7 +201,7 @@ module Discorb
196
201
  #
197
202
  def delete!(reason: nil)
198
203
  Async do
199
- @client.http.delete("/stage-instances/#{@channel_id}", audit_log_reason: reason).wait
204
+ @client.http.request(Route.new("/stage-instances/#{@channel_id}", "//stage-instances/:stage_instance_id", :delete), audit_log_reason: reason).wait
200
205
  self
201
206
  end
202
207
  end
@@ -75,7 +75,7 @@ module Discorb
75
75
  payload[:username] = username if username
76
76
  payload[:avatar_url] = avatar_url if avatar_url != Discorb::Unset
77
77
  files = [file]
78
- _resp, data = @http.multipart_post("#{url}?wait=#{wait}", files, payload, headers: headers).wait
78
+ _resp, data = @http.multipart_request(Route.new("#{url}?wait=#{wait}", "//webhooks/:webhook_id/:token", :post), files, payload, headers: headers).wait
79
79
  data && Webhook::Message.new(self, data)
80
80
  end
81
81
  end
@@ -99,7 +99,7 @@ module Discorb
99
99
  payload[:name] = name if name != Discorb::Unset
100
100
  payload[:avatar] = avatar if avatar != Discorb::Unset
101
101
  payload[:channel_id] = Utils.try(channel, :id) if channel != Discorb::Unset
102
- @http.patch(url.to_s, payload).wait
102
+ @http.request(Route.new(url, "//webhooks/:webhook_id/:token", :patch), payload).wait
103
103
  end
104
104
  end
105
105
 
@@ -113,7 +113,7 @@ module Discorb
113
113
  #
114
114
  def delete!
115
115
  Async do
116
- @http.delete(url).wait
116
+ @http.request(Route.new(url, "//webhooks/:webhook_id/:token", :delete)).wait
117
117
  self
118
118
  end
119
119
  end
@@ -151,7 +151,7 @@ module Discorb
151
151
  payload[:attachments] = attachments.map(&:to_hash) if attachments != Discorb::Unset
152
152
  payload[:allowed_mentions] = allowed_mentions if allowed_mentions != Discorb::Unset
153
153
  files = [file] if file != Discorb::Unset
154
- _resp, data = @http.multipart_patch("#{url}/messages/#{Utils.try(message, :id)}", payload, headers: headers).wait
154
+ _resp, data = @http.multipart_request(Route.new("#{url}/messages/#{Utils.try(message, :id)}", "//webhooks/:webhook_id/:token/messages/:message_id", :patch), payload, files).wait
155
155
  message.send(:_set_data, data)
156
156
  message
157
157
  end
@@ -166,7 +166,10 @@ module Discorb
166
166
  #
167
167
  def delete_message!(message)
168
168
  Async do
169
- @http.delete("#{url}/messages/#{Utils.try(message, :id)}").wait
169
+ @http.request(Route.new(
170
+ "#{url}/messages/#{Utils.try(message, :id)}",
171
+ "//webhooks/:webhook_id/:token/messages/:message_id", :delete
172
+ )).wait
170
173
  message
171
174
  end
172
175
  end
@@ -331,7 +334,7 @@ module Discorb
331
334
  @channel_id = Snowflake.new(data[:channel_id])
332
335
  @author = Author.new(data[:author])
333
336
  @attachments = data[:attachments].map { |a| Attachment.new(a) }
334
- @embeds = data[:embeds] ? data[:embeds].map { |e| Embed.new(data: e) } : []
337
+ @embeds = data[:embeds] ? data[:embeds].map { |e| Embed.from_hash(e) } : []
335
338
  @mentions = data[:mentions].map { |m| Mention.new(m) }
336
339
  @mention_roles = data[:mention_roles].map { |m| Snowflake.new(m) }
337
340
  @mention_everyone = data[:mention_everyone]
data/lib/discorb.rb CHANGED
@@ -40,9 +40,10 @@ module Discorb
40
40
  end
41
41
 
42
42
  require_order = %w[common flag dictionary error rate_limit http intents emoji_table modules] +
43
+ %w[message_meta allowed_mentions] +
43
44
  %w[user member guild emoji channel embed message] +
44
45
  %w[application audit_logs color components event event_handler] +
45
- %w[file guild_template image integration interaction invite log permission] +
46
+ %w[attachment guild_template image integration interaction invite log permission] +
46
47
  %w[presence reaction role sticker utils voice_state webhook] +
47
48
  %w[gateway_requests gateway app_command] +
48
49
  %w[asset extension client extend]