discorb 0.13.2 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
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]