discordrb 3.4.3 → 3.5.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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +44 -18
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -1
  4. data/.github/ISSUE_TEMPLATE/feature_request.md +0 -1
  5. data/.github/workflows/codeql.yml +65 -0
  6. data/.markdownlint.json +4 -0
  7. data/.rubocop.yml +8 -2
  8. data/CHANGELOG.md +390 -225
  9. data/LICENSE.txt +1 -1
  10. data/README.md +37 -25
  11. data/discordrb-webhooks.gemspec +4 -1
  12. data/discordrb.gemspec +9 -6
  13. data/lib/discordrb/api/application.rb +202 -0
  14. data/lib/discordrb/api/channel.rb +177 -11
  15. data/lib/discordrb/api/interaction.rb +54 -0
  16. data/lib/discordrb/api/invite.rb +2 -2
  17. data/lib/discordrb/api/server.rb +40 -19
  18. data/lib/discordrb/api/user.rb +8 -3
  19. data/lib/discordrb/api/webhook.rb +57 -0
  20. data/lib/discordrb/api.rb +19 -5
  21. data/lib/discordrb/bot.rb +317 -32
  22. data/lib/discordrb/cache.rb +27 -22
  23. data/lib/discordrb/commands/command_bot.rb +6 -4
  24. data/lib/discordrb/commands/container.rb +1 -1
  25. data/lib/discordrb/commands/parser.rb +2 -2
  26. data/lib/discordrb/commands/rate_limiter.rb +1 -1
  27. data/lib/discordrb/container.rb +132 -3
  28. data/lib/discordrb/data/attachment.rb +15 -0
  29. data/lib/discordrb/data/audit_logs.rb +3 -3
  30. data/lib/discordrb/data/channel.rb +167 -23
  31. data/lib/discordrb/data/component.rb +229 -0
  32. data/lib/discordrb/data/integration.rb +42 -3
  33. data/lib/discordrb/data/interaction.rb +800 -0
  34. data/lib/discordrb/data/invite.rb +1 -1
  35. data/lib/discordrb/data/member.rb +108 -33
  36. data/lib/discordrb/data/message.rb +99 -19
  37. data/lib/discordrb/data/overwrite.rb +13 -7
  38. data/lib/discordrb/data/role.rb +58 -1
  39. data/lib/discordrb/data/server.rb +82 -80
  40. data/lib/discordrb/data/user.rb +69 -9
  41. data/lib/discordrb/data/webhook.rb +97 -4
  42. data/lib/discordrb/data.rb +3 -0
  43. data/lib/discordrb/errors.rb +44 -3
  44. data/lib/discordrb/events/channels.rb +1 -1
  45. data/lib/discordrb/events/interactions.rb +482 -0
  46. data/lib/discordrb/events/message.rb +9 -6
  47. data/lib/discordrb/events/presence.rb +21 -14
  48. data/lib/discordrb/events/reactions.rb +0 -1
  49. data/lib/discordrb/events/threads.rb +96 -0
  50. data/lib/discordrb/gateway.rb +30 -17
  51. data/lib/discordrb/permissions.rb +59 -34
  52. data/lib/discordrb/version.rb +1 -1
  53. data/lib/discordrb/voice/encoder.rb +2 -2
  54. data/lib/discordrb/voice/network.rb +18 -7
  55. data/lib/discordrb/voice/sodium.rb +3 -1
  56. data/lib/discordrb/voice/voice_bot.rb +3 -3
  57. data/lib/discordrb/webhooks.rb +2 -0
  58. data/lib/discordrb.rb +37 -4
  59. metadata +48 -14
  60. data/.codeclimate.yml +0 -16
  61. data/.travis.yml +0 -32
  62. data/bin/travis_build_docs.sh +0 -17
