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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +44 -18
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -1
- data/.github/ISSUE_TEMPLATE/feature_request.md +0 -1
- data/.github/workflows/codeql.yml +65 -0
- data/.markdownlint.json +4 -0
- data/.rubocop.yml +8 -2
- data/CHANGELOG.md +390 -225
- data/LICENSE.txt +1 -1
- data/README.md +37 -25
- data/discordrb-webhooks.gemspec +4 -1
- data/discordrb.gemspec +9 -6
- data/lib/discordrb/api/application.rb +202 -0
- data/lib/discordrb/api/channel.rb +177 -11
- data/lib/discordrb/api/interaction.rb +54 -0
- data/lib/discordrb/api/invite.rb +2 -2
- data/lib/discordrb/api/server.rb +40 -19
- data/lib/discordrb/api/user.rb +8 -3
- data/lib/discordrb/api/webhook.rb +57 -0
- data/lib/discordrb/api.rb +19 -5
- data/lib/discordrb/bot.rb +317 -32
- data/lib/discordrb/cache.rb +27 -22
- data/lib/discordrb/commands/command_bot.rb +6 -4
- data/lib/discordrb/commands/container.rb +1 -1
- data/lib/discordrb/commands/parser.rb +2 -2
- data/lib/discordrb/commands/rate_limiter.rb +1 -1
- data/lib/discordrb/container.rb +132 -3
- data/lib/discordrb/data/attachment.rb +15 -0
- data/lib/discordrb/data/audit_logs.rb +3 -3
- data/lib/discordrb/data/channel.rb +167 -23
- data/lib/discordrb/data/component.rb +229 -0
- data/lib/discordrb/data/integration.rb +42 -3
- data/lib/discordrb/data/interaction.rb +800 -0
- data/lib/discordrb/data/invite.rb +1 -1
- data/lib/discordrb/data/member.rb +108 -33
- data/lib/discordrb/data/message.rb +99 -19
- data/lib/discordrb/data/overwrite.rb +13 -7
- data/lib/discordrb/data/role.rb +58 -1
- data/lib/discordrb/data/server.rb +82 -80
- data/lib/discordrb/data/user.rb +69 -9
- data/lib/discordrb/data/webhook.rb +97 -4
- data/lib/discordrb/data.rb +3 -0
- data/lib/discordrb/errors.rb +44 -3
- data/lib/discordrb/events/channels.rb +1 -1
- data/lib/discordrb/events/interactions.rb +482 -0
- data/lib/discordrb/events/message.rb +9 -6
- data/lib/discordrb/events/presence.rb +21 -14
- data/lib/discordrb/events/reactions.rb +0 -1
- data/lib/discordrb/events/threads.rb +96 -0
- data/lib/discordrb/gateway.rb +30 -17
- data/lib/discordrb/permissions.rb +59 -34
- data/lib/discordrb/version.rb +1 -1
- data/lib/discordrb/voice/encoder.rb +2 -2
- data/lib/discordrb/voice/network.rb +18 -7
- data/lib/discordrb/voice/sodium.rb +3 -1
- data/lib/discordrb/voice/voice_bot.rb +3 -3
- data/lib/discordrb/webhooks.rb +2 -0
- data/lib/discordrb.rb +37 -4
- metadata +48 -14
- data/.codeclimate.yml +0 -16
- data/.travis.yml +0 -32
- 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 [
|
32
|
-
attr_reader :
|
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
|
-
@
|
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
|