rubycord 1.0.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 +7 -0
- data/lib/rubycord/allowed_mentions.rb +34 -0
- data/lib/rubycord/api/application.rb +200 -0
- data/lib/rubycord/api/channel.rb +597 -0
- data/lib/rubycord/api/interaction.rb +52 -0
- data/lib/rubycord/api/invite.rb +42 -0
- data/lib/rubycord/api/server.rb +557 -0
- data/lib/rubycord/api/user.rb +153 -0
- data/lib/rubycord/api/webhook.rb +138 -0
- data/lib/rubycord/api.rb +356 -0
- data/lib/rubycord/await.rb +49 -0
- data/lib/rubycord/bot.rb +1757 -0
- data/lib/rubycord/cache.rb +259 -0
- data/lib/rubycord/colour_rgb.rb +41 -0
- data/lib/rubycord/commands/command_bot.rb +519 -0
- data/lib/rubycord/commands/container.rb +110 -0
- data/lib/rubycord/commands/events.rb +9 -0
- data/lib/rubycord/commands/parser.rb +325 -0
- data/lib/rubycord/commands/rate_limiter.rb +142 -0
- data/lib/rubycord/container.rb +753 -0
- data/lib/rubycord/data/activity.rb +269 -0
- data/lib/rubycord/data/application.rb +48 -0
- data/lib/rubycord/data/attachment.rb +109 -0
- data/lib/rubycord/data/audit_logs.rb +343 -0
- data/lib/rubycord/data/channel.rb +996 -0
- data/lib/rubycord/data/component.rb +227 -0
- data/lib/rubycord/data/embed.rb +249 -0
- data/lib/rubycord/data/emoji.rb +80 -0
- data/lib/rubycord/data/integration.rb +120 -0
- data/lib/rubycord/data/interaction.rb +798 -0
- data/lib/rubycord/data/invite.rb +135 -0
- data/lib/rubycord/data/member.rb +370 -0
- data/lib/rubycord/data/message.rb +412 -0
- data/lib/rubycord/data/overwrite.rb +106 -0
- data/lib/rubycord/data/profile.rb +89 -0
- data/lib/rubycord/data/reaction.rb +31 -0
- data/lib/rubycord/data/recipient.rb +32 -0
- data/lib/rubycord/data/role.rb +246 -0
- data/lib/rubycord/data/server.rb +1002 -0
- data/lib/rubycord/data/user.rb +261 -0
- data/lib/rubycord/data/voice_region.rb +43 -0
- data/lib/rubycord/data/voice_state.rb +39 -0
- data/lib/rubycord/data/webhook.rb +232 -0
- data/lib/rubycord/data.rb +40 -0
- data/lib/rubycord/errors.rb +737 -0
- data/lib/rubycord/events/await.rb +46 -0
- data/lib/rubycord/events/bans.rb +58 -0
- data/lib/rubycord/events/channels.rb +186 -0
- data/lib/rubycord/events/generic.rb +126 -0
- data/lib/rubycord/events/guilds.rb +191 -0
- data/lib/rubycord/events/interactions.rb +480 -0
- data/lib/rubycord/events/invites.rb +123 -0
- data/lib/rubycord/events/lifetime.rb +29 -0
- data/lib/rubycord/events/members.rb +91 -0
- data/lib/rubycord/events/message.rb +337 -0
- data/lib/rubycord/events/presence.rb +127 -0
- data/lib/rubycord/events/raw.rb +45 -0
- data/lib/rubycord/events/reactions.rb +156 -0
- data/lib/rubycord/events/roles.rb +86 -0
- data/lib/rubycord/events/threads.rb +94 -0
- data/lib/rubycord/events/typing.rb +70 -0
- data/lib/rubycord/events/voice_server_update.rb +45 -0
- data/lib/rubycord/events/voice_state_update.rb +103 -0
- data/lib/rubycord/events/webhooks.rb +62 -0
- data/lib/rubycord/gateway.rb +867 -0
- data/lib/rubycord/id_object.rb +37 -0
- data/lib/rubycord/light/data.rb +60 -0
- data/lib/rubycord/light/integrations.rb +71 -0
- data/lib/rubycord/light/light_bot.rb +56 -0
- data/lib/rubycord/light.rb +6 -0
- data/lib/rubycord/logger.rb +118 -0
- data/lib/rubycord/paginator.rb +55 -0
- data/lib/rubycord/permissions.rb +251 -0
- data/lib/rubycord/version.rb +5 -0
- data/lib/rubycord/voice/encoder.rb +113 -0
- data/lib/rubycord/voice/network.rb +366 -0
- data/lib/rubycord/voice/sodium.rb +96 -0
- data/lib/rubycord/voice/voice_bot.rb +408 -0
- data/lib/rubycord/webhooks/builder.rb +100 -0
- data/lib/rubycord/webhooks/client.rb +132 -0
- data/lib/rubycord/webhooks/embeds.rb +248 -0
- data/lib/rubycord/webhooks/modal.rb +78 -0
- data/lib/rubycord/webhooks/version.rb +7 -0
- data/lib/rubycord/webhooks/view.rb +192 -0
- data/lib/rubycord/webhooks.rb +12 -0
- data/lib/rubycord/websocket.rb +70 -0
- data/lib/rubycord.rb +140 -0
- metadata +231 -0
@@ -0,0 +1,248 @@
|
|
1
|
+
module Rubycord::Webhooks
|
2
|
+
# An embed is a multipart-style attachment to a webhook message that can have a variety of different purposes and
|
3
|
+
# appearances.
|
4
|
+
class Embed
|
5
|
+
def initialize(title: nil, description: nil, url: nil, timestamp: nil, colour: nil, color: nil, footer: nil,
|
6
|
+
image: nil, thumbnail: nil, video: nil, provider: nil, author: nil, fields: [])
|
7
|
+
@title = title
|
8
|
+
@description = description
|
9
|
+
@url = url
|
10
|
+
@timestamp = timestamp
|
11
|
+
self.colour = colour || color
|
12
|
+
@footer = footer
|
13
|
+
@image = image
|
14
|
+
@thumbnail = thumbnail
|
15
|
+
@video = video
|
16
|
+
@provider = provider
|
17
|
+
@author = author
|
18
|
+
@fields = fields
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [String, nil] title of the embed that will be displayed above everything else.
|
22
|
+
attr_accessor :title
|
23
|
+
|
24
|
+
# @return [String, nil] description for this embed
|
25
|
+
attr_accessor :description
|
26
|
+
|
27
|
+
# @return [String, nil] URL the title should point to
|
28
|
+
attr_accessor :url
|
29
|
+
|
30
|
+
# @return [Time, nil] timestamp for this embed. Will be displayed just below the title.
|
31
|
+
attr_accessor :timestamp
|
32
|
+
|
33
|
+
# @return [Integer, nil] the colour of the bar to the side, in decimal form
|
34
|
+
attr_reader :colour
|
35
|
+
alias_method :color, :colour
|
36
|
+
|
37
|
+
# Sets the colour of the bar to the side of the embed to something new.
|
38
|
+
# @param value [String, Integer, {Integer, Integer, Integer}, #to_i, nil] The colour in decimal, hexadecimal, R/G/B decimal, or nil to clear the embeds colour
|
39
|
+
# form.
|
40
|
+
def colour=(value)
|
41
|
+
if value.nil?
|
42
|
+
@colour = nil
|
43
|
+
elsif value.is_a? Integer
|
44
|
+
raise ArgumentError, "Embed colour must be 24-bit!" if value >= 16_777_216
|
45
|
+
|
46
|
+
@colour = value
|
47
|
+
elsif value.is_a? String
|
48
|
+
self.colour = value.delete("#").to_i(16)
|
49
|
+
elsif value.is_a? Array
|
50
|
+
raise ArgumentError, "Colour tuple must have three values!" if value.length != 3
|
51
|
+
|
52
|
+
self.colour = (value[0] << 16) | (value[1] << 8) | value[2]
|
53
|
+
else
|
54
|
+
self.colour = value.to_i
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
alias_method :color=, :colour=
|
59
|
+
|
60
|
+
# @example Add a footer to an embed
|
61
|
+
# embed.footer = Rubycord::Webhooks::EmbedFooter.new(text: 'Hello', icon_url: 'https://i.imgur.com/j69wMDu.jpg')
|
62
|
+
# @return [EmbedFooter, nil] footer for this embed
|
63
|
+
attr_accessor :footer
|
64
|
+
|
65
|
+
# @see EmbedImage
|
66
|
+
# @example Add a image to an embed
|
67
|
+
# embed.image = Rubycord::Webhooks::EmbedImage.new(url: 'https://i.imgur.com/PcMltU7.jpg')
|
68
|
+
# @return [EmbedImage, nil] image for this embed
|
69
|
+
attr_accessor :image
|
70
|
+
|
71
|
+
# @see EmbedThumbnail
|
72
|
+
# @example Add a thumbnail to an embed
|
73
|
+
# embed.thumbnail = Rubycord::Webhooks::EmbedThumbnail.new(url: 'https://i.imgur.com/xTG3a1I.jpg')
|
74
|
+
# @return [EmbedThumbnail, nil] thumbnail for this embed
|
75
|
+
attr_accessor :thumbnail
|
76
|
+
|
77
|
+
# @see EmbedAuthor
|
78
|
+
# @example Add a author to an embed
|
79
|
+
# embed.author = Rubycord::Webhooks::EmbedAuthor.new(name: 'meew0', url: 'https://github.com/meew0', icon_url: 'https://avatars2.githubusercontent.com/u/3662915?v=3&s=466')
|
80
|
+
# @return [EmbedAuthor, nil] author for this embed
|
81
|
+
attr_accessor :author
|
82
|
+
|
83
|
+
# Add a field object to this embed.
|
84
|
+
# @param field [EmbedField] The field to add.
|
85
|
+
def <<(field)
|
86
|
+
@fields << field
|
87
|
+
end
|
88
|
+
|
89
|
+
# Convenience method to add a field to the embed without having to create one manually.
|
90
|
+
# @see EmbedField
|
91
|
+
# @example Add a field to an embed, conveniently
|
92
|
+
# embed.add_field(name: 'A field', value: "The field's content")
|
93
|
+
# @param name [String] The field's name
|
94
|
+
# @param value [String] The field's value
|
95
|
+
# @param inline [true, false] Whether the field should be inline
|
96
|
+
def add_field(name: nil, value: nil, inline: nil)
|
97
|
+
self << EmbedField.new(name: name, value: value, inline: inline)
|
98
|
+
end
|
99
|
+
|
100
|
+
# @return [Array<EmbedField>] the fields attached to this embed.
|
101
|
+
attr_accessor :fields
|
102
|
+
|
103
|
+
# @return [Hash] a hash representation of this embed, to be converted to JSON.
|
104
|
+
def to_hash
|
105
|
+
{
|
106
|
+
title: @title,
|
107
|
+
description: @description,
|
108
|
+
url: @url,
|
109
|
+
timestamp: @timestamp&.utc&.iso8601,
|
110
|
+
color: @colour,
|
111
|
+
footer: @footer&.to_hash,
|
112
|
+
image: @image&.to_hash,
|
113
|
+
thumbnail: @thumbnail&.to_hash,
|
114
|
+
video: @video&.to_hash,
|
115
|
+
provider: @provider&.to_hash,
|
116
|
+
author: @author&.to_hash,
|
117
|
+
fields: @fields.map(&:to_hash)
|
118
|
+
}
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# An embed's footer will be displayed at the very bottom of an embed, together with the timestamp. An icon URL can be
|
123
|
+
# set together with some text to be displayed.
|
124
|
+
class EmbedFooter
|
125
|
+
# @return [String, nil] text to be displayed in the footer
|
126
|
+
attr_accessor :text
|
127
|
+
|
128
|
+
# @return [String, nil] URL to an icon to be showed alongside the text
|
129
|
+
attr_accessor :icon_url
|
130
|
+
|
131
|
+
# Creates a new footer object.
|
132
|
+
# @param text [String, nil] The text to be displayed in the footer.
|
133
|
+
# @param icon_url [String, nil] The URL to an icon to be showed alongside the text.
|
134
|
+
def initialize(text: nil, icon_url: nil)
|
135
|
+
@text = text
|
136
|
+
@icon_url = icon_url
|
137
|
+
end
|
138
|
+
|
139
|
+
# @return [Hash] a hash representation of this embed footer, to be converted to JSON.
|
140
|
+
def to_hash
|
141
|
+
{
|
142
|
+
text: @text,
|
143
|
+
icon_url: @icon_url
|
144
|
+
}
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# An embed's image will be displayed at the bottom, in large format. It will replace a footer icon URL if one is set.
|
149
|
+
class EmbedImage
|
150
|
+
# @return [String, nil] URL of the image
|
151
|
+
attr_accessor :url
|
152
|
+
|
153
|
+
# Creates a new image object.
|
154
|
+
# @param url [String, nil] The URL of the image.
|
155
|
+
def initialize(url: nil)
|
156
|
+
@url = url
|
157
|
+
end
|
158
|
+
|
159
|
+
# @return [Hash] a hash representation of this embed image, to be converted to JSON.
|
160
|
+
def to_hash
|
161
|
+
{
|
162
|
+
url: @url
|
163
|
+
}
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
# An embed's thumbnail will be displayed at the right of the message, next to the description and fields. When clicked
|
168
|
+
# it will point to the embed URL.
|
169
|
+
class EmbedThumbnail
|
170
|
+
# @return [String, nil] URL of the thumbnail
|
171
|
+
attr_accessor :url
|
172
|
+
|
173
|
+
# Creates a new thumbnail object.
|
174
|
+
# @param url [String, nil] The URL of the thumbnail.
|
175
|
+
def initialize(url: nil)
|
176
|
+
@url = url
|
177
|
+
end
|
178
|
+
|
179
|
+
# @return [Hash] a hash representation of this embed thumbnail, to be converted to JSON.
|
180
|
+
def to_hash
|
181
|
+
{
|
182
|
+
url: @url
|
183
|
+
}
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# An embed's author will be shown at the top to indicate who "authored" the particular event the webhook was sent for.
|
188
|
+
class EmbedAuthor
|
189
|
+
# @return [String, nil] name of the author
|
190
|
+
attr_accessor :name
|
191
|
+
|
192
|
+
# @return [String, nil] URL the name should link to
|
193
|
+
attr_accessor :url
|
194
|
+
|
195
|
+
# @return [String, nil] URL of the icon to be displayed next to the author
|
196
|
+
attr_accessor :icon_url
|
197
|
+
|
198
|
+
# Creates a new author object.
|
199
|
+
# @param name [String, nil] The name of the author.
|
200
|
+
# @param url [String, nil] The URL the name should link to.
|
201
|
+
# @param icon_url [String, nil] The URL of the icon to be displayed next to the author.
|
202
|
+
def initialize(name: nil, url: nil, icon_url: nil)
|
203
|
+
@name = name
|
204
|
+
@url = url
|
205
|
+
@icon_url = icon_url
|
206
|
+
end
|
207
|
+
|
208
|
+
# @return [Hash] a hash representation of this embed author, to be converted to JSON.
|
209
|
+
def to_hash
|
210
|
+
{
|
211
|
+
name: @name,
|
212
|
+
url: @url,
|
213
|
+
icon_url: @icon_url
|
214
|
+
}
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
# A field is a small block of text with a header that can be relatively freely layouted with other fields.
|
219
|
+
class EmbedField
|
220
|
+
# @return [String, nil] name of the field, displayed in bold at the top of the field.
|
221
|
+
attr_accessor :name
|
222
|
+
|
223
|
+
# @return [String, nil] value of the field, displayed in normal text below the name.
|
224
|
+
attr_accessor :value
|
225
|
+
|
226
|
+
# @return [true, false] whether the field should be displayed inline with other fields.
|
227
|
+
attr_accessor :inline
|
228
|
+
|
229
|
+
# Creates a new field object.
|
230
|
+
# @param name [String, nil] The name of the field, displayed in bold at the top of the field.
|
231
|
+
# @param value [String, nil] The value of the field, displayed in normal text below the name.
|
232
|
+
# @param inline [true, false] Whether the field should be displayed inline with other fields.
|
233
|
+
def initialize(name: nil, value: nil, inline: false)
|
234
|
+
@name = name
|
235
|
+
@value = value
|
236
|
+
@inline = inline
|
237
|
+
end
|
238
|
+
|
239
|
+
# @return [Hash] a hash representation of this embed field, to be converted to JSON.
|
240
|
+
def to_hash
|
241
|
+
{
|
242
|
+
name: @name,
|
243
|
+
value: @value,
|
244
|
+
inline: @inline
|
245
|
+
}
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# Modal component builder.
|
2
|
+
class Rubycord::Webhooks::Modal
|
3
|
+
# A mapping of names to types of components usable in a modal.
|
4
|
+
COMPONENT_TYPES = {
|
5
|
+
action_row: 1,
|
6
|
+
text_input: 4
|
7
|
+
}.freeze
|
8
|
+
|
9
|
+
# This builder is used when constructing an ActionRow. All current components must be within an action row, but this can
|
10
|
+
# change in the future. A message can have 5 action rows, each action row can hold a weight of 5. Buttons have a weight of 1,
|
11
|
+
# and dropdowns have a weight of 5.
|
12
|
+
class RowBuilder
|
13
|
+
# A mapping of short names to types of input styles. `short` is a single line where `paragraph` is a block.
|
14
|
+
TEXT_INPUT_STYLES = {
|
15
|
+
short: 1,
|
16
|
+
paragraph: 2
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
# @!visibility private
|
20
|
+
def initialize
|
21
|
+
@components = []
|
22
|
+
end
|
23
|
+
|
24
|
+
# Add a text input to this action row.
|
25
|
+
# @param style [Symbol, Integer] The text input's style type. See {TEXT_INPUT_STYLES}
|
26
|
+
# @param custom_id [String] Custom IDs are used to pass state to the events that are raised from interactions.
|
27
|
+
# There is a limit of 100 characters to each custom_id.
|
28
|
+
# @param label [String, nil] The text label for the field.
|
29
|
+
# @param min_length [Integer, nil] The minimum input length for a text input, min 0, max 4000.
|
30
|
+
# @param max_length [Integer, nil] The maximum input length for a text input, min 1, max 4000.
|
31
|
+
# @param required [true, false, nil] Whether this component is required to be filled, default true.
|
32
|
+
# @param value [String, nil] A pre-filled value for this component, max 4000 characters.
|
33
|
+
# @param placeholder [String, nil] Custom placeholder text if the input is empty, max 100 characters
|
34
|
+
def text_input(style:, custom_id:, label: nil, min_length: nil, max_length: nil, required: nil, value: nil, placeholder: nil)
|
35
|
+
style = TEXT_INPUT_STYLES[style] || style
|
36
|
+
|
37
|
+
@components << {
|
38
|
+
style: style,
|
39
|
+
custom_id: custom_id,
|
40
|
+
type: COMPONENT_TYPES[:text_input],
|
41
|
+
label: label,
|
42
|
+
min_length: min_length,
|
43
|
+
max_length: max_length,
|
44
|
+
required: required,
|
45
|
+
value: value,
|
46
|
+
placeholder: placeholder
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
# @!visibility private
|
51
|
+
def to_h
|
52
|
+
{type: COMPONENT_TYPES[:action_row], components: @components}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
attr_reader :rows
|
57
|
+
|
58
|
+
def initialize
|
59
|
+
@rows = []
|
60
|
+
|
61
|
+
yield self if block_given?
|
62
|
+
end
|
63
|
+
|
64
|
+
# Add a new ActionRow to the view
|
65
|
+
# @yieldparam [RowBuilder]
|
66
|
+
def row
|
67
|
+
new_row = RowBuilder.new
|
68
|
+
|
69
|
+
yield new_row
|
70
|
+
|
71
|
+
@rows << new_row
|
72
|
+
end
|
73
|
+
|
74
|
+
# @!visibility private
|
75
|
+
def to_a
|
76
|
+
@rows.map(&:to_h)
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
# A reusable view representing a component collection, with builder methods.
|
2
|
+
class Rubycord::Webhooks::View
|
3
|
+
# Possible button style names and values.
|
4
|
+
BUTTON_STYLES = {
|
5
|
+
primary: 1,
|
6
|
+
secondary: 2,
|
7
|
+
success: 3,
|
8
|
+
danger: 4,
|
9
|
+
link: 5
|
10
|
+
}.freeze
|
11
|
+
|
12
|
+
# Component types.
|
13
|
+
# @see https://discord.com/developers/docs/interactions/message-components#component-types
|
14
|
+
COMPONENT_TYPES = {
|
15
|
+
action_row: 1,
|
16
|
+
button: 2,
|
17
|
+
string_select: 3,
|
18
|
+
# text_input: 4, # (defined in modal.rb)
|
19
|
+
user_select: 5,
|
20
|
+
role_select: 6,
|
21
|
+
mentionable_select: 7,
|
22
|
+
channel_select: 8
|
23
|
+
}.freeze
|
24
|
+
|
25
|
+
# This builder is used when constructing an ActionRow. All current components must be within an action row, but this can
|
26
|
+
# change in the future. A message can have 5 action rows, each action row can hold a weight of 5. Buttons have a weight of 1,
|
27
|
+
# and dropdowns have a weight of 5.
|
28
|
+
class RowBuilder
|
29
|
+
# @!visibility private
|
30
|
+
def initialize
|
31
|
+
@components = []
|
32
|
+
end
|
33
|
+
|
34
|
+
# Add a button to this action row.
|
35
|
+
# @param style [Symbol, Integer] The button's style type. See {BUTTON_STYLES}
|
36
|
+
# @param label [String, nil] The text label for the button. Either a label or emoji must be provided.
|
37
|
+
# @param emoji [#to_h, String, Integer] An emoji ID, or unicode emoji to attach to the button. Can also be a object
|
38
|
+
# that responds to `#to_h` which returns a hash in the format of `{ id: Integer, name: string }`.
|
39
|
+
# @param custom_id [String] Custom IDs are used to pass state to the events that are raised from interactions.
|
40
|
+
# There is a limit of 100 characters to each custom_id.
|
41
|
+
# @param disabled [true, false] Whether this button is disabled and shown as greyed out.
|
42
|
+
# @param url [String, nil] The URL, when using a link style button.
|
43
|
+
def button(style:, label: nil, emoji: nil, custom_id: nil, disabled: nil, url: nil)
|
44
|
+
style = BUTTON_STYLES[style] || style
|
45
|
+
|
46
|
+
emoji = case emoji
|
47
|
+
when Integer, String
|
48
|
+
emoji.to_i.positive? ? {id: emoji} : {name: emoji}
|
49
|
+
else
|
50
|
+
emoji&.to_h
|
51
|
+
end
|
52
|
+
|
53
|
+
@components << {type: COMPONENT_TYPES[:button], label: label, emoji: emoji, style: style, custom_id: custom_id, disabled: disabled, url: url}
|
54
|
+
end
|
55
|
+
|
56
|
+
# Add a select string to this action row.
|
57
|
+
# @param custom_id [String] Custom IDs are used to pass state to the events that are raised from interactions.
|
58
|
+
# There is a limit of 100 characters to each custom_id.
|
59
|
+
# @param options [Array<Hash>] Options that can be selected in this menu. Can also be provided via the yielded builder.
|
60
|
+
# @param placeholder [String, nil] Default text to show when no entries are selected.
|
61
|
+
# @param min_values [Integer, nil] The minimum amount of values a user must select.
|
62
|
+
# @param max_values [Integer, nil] The maximum amount of values a user can select.
|
63
|
+
# @param disabled [true, false, nil] Grey out the component to make it unusable.
|
64
|
+
# @yieldparam builder [SelectMenuBuilder]
|
65
|
+
def string_select(custom_id:, options: [], placeholder: nil, min_values: nil, max_values: nil, disabled: nil)
|
66
|
+
builder = SelectMenuBuilder.new(custom_id, options, placeholder, min_values, max_values, disabled, select_type: :string_select)
|
67
|
+
|
68
|
+
yield builder if block_given?
|
69
|
+
|
70
|
+
@components << builder.to_h
|
71
|
+
end
|
72
|
+
|
73
|
+
alias_method :select_menu, :string_select
|
74
|
+
|
75
|
+
# Add a select user to this action row.
|
76
|
+
# @param custom_id [String] Custom IDs are used to pass state to the events that are raised from interactions.
|
77
|
+
# There is a limit of 100 characters to each custom_id.
|
78
|
+
# @param placeholder [String, nil] Default text to show when no entries are selected.
|
79
|
+
# @param min_values [Integer, nil] The minimum amount of values a user must select.
|
80
|
+
# @param max_values [Integer, nil] The maximum amount of values a user can select.
|
81
|
+
# @param disabled [true, false, nil] Grey out the component to make it unusable.
|
82
|
+
def user_select(custom_id:, placeholder: nil, min_values: nil, max_values: nil, disabled: nil)
|
83
|
+
@components << SelectMenuBuilder.new(custom_id, [], placeholder, min_values, max_values, disabled, select_type: :user_select).to_h
|
84
|
+
end
|
85
|
+
|
86
|
+
# Add a select role to this action row.
|
87
|
+
# @param custom_id [String] Custom IDs are used to pass state to the events that are raised from interactions.
|
88
|
+
# There is a limit of 100 characters to each custom_id.
|
89
|
+
# @param placeholder [String, nil] Default text to show when no entries are selected.
|
90
|
+
# @param min_values [Integer, nil] The minimum amount of values a user must select.
|
91
|
+
# @param max_values [Integer, nil] The maximum amount of values a user can select.
|
92
|
+
# @param disabled [true, false, nil] Grey out the component to make it unusable.
|
93
|
+
def role_select(custom_id:, placeholder: nil, min_values: nil, max_values: nil, disabled: nil)
|
94
|
+
@components << SelectMenuBuilder.new(custom_id, [], placeholder, min_values, max_values, disabled, select_type: :role_select).to_h
|
95
|
+
end
|
96
|
+
|
97
|
+
# Add a select mentionable to this action row.
|
98
|
+
# @param custom_id [String] Custom IDs are used to pass state to the events that are raised from interactions.
|
99
|
+
# There is a limit of 100 characters to each custom_id.
|
100
|
+
# @param placeholder [String, nil] Default text to show when no entries are selected.
|
101
|
+
# @param min_values [Integer, nil] The minimum amount of values a user must select.
|
102
|
+
# @param max_values [Integer, nil] The maximum amount of values a user can select.
|
103
|
+
# @param disabled [true, false, nil] Grey out the component to make it unusable.
|
104
|
+
def mentionable_select(custom_id:, placeholder: nil, min_values: nil, max_values: nil, disabled: nil)
|
105
|
+
@components << SelectMenuBuilder.new(custom_id, [], placeholder, min_values, max_values, disabled, select_type: :mentionable_select).to_h
|
106
|
+
end
|
107
|
+
|
108
|
+
# Add a select channel to this action row.
|
109
|
+
# @param custom_id [String] Custom IDs are used to pass state to the events that are raised from interactions.
|
110
|
+
# There is a limit of 100 characters to each custom_id.
|
111
|
+
# @param placeholder [String, nil] Default text to show when no entries are selected.
|
112
|
+
# @param min_values [Integer, nil] The minimum amount of values a user must select.
|
113
|
+
# @param max_values [Integer, nil] The maximum amount of values a user can select.
|
114
|
+
# @param disabled [true, false, nil] Grey out the component to make it unusable.
|
115
|
+
def channel_select(custom_id:, placeholder: nil, min_values: nil, max_values: nil, disabled: nil)
|
116
|
+
@components << SelectMenuBuilder.new(custom_id, [], placeholder, min_values, max_values, disabled, select_type: :channel_select).to_h
|
117
|
+
end
|
118
|
+
|
119
|
+
# @!visibility private
|
120
|
+
def to_h
|
121
|
+
{type: COMPONENT_TYPES[:action_row], components: @components}
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# A builder to assist in adding options to select menus.
|
126
|
+
class SelectMenuBuilder
|
127
|
+
# @!visibility hidden
|
128
|
+
def initialize(custom_id, options = [], placeholder = nil, min_values = nil, max_values = nil, disabled = nil, select_type: :string_select)
|
129
|
+
@custom_id = custom_id
|
130
|
+
@options = options
|
131
|
+
@placeholder = placeholder
|
132
|
+
@min_values = min_values
|
133
|
+
@max_values = max_values
|
134
|
+
@disabled = disabled
|
135
|
+
@select_type = select_type
|
136
|
+
end
|
137
|
+
|
138
|
+
# Add an option to this select menu.
|
139
|
+
# @param label [String] The title of this option.
|
140
|
+
# @param value [String] The value that this option represents.
|
141
|
+
# @param description [String, nil] An optional description of the option.
|
142
|
+
# @param emoji [#to_h, String, Integer] An emoji ID, or unicode emoji to attach to the button. Can also be a object
|
143
|
+
# that responds to `#to_h` which returns a hash in the format of `{ id: Integer, name: string }`.
|
144
|
+
# @param default [true, false, nil] Whether this is the default selected option.
|
145
|
+
def option(label:, value:, description: nil, emoji: nil, default: nil)
|
146
|
+
emoji = case emoji
|
147
|
+
when Integer, String
|
148
|
+
emoji.to_i.positive? ? {id: emoji} : {name: emoji}
|
149
|
+
else
|
150
|
+
emoji&.to_h
|
151
|
+
end
|
152
|
+
|
153
|
+
@options << {label: label, value: value, description: description, emoji: emoji, default: default}
|
154
|
+
end
|
155
|
+
|
156
|
+
# @!visibility private
|
157
|
+
def to_h
|
158
|
+
{
|
159
|
+
type: COMPONENT_TYPES[@select_type],
|
160
|
+
options: @options,
|
161
|
+
placeholder: @placeholder,
|
162
|
+
min_values: @min_values,
|
163
|
+
max_values: @max_values,
|
164
|
+
custom_id: @custom_id,
|
165
|
+
disabled: @disabled
|
166
|
+
}
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
attr_reader :rows
|
171
|
+
|
172
|
+
def initialize
|
173
|
+
@rows = []
|
174
|
+
|
175
|
+
yield self if block_given?
|
176
|
+
end
|
177
|
+
|
178
|
+
# Add a new ActionRow to the view
|
179
|
+
# @yieldparam [RowBuilder]
|
180
|
+
def row
|
181
|
+
new_row = RowBuilder.new
|
182
|
+
|
183
|
+
yield new_row
|
184
|
+
|
185
|
+
@rows << new_row
|
186
|
+
end
|
187
|
+
|
188
|
+
# @!visibility private
|
189
|
+
def to_a
|
190
|
+
@rows.map(&:to_h)
|
191
|
+
end
|
192
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require "rubycord/webhooks/version"
|
2
|
+
require "rubycord/webhooks/embeds"
|
3
|
+
require "rubycord/webhooks/client"
|
4
|
+
require "rubycord/webhooks/builder"
|
5
|
+
require "rubycord/webhooks/view"
|
6
|
+
require "rubycord/webhooks/modal"
|
7
|
+
|
8
|
+
module Rubycord
|
9
|
+
# Webhook client
|
10
|
+
module Webhooks
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require "websocket-client-simple"
|
2
|
+
|
3
|
+
# The WSCS module which we're hooking
|
4
|
+
# @see Websocket::Client::Simple::Client
|
5
|
+
module WebSocket::Client::Simple
|
6
|
+
# Patch to the WSCS class to allow reading the internal thread
|
7
|
+
class Client
|
8
|
+
# @return [Thread] the internal thread this client is using for the event loop.
|
9
|
+
attr_reader :thread
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module Rubycord
|
14
|
+
# Utility wrapper class that abstracts an instance of WSCS. Useful should we decide that WSCS isn't good either -
|
15
|
+
# in that case we can just switch to something else
|
16
|
+
class WebSocket
|
17
|
+
attr_reader :open_handler, :message_handler, :close_handler, :error_handler
|
18
|
+
|
19
|
+
# Create a new WebSocket and connect to the given endpoint.
|
20
|
+
# @param endpoint [String] Where to connect to.
|
21
|
+
# @param open_handler [#call] The handler that should be called when the websocket has opened successfully.
|
22
|
+
# @param message_handler [#call] The handler that should be called when the websocket receives a message. The
|
23
|
+
# handler can take one parameter which will have a `data` attribute for normal messages and `code` and `data` for
|
24
|
+
# close frames.
|
25
|
+
# @param close_handler [#call] The handler that should be called when the websocket is closed due to an internal
|
26
|
+
# error. The error will be passed as the first parameter to the handler.
|
27
|
+
# @param error_handler [#call] The handler that should be called when an error occurs in another handler. The error
|
28
|
+
# will be passed as the first parameter to the handler.
|
29
|
+
def initialize(endpoint, open_handler, message_handler, close_handler, error_handler)
|
30
|
+
Rubycord::LOGGER.debug "Using WSCS version: #{::WebSocket::Client::Simple::VERSION}"
|
31
|
+
|
32
|
+
@open_handler = open_handler
|
33
|
+
@message_handler = message_handler
|
34
|
+
@close_handler = close_handler
|
35
|
+
@error_handler = error_handler
|
36
|
+
|
37
|
+
instance = self # to work around WSCS's weird way of handling blocks
|
38
|
+
|
39
|
+
@client = ::WebSocket::Client::Simple.connect(endpoint) do |ws|
|
40
|
+
ws.on(:open) { instance.open_handler.call }
|
41
|
+
ws.on(:message) do |msg|
|
42
|
+
# If the message has a code attribute, it is in reality a close message
|
43
|
+
if msg.code
|
44
|
+
instance.close_handler.call(msg)
|
45
|
+
else
|
46
|
+
instance.message_handler.call(msg.data)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
ws.on(:close) { |err| instance.close_handler.call(err) }
|
50
|
+
ws.on(:error) { |err| instance.error_handler.call(err) }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Send data over this WebSocket
|
55
|
+
# @param data [String] What to send
|
56
|
+
def send(data)
|
57
|
+
@client.send(data)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Close the WebSocket connection
|
61
|
+
def close
|
62
|
+
@client.close
|
63
|
+
end
|
64
|
+
|
65
|
+
# @return [Thread] the internal WSCS thread
|
66
|
+
def thread
|
67
|
+
@client.thread
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|