@@ -0,0 +1,229 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Discordrb
4
+ # Components are interactable interfaces that can be attached to messages.
5
+ module Components
6
+ # @deprecated This alias will be removed in future releases.
7
+ class View < Webhooks::View
8
+ end
9
+
10
+ # @!visibility private
11
+ def self.from_data(data, bot)
12
+ case data['type']
13
+ when Webhooks::View::COMPONENT_TYPES[:action_row]
14
+ ActionRow.new(data, bot)
15
+ when Webhooks::View::COMPONENT_TYPES[:button]
16
+ Button.new(data, bot)
17
+ when Webhooks::View::COMPONENT_TYPES[:string_select]
18
+ SelectMenu.new(data, bot)
19
+ when Webhooks::Modal::COMPONENT_TYPES[:text_input]
20
+ TextInput.new(data, bot)
21
+ end
22
+ end
23
+
24
+ # Represents a row of components
25
+ class ActionRow
26
+ include Enumerable
27
+
28
+ # @return [Array<Button>]
29
+ attr_reader :components
30
+
31
+ # @!visibility private
32
+ def initialize(data, bot)
33
+ @bot = bot
34
+ @components = data['components'].map { |component_data| Components.from_data(component_data, @bot) }
35
+ end
36
+
37
+ # Iterate over each component in the row.
38
+ def each(&block)
39
+ @components.each(&block)
40
+ end
41
+
42
+ # Get all buttons in this row
43
+ # @return [Array<Button>]
44
+ def buttons
45
+ select { |component| component.is_a? Button }
46
+ end
47
+
48
+ # Get all buttons in this row
49
+ # @return [Array<Button>]
50
+ def text_inputs
51
+ select { |component| component.is_a? TextInput }
52
+ end
53
+
54
+ # @!visibility private
55
+ def to_a
56
+ @components
57
+ end
58
+ end
59
+
60
+ # An interactable button component.
61
+ class Button
62
+ # @return [String]
63
+ attr_reader :label
64
+
65
+ # @return [Integer]
66
+ attr_reader :style
67
+
68
+ # @return [String]
69
+ attr_reader :custom_id
70
+
71
+ # @return [true, false]
72
+ attr_reader :disabled
73
+
74
+ # @return [String, nil]
75
+ attr_reader :url
76
+
77
+ # @return [Emoji, nil]
78
+ attr_reader :emoji
79
+
80
+ # @!visibility private
81
+ def initialize(data, bot)
82
+ @bot = bot
83
+
84
+ @label = data['label']
85
+ @style = data['style']
86
+ @custom_id = data['custom_id']
87
+ @disabled = data['disabled']
88
+ @url = data['url']
89
+ @emoji = Emoji.new(data['emoji'], @bot) if data['emoji']
90
+ end
91
+
92
+ # @method primary?
93
+ # @return [true, false]
94
+ # @method secondary?
95
+ # @return [true, false]
96
+ # @method success?
97
+ # @return [true, false]
98
+ # @method danger?
99
+ # @return [true, false]
100
+ # @method link?
101
+ # @return [true, false]
102
+ Webhooks::View::BUTTON_STYLES.each do |name, value|
103
+ define_method("#{name}?") do
104
+ @style == value
105
+ end
106
+ end
107
+
108
+ # Await a button click
109
+ def await_click(key, **attributes, &block)
110
+ @bot.add_await(key, Discordrb::Events::ButtonEvent, { custom_id: @custom_id }.merge(attributes), &block)
111
+ end
112
+
113
+ # Await a button click, blocking.
114
+ def await_click!(**attributes, &block)
115
+ @bot.add_await!(Discordrb::Events::ButtonEvent, { custom_id: @custom_id }.merge(attributes), &block)
116
+ end
117
+ end
118
+
119
+ # An interactable select menu component.
120
+ class SelectMenu
121
+ # A select menu option.
122
+ class Option
123
+ # @return [String]
124
+ attr_reader :label
125
+
126
+ # @return [String]
127
+ attr_reader :value
128
+
129
+ # @return [String, nil]
130
+ attr_reader :description
131
+
132
+ # @return [Emoji, nil]
133
+ attr_reader :emoji
134
+
135
+ # @!visibility hidden
136
+ def initialize(data)
137
+ @label = data['label']
138
+ @value = data['value']
139
+ @description = data['description']
140
+ @emoji = Emoji.new(data['emoji'], @bot) if data['emoji']
141
+ end
142
+ end
143
+
144
+ # @return [String]
145
+ attr_reader :custom_id
146
+
147
+ # @return [Integer, nil]
148
+ attr_reader :max_values
149
+
150
+ # @return [Integer, nil]
151
+ attr_reader :min_values
152
+
153
+ # @return [String, nil]
154
+ attr_reader :placeholder
155
+
156
+ # @return [Array<Option>]
157
+ attr_reader :options
158
+
159
+ # @!visibility private
160
+ def initialize(data, bot)
161
+ @bot = bot
162
+
163
+ @max_values = data['max_values']
164
+ @min_values = data['min_values']
165
+ @placeholder = data['placeholder']
166
+ @custom_id = data['custom_id']
167
+ @emoji = Emoji.new(data['emoji'], @bot) if data['emoji']
168
+ @options = data['options'].map { |opt| Option.new(opt) }
169
+ end
170
+ end
171
+
172
+ # Text input component for use in modals. Can be either a line (`short`), or a multi line (`paragraph`) block.
173
+ class TextInput
174
+ # Single line text input
175
+ SHORT = 1
176
+ # Multi-line text input
177
+ PARAGRAPH = 2
178
+
179
+ # @return [String]
180
+ attr_reader :custom_id
181
+
182
+ # @return [Symbol]
183
+ attr_reader :style
184
+
185
+ # @return [String]
186
+ attr_reader :label
187
+
188
+ # @return [Integer, nil]
189
+ attr_reader :min_length
190
+
191
+ # @return [Integer, nil]
192
+ attr_reader :max_length
193
+
194
+ # @return [true, false]
195
+ attr_reader :required
196
+
197
+ # @return [String, nil]
198
+ attr_reader :value
199
+
200
+ # @return [String, nil]
201
+ attr_reader :placeholder
202
+
203
+ # @!visibility private
204
+ def initialize(data, bot)
205
+ @bot = bot
206
+ @style = data['style'] == SHORT ? :short : :paragraph
207
+ @label = data['label']
208
+ @min_length = data['min_length']
209
+ @max_length = data['max_length']
210
+ @required = data['required']
211
+ @value = data['value']
212
+ @placeholder = data['placeholder']
213
+ @custom_id = data['custom_id']
214
+ end
215
+
216
+ def short?
217
+ @style == :short
218
+ end
219
+
220
+ def paragraph?
221
+ @style == :paragraph
222
+ end
223
+
224
+ def required?
225
+ @required
226
+ end
227
+ end
228
+ end
229
+ end
@@ -15,6 +15,36 @@ module Discordrb
15
15
  end
