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