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,91 @@
|
|
1
|
+
require "rubycord/events/generic"
|
2
|
+
require "rubycord/data"
|
3
|
+
|
4
|
+
module Rubycord::Events
|
5
|
+
# Generic subclass for server member events (add/update/delete)
|
6
|
+
class ServerMemberEvent < Event
|
7
|
+
# @return [Member] the member in question.
|
8
|
+
attr_reader :user
|
9
|
+
alias_method :member, :user
|
10
|
+
|
11
|
+
# @return [Array<Role>] the member's roles.
|
12
|
+
attr_reader :roles
|
13
|
+
|
14
|
+
# @return [Server] the server on which the event happened.
|
15
|
+
attr_reader :server
|
16
|
+
|
17
|
+
def initialize(data, bot)
|
18
|
+
@bot = bot
|
19
|
+
|
20
|
+
@server = bot.server(data["guild_id"].to_i)
|
21
|
+
return unless @server
|
22
|
+
|
23
|
+
init_user(data, bot)
|
24
|
+
init_roles(data, bot)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def init_user(data, _)
|
30
|
+
user_id = data["user"]["id"].to_i
|
31
|
+
@user = @server.member(user_id)
|
32
|
+
end
|
33
|
+
|
34
|
+
def init_roles(data, _)
|
35
|
+
@roles = [@server.role(@server.id)]
|
36
|
+
return unless data["roles"]
|
37
|
+
|
38
|
+
data["roles"].each do |element|
|
39
|
+
role_id = element.to_i
|
40
|
+
@roles << @server.roles.find { |r| r.id == role_id }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Generic event handler for member events
|
46
|
+
class ServerMemberEventHandler < EventHandler
|
47
|
+
def matches?(event)
|
48
|
+
# Check for the proper event type
|
49
|
+
return false unless event.is_a? ServerMemberEvent
|
50
|
+
|
51
|
+
[
|
52
|
+
matches_all(@attributes[:username], event.user.name) do |a, e|
|
53
|
+
a == if a.is_a? String
|
54
|
+
e.to_s
|
55
|
+
else
|
56
|
+
e
|
57
|
+
end
|
58
|
+
end
|
59
|
+
].reduce(true, &:&)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Member joins
|
64
|
+
# @see Rubycord::EventContainer#member_join
|
65
|
+
class ServerMemberAddEvent < ServerMemberEvent; end
|
66
|
+
|
67
|
+
# Event handler for {ServerMemberAddEvent}
|
68
|
+
class ServerMemberAddEventHandler < ServerMemberEventHandler; end
|
69
|
+
|
70
|
+
# Member is updated (roles added or deleted)
|
71
|
+
# @see Rubycord::EventContainer#member_update
|
72
|
+
class ServerMemberUpdateEvent < ServerMemberEvent; end
|
73
|
+
|
74
|
+
# Event handler for {ServerMemberUpdateEvent}
|
75
|
+
class ServerMemberUpdateEventHandler < ServerMemberEventHandler; end
|
76
|
+
|
77
|
+
# Member leaves
|
78
|
+
# @see Rubycord::EventContainer#member_leave
|
79
|
+
class ServerMemberDeleteEvent < ServerMemberEvent
|
80
|
+
# Override init_user to account for the deleted user on the server
|
81
|
+
def init_user(data, bot)
|
82
|
+
@user = Rubycord::User.new(data["user"], bot)
|
83
|
+
end
|
84
|
+
|
85
|
+
# @return [User] the user in question.
|
86
|
+
attr_reader :user
|
87
|
+
end
|
88
|
+
|
89
|
+
# Event handler for {ServerMemberDeleteEvent}
|
90
|
+
class ServerMemberDeleteEventHandler < ServerMemberEventHandler; end
|
91
|
+
end
|
@@ -0,0 +1,337 @@
|
|
1
|
+
require "rubycord/events/generic"
|
2
|
+
require "rubycord/data"
|
3
|
+
|
4
|
+
module Rubycord::Events
|
5
|
+
# Module to make sending messages easier with the presence of a text channel in an event
|
6
|
+
module Respondable
|
7
|
+
# @return [Channel] the channel in which this event occurred
|
8
|
+
attr_reader :channel
|
9
|
+
|
10
|
+
# Sends a message to the channel this message was sent in, right now. It is usually preferable to use {#<<} instead
|
11
|
+
# because it avoids rate limiting problems
|
12
|
+
# @param content [String] The message to send to the channel
|
13
|
+
# @param tts [true, false] Whether or not this message should be sent using Discord text-to-speech.
|
14
|
+
# @param embed [Hash, Rubycord::Webhooks::Embed, nil] The rich embed to append to this message.
|
15
|
+
# @param attachments [Array<File>] Files that can be referenced in embeds via `attachment://file.png`
|
16
|
+
# @param allowed_mentions [Hash, Rubycord::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
|
17
|
+
# @param message_reference [Message, String, Integer, nil] The message, or message ID, to reply to if any.
|
18
|
+
# @param components [View, Array<Hash>, nil] A collection of components to attach to the message.
|
19
|
+
# @return [Rubycord::Message] the message that was sent
|
20
|
+
def send_message(content, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil)
|
21
|
+
channel.send_message(content, tts, embed, attachments, allowed_mentions, message_reference, components)
|
22
|
+
end
|
23
|
+
|
24
|
+
# The same as {#send_message}, but yields a {Webhooks::Embed} for easy building of embedded content inside a block.
|
25
|
+
# @see Channel#send_embed
|
26
|
+
# @param message [String] The message that should be sent along with the embed. If this is the empty string, only the embed will be shown.
|
27
|
+
# @param embed [Rubycord::Webhooks::Embed, nil] The embed to start the building process with, or nil if one should be created anew.
|
28
|
+
# @param attachments [Array<File>] Files that can be referenced in embeds via `attachment://file.png`
|
29
|
+
# @param tts [true, false] Whether or not this message should be sent using Discord text-to-speech.
|
30
|
+
# @param allowed_mentions [Hash, Rubycord::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
|
31
|
+
# @param message_reference [Message, String, Integer, nil] The message, or message ID, to reply to if any.
|
32
|
+
# @param components [View, Array<Hash>, nil] A collection of components to attach to the message.
|
33
|
+
# @yield [embed] Yields the embed to allow for easy building inside a block.
|
34
|
+
# @yieldparam embed [Rubycord::Webhooks::Embed] The embed from the parameters, or a new one.
|
35
|
+
# @return [Message] The resulting message.
|
36
|
+
def send_embed(message = "", embed = nil, attachments = nil, tts = false, allowed_mentions = nil, message_reference = nil, components = nil, &)
|
37
|
+
channel.send_embed(message, embed, attachments, tts, allowed_mentions, message_reference, components, &)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Sends a temporary message to the channel this message was sent in, right now.
|
41
|
+
# @param content [String] The content to send. Should not be longer than 2000 characters or it will result in an error.
|
42
|
+
# @param timeout [Float] The amount of time in seconds after which the message sent will be deleted.
|
43
|
+
# @param tts [true, false] Whether or not this message should be sent using Discord text-to-speech.
|
44
|
+
# @param embed [Hash, Rubycord::Webhooks::Embed, nil] The rich embed to append to this message.
|
45
|
+
# @param attachments [Array<File>] Files that can be referenced in embeds via `attachment://file.png`
|
46
|
+
# @param allowed_mentions [Hash, Rubycord::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
|
47
|
+
# @param components [View, Array<Hash>, nil] A collection of components to attach to the message.
|
48
|
+
def send_temporary_message(content, timeout, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, components = nil)
|
49
|
+
channel.send_temporary_message(content, timeout, tts, embed, attachments, allowed_mentions, components)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Adds a string to be sent after the event has finished execution. Avoids problems with rate limiting because only
|
53
|
+
# one message is ever sent. If it is used multiple times, the strings will bunch up into one message (separated by
|
54
|
+
# newlines)
|
55
|
+
# @param message [String] The message to send to the channel
|
56
|
+
def <<(message)
|
57
|
+
addition = "#{message}\n"
|
58
|
+
@saved_message = @saved_message ? @saved_message + addition : addition
|
59
|
+
nil
|
60
|
+
end
|
61
|
+
|
62
|
+
# Drains the currently saved message, which clears it out, resulting in everything being saved before being
|
63
|
+
# thrown away and nothing being sent to the channel (unless there is something saved after this).
|
64
|
+
# @see #<<
|
65
|
+
def drain
|
66
|
+
@saved_message = ""
|
67
|
+
nil
|
68
|
+
end
|
69
|
+
|
70
|
+
# Drains the currently saved message into a result string. This prepends it before that string, clears the saved
|
71
|
+
# message and returns the concatenation.
|
72
|
+
# @param result [String] The result string to drain into.
|
73
|
+
# @return [String] a string formed by concatenating the saved message and the argument.
|
74
|
+
def drain_into(result)
|
75
|
+
return if result.is_a?(Rubycord::Message)
|
76
|
+
|
77
|
+
result = (@saved_message.nil? ? "" : @saved_message.to_s) + (result.nil? ? "" : result.to_s)
|
78
|
+
drain
|
79
|
+
result
|
80
|
+
end
|
81
|
+
|
82
|
+
alias_method :send, :send_message
|
83
|
+
alias_method :respond, :send_message
|
84
|
+
alias_method :send_temp, :send_temporary_message
|
85
|
+
end
|
86
|
+
|
87
|
+
# Event raised when a text message is sent to a channel
|
88
|
+
class MessageEvent < Event
|
89
|
+
include Respondable
|
90
|
+
|
91
|
+
# @return [Message] the message which triggered this event.
|
92
|
+
attr_reader :message
|
93
|
+
|
94
|
+
# @return [String] the message that has been saved by calls to {#<<} and will be sent to Discord upon completion.
|
95
|
+
attr_reader :saved_message
|
96
|
+
|
97
|
+
# @return [File] the file that has been saved by a call to {#attach_file} and will be sent to Discord upon completion.
|
98
|
+
attr_reader :file
|
99
|
+
|
100
|
+
# @return [String] the filename set in {#attach_file} that will override the original filename when sent.
|
101
|
+
attr_reader :filename
|
102
|
+
|
103
|
+
# @return [true, false] Whether or not this file should appear as a spoiler. Set by {#attach_file}
|
104
|
+
attr_reader :file_spoiler
|
105
|
+
|
106
|
+
# @!attribute [r] author
|
107
|
+
# @return [Member, User] who sent this message.
|
108
|
+
# @see Message#author
|
109
|
+
# @!attribute [r] channel
|
110
|
+
# @return [Channel] the channel in which this message was sent.
|
111
|
+
# @see Message#channel
|
112
|
+
# @!attribute [r] content
|
113
|
+
# @return [String] the message's content.
|
114
|
+
# @see Message#content
|
115
|
+
# @!attribute [r] timestamp
|
116
|
+
# @return [Time] the time at which the message was sent.
|
117
|
+
# @see Message#timestamp
|
118
|
+
delegate :author, :channel, :content, :timestamp, to: :message
|
119
|
+
|
120
|
+
# @!attribute [r] server
|
121
|
+
# @return [Server, nil] the server where this message was sent, or nil if it was sent in PM.
|
122
|
+
# @see Channel#server
|
123
|
+
delegate :server, to: :channel
|
124
|
+
|
125
|
+
def initialize(message, bot)
|
126
|
+
@bot = bot
|
127
|
+
@message = message
|
128
|
+
@channel = message.channel
|
129
|
+
@saved_message = ""
|
130
|
+
@file = nil
|
131
|
+
@filename = nil
|
132
|
+
@file_spoiler = nil
|
133
|
+
end
|
134
|
+
|
135
|
+
# Sends file with a caption to the channel this message was sent in, right now.
|
136
|
+
# It is usually preferable to use {#<<} and {#attach_file} instead
|
137
|
+
# because it avoids rate limiting problems
|
138
|
+
# @param file [File] The file to send to the channel
|
139
|
+
# @param caption [String] The caption attached to the file
|
140
|
+
# @param filename [String] Overrides the filename of the uploaded file
|
141
|
+
# @param spoiler [true, false] Whether or not this file should appear as a spoiler.
|
142
|
+
# @return [Rubycord::Message] the message that was sent
|
143
|
+
# @example Send a file from disk
|
144
|
+
# event.send_file(File.open('rubytaco.png', 'r'))
|
145
|
+
def send_file(file, caption: nil, filename: nil, spoiler: nil)
|
146
|
+
@message.channel.send_file(file, caption: caption, filename: filename, spoiler: spoiler)
|
147
|
+
end
|
148
|
+
|
149
|
+
# Attaches a file to the message event and converts the message into
|
150
|
+
# a caption.
|
151
|
+
# @param file [File] The file to be attached
|
152
|
+
# @param filename [String] Overrides the filename of the uploaded file
|
153
|
+
# @param spoiler [true, false] Whether or not this file should appear as a spoiler.
|
154
|
+
def attach_file(file, filename: nil, spoiler: nil)
|
155
|
+
raise ArgumentError, "Argument is not a file!" unless file.is_a?(File)
|
156
|
+
|
157
|
+
@file = file
|
158
|
+
@filename = filename
|
159
|
+
@file_spoiler = spoiler
|
160
|
+
nil
|
161
|
+
end
|
162
|
+
|
163
|
+
# Detaches a file from the message event.
|
164
|
+
def detach_file
|
165
|
+
@file = nil
|
166
|
+
@filename = nil
|
167
|
+
@file_spoiler = nil
|
168
|
+
end
|
169
|
+
|
170
|
+
# @return [true, false] whether or not this message was sent by the bot itself
|
171
|
+
def from_bot?
|
172
|
+
@message.user.id == @bot.profile.id
|
173
|
+
end
|
174
|
+
|
175
|
+
# Utility method to get the voice bot for the current server
|
176
|
+
# @return [VoiceBot, nil] the voice bot connected to this message's server, or nil if there is none connected
|
177
|
+
def voice
|
178
|
+
@bot.voice(@message.channel.server.id)
|
179
|
+
end
|
180
|
+
|
181
|
+
alias_method :user, :author
|
182
|
+
alias_method :text, :content
|
183
|
+
end
|
184
|
+
|
185
|
+
# Event handler for MessageEvent
|
186
|
+
class MessageEventHandler < EventHandler
|
187
|
+
def matches?(event)
|
188
|
+
# Check for the proper event type
|
189
|
+
return false unless event.is_a? MessageEvent
|
190
|
+
|
191
|
+
[
|
192
|
+
matches_all(@attributes[:starting_with] || @attributes[:start_with], event.content) do |a, e|
|
193
|
+
case a
|
194
|
+
when String
|
195
|
+
e.start_with? a
|
196
|
+
when Regexp
|
197
|
+
(e =~ a)&.zero?
|
198
|
+
end
|
199
|
+
end,
|
200
|
+
matches_all(@attributes[:ending_with] || @attributes[:end_with], event.content) do |a, e|
|
201
|
+
case a
|
202
|
+
when String
|
203
|
+
e.end_with? a
|
204
|
+
when Regexp
|
205
|
+
!(e =~ Regexp.new("#{a}$")).nil?
|
206
|
+
end
|
207
|
+
end,
|
208
|
+
matches_all(@attributes[:containing] || @attributes[:contains], event.content) do |a, e|
|
209
|
+
case a
|
210
|
+
when String
|
211
|
+
e.include? a
|
212
|
+
when Regexp
|
213
|
+
(e =~ a)
|
214
|
+
end
|
215
|
+
end,
|
216
|
+
matches_all(@attributes[:in], event.channel) do |a, e|
|
217
|
+
case a
|
218
|
+
when String
|
219
|
+
# Make sure to remove the "#" from channel names in case it was specified
|
220
|
+
a.delete("#") == e.name
|
221
|
+
when Integer
|
222
|
+
a == e.id
|
223
|
+
else
|
224
|
+
a == e
|
225
|
+
end
|
226
|
+
end,
|
227
|
+
matches_all(@attributes[:from], event.author) do |a, e|
|
228
|
+
case a
|
229
|
+
when String
|
230
|
+
a == e.name
|
231
|
+
when Integer
|
232
|
+
a == e.id
|
233
|
+
when :bot
|
234
|
+
e.current_bot?
|
235
|
+
else
|
236
|
+
a == e
|
237
|
+
end
|
238
|
+
end,
|
239
|
+
matches_all(@attributes[:with_text] || @attributes[:content] || @attributes[:exact_text], event.content) do |a, e|
|
240
|
+
case a
|
241
|
+
when String
|
242
|
+
e == a
|
243
|
+
when Regexp
|
244
|
+
match = a.match(e)
|
245
|
+
match ? (e == match[0]) : false
|
246
|
+
end
|
247
|
+
end,
|
248
|
+
matches_all(@attributes[:after], event.timestamp) { |a, e| a > e },
|
249
|
+
matches_all(@attributes[:before], event.timestamp) { |a, e| a < e },
|
250
|
+
matches_all(@attributes[:private], event.channel.private?) { |a, e| !e == !a }
|
251
|
+
].reduce(true, &:&)
|
252
|
+
end
|
253
|
+
|
254
|
+
# @see EventHandler#after_call
|
255
|
+
def after_call(event)
|
256
|
+
if event.file.nil?
|
257
|
+
event.send_message(event.saved_message) unless event.saved_message.empty?
|
258
|
+
else
|
259
|
+
event.send_file(event.file, caption: event.saved_message, filename: event.filename, spoiler: event.file_spoiler)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
# @see Rubycord::EventContainer#mention
|
265
|
+
class MentionEvent < MessageEvent; end
|
266
|
+
|
267
|
+
# Event handler for {MentionEvent}
|
268
|
+
class MentionEventHandler < MessageEventHandler; end
|
269
|
+
|
270
|
+
# @see Rubycord::EventContainer#pm
|
271
|
+
class PrivateMessageEvent < MessageEvent; end
|
272
|
+
|
273
|
+
# Event handler for {PrivateMessageEvent}
|
274
|
+
class PrivateMessageEventHandler < MessageEventHandler; end
|
275
|
+
|
276
|
+
# A subset of MessageEvent that only contains a message ID and a channel
|
277
|
+
class MessageIDEvent < Event
|
278
|
+
include Respondable
|
279
|
+
|
280
|
+
# @return [Integer] the ID associated with this event
|
281
|
+
attr_reader :id
|
282
|
+
|
283
|
+
# @!visibility private
|
284
|
+
def initialize(data, bot)
|
285
|
+
@id = data["id"].to_i
|
286
|
+
@channel = bot.channel(data["channel_id"].to_i)
|
287
|
+
@saved_message = ""
|
288
|
+
@bot = bot
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
# Event handler for {MessageIDEvent}
|
293
|
+
class MessageIDEventHandler < EventHandler
|
294
|
+
def matches?(event)
|
295
|
+
# Check for the proper event type
|
296
|
+
return false unless event.is_a? MessageIDEvent
|
297
|
+
|
298
|
+
[
|
299
|
+
matches_all(@attributes[:id], event.id) do |a, e|
|
300
|
+
a.resolve_id == e.resolve_id
|
301
|
+
end,
|
302
|
+
matches_all(@attributes[:in], event.channel) do |a, e|
|
303
|
+
case a
|
304
|
+
when String
|
305
|
+
# Make sure to remove the "#" from channel names in case it was specified
|
306
|
+
a.delete("#") == e.name
|
307
|
+
when Integer
|
308
|
+
a == e.id
|
309
|
+
else
|
310
|
+
a == e
|
311
|
+
end
|
312
|
+
end
|
313
|
+
].reduce(true, &:&)
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
# Raised when a message is edited
|
318
|
+
# @see Rubycord::EventContainer#message_edit
|
319
|
+
class MessageEditEvent < MessageEvent; end
|
320
|
+
|
321
|
+
# Event handler for {MessageEditEvent}
|
322
|
+
class MessageEditEventHandler < MessageEventHandler; end
|
323
|
+
|
324
|
+
# Raised when a message is deleted
|
325
|
+
# @see Rubycord::EventContainer#message_delete
|
326
|
+
class MessageDeleteEvent < MessageIDEvent; end
|
327
|
+
|
328
|
+
# Event handler for {MessageDeleteEvent}
|
329
|
+
class MessageDeleteEventHandler < MessageIDEventHandler; end
|
330
|
+
|
331
|
+
# Raised whenever a MESSAGE_UPDATE is received
|
332
|
+
# @see Rubycord::EventContainer#message_update
|
333
|
+
class MessageUpdateEvent < MessageEvent; end
|
334
|
+
|
335
|
+
# Event handler for {MessageUpdateEvent}
|
336
|
+
class MessageUpdateEventHandler < MessageEventHandler; end
|
337
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require "rubycord/events/generic"
|
2
|
+
require "rubycord/data"
|
3
|
+
|
4
|
+
module Rubycord::Events
|
5
|
+
# Event raised when a user's presence state updates (idle or online)
|
6
|
+
class PresenceEvent < Event
|
7
|
+
# @return [Server] the server on which the presence update happened.
|
8
|
+
attr_reader :server
|
9
|
+
|
10
|
+
# @return [User] the user whose status got updated.
|
11
|
+
attr_reader :user
|
12
|
+
|
13
|
+
# @return [Symbol] the new status.
|
14
|
+
attr_reader :status
|
15
|
+
|
16
|
+
# @return [Hash<Symbol, Symbol>] the current online status (`:online`, `:idle` or `:dnd`) of the user
|
17
|
+
# on various device types (`:desktop`, `:mobile`, or `:web`). The value will be `nil` if the user is offline or invisible.
|
18
|
+
attr_reader :client_status
|
19
|
+
|
20
|
+
def initialize(data, bot)
|
21
|
+
@bot = bot
|
22
|
+
|
23
|
+
@user = bot.user(data["user"]["id"].to_i)
|
24
|
+
@status = data["status"].to_sym
|
25
|
+
@client_status = user.client_status
|
26
|
+
@server = bot.server(data["guild_id"].to_i)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Event handler for PresenceEvent
|
31
|
+
class PresenceEventHandler < EventHandler
|
32
|
+
def matches?(event)
|
33
|
+
# Check for the proper event type
|
34
|
+
return false unless event.is_a? PresenceEvent
|
35
|
+
|
36
|
+
[
|
37
|
+
matches_all(@attributes[:from], event.user) do |a, e|
|
38
|
+
a == case a
|
39
|
+
when String
|
40
|
+
e.name
|
41
|
+
when Integer
|
42
|
+
e.id
|
43
|
+
else
|
44
|
+
e
|
45
|
+
end
|
46
|
+
end,
|
47
|
+
matches_all(@attributes[:status], event.status) do |a, e|
|
48
|
+
a == if a.is_a? String
|
49
|
+
e.to_s
|
50
|
+
else
|
51
|
+
e
|
52
|
+
end
|
53
|
+
end
|
54
|
+
].reduce(true, &:&)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Event raised when a user starts or stops playing a game
|
59
|
+
class PlayingEvent < Event
|
60
|
+
# @return [Server] the server on which the presence update happened.
|
61
|
+
attr_reader :server
|
62
|
+
|
63
|
+
# @return [User] the user whose status got updated.
|
64
|
+
attr_reader :user
|
65
|
+
|
66
|
+
# @return [Rubycord::Activity] The new activity
|
67
|
+
attr_reader :activity
|
68
|
+
|
69
|
+
# @!attribute [r] url
|
70
|
+
# @return [String] the URL to the stream
|
71
|
+
|
72
|
+
# @!attribute [r] details
|
73
|
+
# @return [String] what the player is currently doing (ex. game being streamed)
|
74
|
+
|
75
|
+
# @!attribute [r] type
|
76
|
+
# @return [Integer] the type of play. See {Rubycord::Activity}
|
77
|
+
delegate :url, :details, :type, to: :activity
|
78
|
+
|
79
|
+
# @return [Hash<Symbol, Symbol>] the current online status (`:online`, `:idle` or `:dnd`) of the user
|
80
|
+
# on various device types (`:desktop`, `:mobile`, or `:web`). The value will be `nil` if the user is offline or invisible.
|
81
|
+
attr_reader :client_status
|
82
|
+
|
83
|
+
def initialize(data, activity, bot)
|
84
|
+
@bot = bot
|
85
|
+
@activity = activity
|
86
|
+
|
87
|
+
@server = bot.server(data["guild_id"].to_i)
|
88
|
+
@user = bot.user(data["user"]["id"].to_i)
|
89
|
+
@client_status = @user.client_status
|
90
|
+
end
|
91
|
+
|
92
|
+
# @return [String] the name of the new game the user is playing.
|
93
|
+
def game
|
94
|
+
@activity.name
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Event handler for PlayingEvent
|
99
|
+
class PlayingEventHandler < EventHandler
|
100
|
+
def matches?(event)
|
101
|
+
# Check for the proper event type
|
102
|
+
return false unless event.is_a? PlayingEvent
|
103
|
+
|
104
|
+
[
|
105
|
+
matches_all(@attributes[:from], event.user) do |a, e|
|
106
|
+
a == case a
|
107
|
+
when String
|
108
|
+
e.name
|
109
|
+
when Integer
|
110
|
+
e.id
|
111
|
+
else
|
112
|
+
e
|
113
|
+
end
|
114
|
+
end,
|
115
|
+
matches_all(@attributes[:game], event.game) do |a, e|
|
116
|
+
a == e
|
117
|
+
end,
|
118
|
+
matches_all(@attributes[:type], event.type) do |a, e|
|
119
|
+
a == e
|
120
|
+
end,
|
121
|
+
matches_all(@attributes[:client_status], event.client_status) do |a, e|
|
122
|
+
e.slice(a.keys) == a
|
123
|
+
end
|
124
|
+
].reduce(true, &:&)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "rubycord/events/generic"
|
2
|
+
|
3
|
+
# Event classes and handlers
|
4
|
+
module Rubycord::Events
|
5
|
+
# Event raised when any dispatch is received
|
6
|
+
class RawEvent < Event
|
7
|
+
# @return [Symbol] the type of this dispatch.
|
8
|
+
attr_reader :type
|
9
|
+
alias_method :t, :type
|
10
|
+
|
11
|
+
# @return [Hash] the data of this dispatch.
|
12
|
+
attr_reader :data
|
13
|
+
alias_method :d, :data
|
14
|
+
|
15
|
+
def initialize(type, data, bot)
|
16
|
+
@type = type
|
17
|
+
@data = data
|
18
|
+
@bot = bot
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Event handler for {RawEvent}
|
23
|
+
class RawEventHandler < EventHandler
|
24
|
+
def matches?(event)
|
25
|
+
# Check for the proper event type
|
26
|
+
return false unless event.is_a? RawEvent
|
27
|
+
|
28
|
+
[
|
29
|
+
matches_all(@attributes[:type] || @attributes[:t], event.type) do |a, e|
|
30
|
+
if a.is_a? Regexp
|
31
|
+
a.match?(e)
|
32
|
+
else
|
33
|
+
e.to_s.casecmp(a.to_s).zero?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
].reduce(true, &:&)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Event raised when an unknown dispatch is received
|
41
|
+
class UnknownEvent < RawEvent; end
|
42
|
+
|
43
|
+
# Event handler for {UnknownEvent}
|
44
|
+
class UnknownEventHandler < RawEventHandler; end
|
45
|
+
end
|