16
16
  end
17
17
 
18
+ # Bot/OAuth2 application for discord integrations
19
+ class IntegrationApplication
20
+ # @return [Integer] the ID of the application.
21
+ attr_reader :id
22
+
23
+ # @return [String] the name of the application.
24
+ attr_reader :name
25
+
26
+ # @return [String, nil] the icon hash of the application.
27
+ attr_reader :icon
28
+
29
+ # @return [String] the description of the application.
30
+ attr_reader :description
31
+
32
+ # @return [String] the summary of the application.
33
+ attr_reader :summary
34
+
35
+ # @return [User, nil] the bot associated with this application.
36
+ attr_reader :bot
37
+
38
+ def initialize(data, bot)
39
+ @id = data['id'].to_i
40
+ @name = data['name']
41
+ @icon = data['icon']
42
+ @description = data['description']
43
+ @summary = data['summary']
44
+ @bot = Discordrb::User.new(data['user'], bot) if data['user']
45
+ end
46
+ end
47
+
18
48
  # Server integration
19
49
  class Integration
20
50
  include IDObject
@@ -28,8 +58,8 @@ module Discordrb
28
58
  # @return [User] the user the integration is linked to
29
59
  attr_reader :user
30
60
 
31
- # @return [Role, nil] the role that this integration uses for "subscribers"
32
- attr_reader :role
61
+ # @return [Integer, nil] the role that this integration uses for "subscribers"
62
+ attr_reader :role_id
33
63
 
34
64
  # @return [true, false] whether emoticons are enabled
35
65
  attr_reader :emoticon
@@ -57,6 +87,12 @@ module Discordrb
57
87
  # @return [Integer] the grace period before subscribers expire (in days)
58
88
  attr_reader :expire_grace_period
59
89
 
90
+ # @return [Integer, nil] how many subscribers this integration has.
91
+ attr_reader :subscriber_count
92
+
93
+ # @return [true, false] has this integration been revoked.
94
+ attr_reader :revoked
95
+
60
96
  def initialize(data, bot, server)
61
97
  @bot = bot
62
98
 
@@ -71,8 +107,11 @@ module Discordrb
71
107
  @expire_behaviour = %i[remove kick][data['expire_behavior']]
72
108
  @expire_grace_period = data['expire_grace_period']
73
109
  @user = @bot.ensure_user(data['user'])
74
- @role = server.role(data['role_id']) || nil
110
+ @role_id = data['role_id']&.to_i
75
111
  @emoticon = data['enable_emoticons']
112
+ @subscriber_count = data['subscriber_count']&.to_i
113
+ @revoked = data['revoked']
114
+ @application = IntegrationApplication.new(data['application'], bot) if data['application']
76
115
  end
77
116
 
78
117
  # The inspect method is overwritten to give more useful output