onyxcord 1.1.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/.devcontainer/Dockerfile +13 -0
- data/.devcontainer/devcontainer.json +29 -0
- data/.devcontainer/postcreate.sh +4 -0
- data/.github/CONTRIBUTING.md +13 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +24 -0
- data/.github/pull_request_template.md +37 -0
- data/.github/workflows/ci.yml +78 -0
- data/.github/workflows/codeql.yml +65 -0
- data/.github/workflows/deploy.yml +54 -0
- data/.github/workflows/release.yml +51 -0
- data/.gitignore +16 -0
- data/.markdownlint.json +4 -0
- data/.overcommit.yml +7 -0
- data/.rspec +2 -0
- data/.rubocop.yml +129 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +0 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +305 -0
- data/Rakefile +17 -0
- data/bin/console +15 -0
- data/bin/setup +7 -0
- data/lib/onyxcord/allowed_mentions.rb +43 -0
- data/lib/onyxcord/api/application.rb +316 -0
- data/lib/onyxcord/api/channel.rb +700 -0
- data/lib/onyxcord/api/interaction.rb +67 -0
- data/lib/onyxcord/api/invite.rb +44 -0
- data/lib/onyxcord/api/server.rb +775 -0
- data/lib/onyxcord/api/user.rb +158 -0
- data/lib/onyxcord/api/webhook.rb +163 -0
- data/lib/onyxcord/api.rb +335 -0
- data/lib/onyxcord/await.rb +51 -0
- data/lib/onyxcord/bot.rb +1971 -0
- data/lib/onyxcord/cache.rb +326 -0
- data/lib/onyxcord/colour_rgb.rb +43 -0
- data/lib/onyxcord/commands/command_bot.rb +511 -0
- data/lib/onyxcord/commands/container.rb +112 -0
- data/lib/onyxcord/commands/events.rb +11 -0
- data/lib/onyxcord/commands/parser.rb +327 -0
- data/lib/onyxcord/commands/rate_limiter.rb +144 -0
- data/lib/onyxcord/configuration.rb +125 -0
- data/lib/onyxcord/container.rb +988 -0
- data/lib/onyxcord/data/activity.rb +271 -0
- data/lib/onyxcord/data/application.rb +341 -0
- data/lib/onyxcord/data/attachment.rb +91 -0
- data/lib/onyxcord/data/audit_logs.rb +438 -0
- data/lib/onyxcord/data/avatar_decoration.rb +26 -0
- data/lib/onyxcord/data/call.rb +22 -0
- data/lib/onyxcord/data/channel.rb +1355 -0
- data/lib/onyxcord/data/channel_tag.rb +69 -0
- data/lib/onyxcord/data/collectibles.rb +47 -0
- data/lib/onyxcord/data/component.rb +583 -0
- data/lib/onyxcord/data/embed.rb +258 -0
- data/lib/onyxcord/data/emoji.rb +123 -0
- data/lib/onyxcord/data/install_params.rb +24 -0
- data/lib/onyxcord/data/integration.rb +144 -0
- data/lib/onyxcord/data/interaction.rb +1141 -0
- data/lib/onyxcord/data/invite.rb +137 -0
- data/lib/onyxcord/data/member.rb +528 -0
- data/lib/onyxcord/data/message.rb +612 -0
- data/lib/onyxcord/data/message_activity.rb +41 -0
- data/lib/onyxcord/data/overwrite.rb +109 -0
- data/lib/onyxcord/data/poll.rb +365 -0
- data/lib/onyxcord/data/primary_server.rb +60 -0
- data/lib/onyxcord/data/profile.rb +79 -0
- data/lib/onyxcord/data/reaction.rb +64 -0
- data/lib/onyxcord/data/recipient.rb +34 -0
- data/lib/onyxcord/data/role.rb +449 -0
- data/lib/onyxcord/data/role_connection_data.rb +69 -0
- data/lib/onyxcord/data/role_subscription.rb +41 -0
- data/lib/onyxcord/data/scheduled_event.rb +513 -0
- data/lib/onyxcord/data/server.rb +1614 -0
- data/lib/onyxcord/data/server_preview.rb +68 -0
- data/lib/onyxcord/data/snapshot.rb +112 -0
- data/lib/onyxcord/data/team.rb +98 -0
- data/lib/onyxcord/data/timestamp.rb +69 -0
- data/lib/onyxcord/data/user.rb +324 -0
- data/lib/onyxcord/data/voice_region.rb +46 -0
- data/lib/onyxcord/data/voice_state.rb +41 -0
- data/lib/onyxcord/data/webhook.rb +238 -0
- data/lib/onyxcord/data.rb +57 -0
- data/lib/onyxcord/errors.rb +246 -0
- data/lib/onyxcord/event_executor.rb +80 -0
- data/lib/onyxcord/events/await.rb +48 -0
- data/lib/onyxcord/events/bans.rb +60 -0
- data/lib/onyxcord/events/channels.rb +225 -0
- data/lib/onyxcord/events/generic.rb +129 -0
- data/lib/onyxcord/events/guilds.rb +269 -0
- data/lib/onyxcord/events/integrations.rb +100 -0
- data/lib/onyxcord/events/interactions.rb +624 -0
- data/lib/onyxcord/events/invites.rb +127 -0
- data/lib/onyxcord/events/lifetime.rb +31 -0
- data/lib/onyxcord/events/members.rb +110 -0
- data/lib/onyxcord/events/message.rb +399 -0
- data/lib/onyxcord/events/polls.rb +118 -0
- data/lib/onyxcord/events/presence.rb +131 -0
- data/lib/onyxcord/events/raw.rb +74 -0
- data/lib/onyxcord/events/reactions.rb +218 -0
- data/lib/onyxcord/events/roles.rb +87 -0
- data/lib/onyxcord/events/scheduled_events.rb +171 -0
- data/lib/onyxcord/events/threads.rb +100 -0
- data/lib/onyxcord/events/typing.rb +73 -0
- data/lib/onyxcord/events/voice_server_update.rb +48 -0
- data/lib/onyxcord/events/voice_state_update.rb +106 -0
- data/lib/onyxcord/events/webhooks.rb +65 -0
- data/lib/onyxcord/gateway.rb +890 -0
- data/lib/onyxcord/id_object.rb +39 -0
- data/lib/onyxcord/light/data.rb +62 -0
- data/lib/onyxcord/light/integrations.rb +73 -0
- data/lib/onyxcord/light/light_bot.rb +58 -0
- data/lib/onyxcord/light.rb +8 -0
- data/lib/onyxcord/logger.rb +120 -0
- data/lib/onyxcord/message_components.rb +70 -0
- data/lib/onyxcord/paginator.rb +60 -0
- data/lib/onyxcord/permissions.rb +255 -0
- data/lib/onyxcord/rate_limiter/gateway.rb +42 -0
- data/lib/onyxcord/rate_limiter/rest.rb +89 -0
- data/lib/onyxcord/version.rb +7 -0
- data/lib/onyxcord/voice/encoder.rb +115 -0
- data/lib/onyxcord/voice/network.rb +380 -0
- data/lib/onyxcord/voice/opcodes.rb +29 -0
- data/lib/onyxcord/voice/sodium.rb +157 -0
- data/lib/onyxcord/voice/timer.rb +19 -0
- data/lib/onyxcord/voice/voice_bot.rb +386 -0
- data/lib/onyxcord/webhooks.rb +14 -0
- data/lib/onyxcord/websocket.rb +62 -0
- data/lib/onyxcord.rb +180 -0
- data/onyxcord-webhooks.gemspec +30 -0
- data/onyxcord.gemspec +50 -0
- metadata +421 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OnyxCord::Events
|
|
4
|
+
# Raised when an invite is created.
|
|
5
|
+
class InviteCreateEvent < Event
|
|
6
|
+
# @return [Invite] The invite that was created.
|
|
7
|
+
attr_reader :invite
|
|
8
|
+
|
|
9
|
+
# @return [Server, nil] The server the invite was created for.
|
|
10
|
+
attr_reader :server
|
|
11
|
+
|
|
12
|
+
# @return [Channel] The channel the invite was created for.
|
|
13
|
+
attr_reader :channel
|
|
14
|
+
|
|
15
|
+
# @!attribute [r] code
|
|
16
|
+
# @return [String] The code for the created invite.
|
|
17
|
+
# @see Invite#code
|
|
18
|
+
# @!attribute [r] created_at
|
|
19
|
+
# @return [Time] The time the invite was created at.
|
|
20
|
+
# @see Invite#created_at
|
|
21
|
+
# @!attribute [r] max_age
|
|
22
|
+
# @return [Integer] The maximum age of the created invite.
|
|
23
|
+
# @see Invite#max_age
|
|
24
|
+
# @!attribute [r] max_uses
|
|
25
|
+
# @return [Integer] The maximum number of uses before the invite expires.
|
|
26
|
+
# @see Invite#max_uses
|
|
27
|
+
# @!attribute [r] temporary
|
|
28
|
+
# @return [true, false] Whether or not this invite grants temporary membership.
|
|
29
|
+
# @see Invite#temporary
|
|
30
|
+
# @!attribute [r] inviter
|
|
31
|
+
# @return [User] The user that created the invite.
|
|
32
|
+
# @see Invite#inviter
|
|
33
|
+
delegate :code, :created_at, :max_age, :max_uses, :temporary, :inviter, to: :invite
|
|
34
|
+
|
|
35
|
+
alias temporary? temporary
|
|
36
|
+
|
|
37
|
+
# @!visibility private
|
|
38
|
+
def initialize(data, invite, bot)
|
|
39
|
+
@bot = bot
|
|
40
|
+
@invite = invite
|
|
41
|
+
@channel = bot.channel(data['channel_id'])
|
|
42
|
+
@server = bot.server(data['guild_id']) if data['guild_id']
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Raised when an invite is deleted.
|
|
47
|
+
class InviteDeleteEvent < Event
|
|
48
|
+
# @return [Channel] The channel the deleted invite was for.
|
|
49
|
+
attr_reader :channel
|
|
50
|
+
|
|
51
|
+
# @return [Server, nil] The server the deleted invite was for.
|
|
52
|
+
attr_reader :server
|
|
53
|
+
|
|
54
|
+
# @return [String] The code of the deleted invite.
|
|
55
|
+
attr_reader :code
|
|
56
|
+
|
|
57
|
+
# @!visibility private
|
|
58
|
+
def initialize(data, bot)
|
|
59
|
+
@bot = bot
|
|
60
|
+
@channel = bot.channel(data['channel_id'])
|
|
61
|
+
@server = bot.server(data['guild_id']) if data['guild_id']
|
|
62
|
+
@code = data['code']
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Event handler for InviteCreateEvent.
|
|
67
|
+
class InviteCreateEventHandler < EventHandler
|
|
68
|
+
def matches?(event)
|
|
69
|
+
return false unless event.is_a? InviteCreateEvent
|
|
70
|
+
|
|
71
|
+
[
|
|
72
|
+
matches_all(@attributes[:server], event.server) do |a, e|
|
|
73
|
+
a == case a
|
|
74
|
+
when String
|
|
75
|
+
e.name
|
|
76
|
+
when Integer
|
|
77
|
+
e.id
|
|
78
|
+
else
|
|
79
|
+
e
|
|
80
|
+
end
|
|
81
|
+
end,
|
|
82
|
+
matches_all(@attributes[:channel], event.channel) do |a, e|
|
|
83
|
+
a == case a
|
|
84
|
+
when String
|
|
85
|
+
e.name
|
|
86
|
+
when Integer
|
|
87
|
+
e.id
|
|
88
|
+
else
|
|
89
|
+
e
|
|
90
|
+
end
|
|
91
|
+
end,
|
|
92
|
+
matches_all(@attributes[:temporary], event.temporary?, &:==),
|
|
93
|
+
matches_all(@attributes[:inviter], event.inviter, &:==)
|
|
94
|
+
].reduce(true, &:&)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Event handler for InviteDeleteEvent
|
|
99
|
+
class InviteDeleteEventHandler < EventHandler
|
|
100
|
+
def matches?(event)
|
|
101
|
+
return false unless event.is_a? InviteDeleteEvent
|
|
102
|
+
|
|
103
|
+
[
|
|
104
|
+
matches_all(@attributes[:server], event.server) do |a, e|
|
|
105
|
+
a == case a
|
|
106
|
+
when String
|
|
107
|
+
e.name
|
|
108
|
+
when Integer
|
|
109
|
+
e.id
|
|
110
|
+
else
|
|
111
|
+
e
|
|
112
|
+
end
|
|
113
|
+
end,
|
|
114
|
+
matches_all(@attributes[:channel], event.channel) do |a, e|
|
|
115
|
+
a == case a
|
|
116
|
+
when String
|
|
117
|
+
e.name
|
|
118
|
+
when Integer
|
|
119
|
+
e.id
|
|
120
|
+
else
|
|
121
|
+
e
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
].reduce(true, &:&)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'onyxcord/events/generic'
|
|
4
|
+
|
|
5
|
+
module OnyxCord::Events
|
|
6
|
+
# Common superclass for all lifetime events
|
|
7
|
+
class LifetimeEvent < Event
|
|
8
|
+
# @!visibility private
|
|
9
|
+
def initialize(bot)
|
|
10
|
+
@bot = bot
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# @see OnyxCord::EventContainer#ready
|
|
15
|
+
class ReadyEvent < LifetimeEvent; end
|
|
16
|
+
|
|
17
|
+
# Event handler for {ReadyEvent}
|
|
18
|
+
class ReadyEventHandler < TrueEventHandler; end
|
|
19
|
+
|
|
20
|
+
# @see OnyxCord::EventContainer#disconnected
|
|
21
|
+
class DisconnectEvent < LifetimeEvent; end
|
|
22
|
+
|
|
23
|
+
# Event handler for {DisconnectEvent}
|
|
24
|
+
class DisconnectEventHandler < TrueEventHandler; end
|
|
25
|
+
|
|
26
|
+
# @see OnyxCord::EventContainer#heartbeat
|
|
27
|
+
class HeartbeatEvent < LifetimeEvent; end
|
|
28
|
+
|
|
29
|
+
# Event handler for {HeartbeatEvent}
|
|
30
|
+
class HeartbeatEventHandler < TrueEventHandler; end
|
|
31
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'onyxcord/events/generic'
|
|
4
|
+
require 'onyxcord/data'
|
|
5
|
+
|
|
6
|
+
module OnyxCord::Events
|
|
7
|
+
# Generic subclass for server member events (add/update/delete)
|
|
8
|
+
class ServerMemberEvent < Event
|
|
9
|
+
# @return [Member] the member in question.
|
|
10
|
+
attr_reader :user
|
|
11
|
+
alias_method :member, :user
|
|
12
|
+
|
|
13
|
+
# @return [Array<Role>] the member's roles.
|
|
14
|
+
attr_reader :roles
|
|
15
|
+
|
|
16
|
+
# @return [Server] the server on which the event happened.
|
|
17
|
+
attr_reader :server
|
|
18
|
+
|
|
19
|
+
# @!visibility private
|
|
20
|
+
def initialize(data, bot)
|
|
21
|
+
@bot = bot
|
|
22
|
+
|
|
23
|
+
@server = bot.server(data['guild_id'].to_i)
|
|
24
|
+
return unless @server
|
|
25
|
+
|
|
26
|
+
init_user(data, bot)
|
|
27
|
+
init_roles(data, bot)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
# @!visibility private
|
|
33
|
+
def init_user(data, _)
|
|
34
|
+
user_id = data['user']['id'].to_i
|
|
35
|
+
@user = @server.member(user_id)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @!visibility private
|
|
39
|
+
def init_roles(data, _)
|
|
40
|
+
@roles = [@server.role(@server.id)]
|
|
41
|
+
return unless data['roles']
|
|
42
|
+
|
|
43
|
+
data['roles'].each do |element|
|
|
44
|
+
role_id = element.to_i
|
|
45
|
+
@roles << @server.roles.find { |r| r.id == role_id }
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Generic event handler for member events
|
|
51
|
+
class ServerMemberEventHandler < EventHandler
|
|
52
|
+
def matches?(event)
|
|
53
|
+
# Check for the proper event type
|
|
54
|
+
return false unless event.is_a? ServerMemberEvent
|
|
55
|
+
|
|
56
|
+
[
|
|
57
|
+
matches_all(@attributes[:username], event.user.name) do |a, e|
|
|
58
|
+
a == if a.is_a? String
|
|
59
|
+
e.to_s
|
|
60
|
+
else
|
|
61
|
+
e
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
].reduce(true, &:&)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Member joins
|
|
69
|
+
# @see OnyxCord::EventContainer#member_join
|
|
70
|
+
class ServerMemberAddEvent < ServerMemberEvent; end
|
|
71
|
+
|
|
72
|
+
# Event handler for {ServerMemberAddEvent}
|
|
73
|
+
class ServerMemberAddEventHandler < ServerMemberEventHandler; end
|
|
74
|
+
|
|
75
|
+
# Member is updated (roles added or deleted)
|
|
76
|
+
# @see OnyxCord::EventContainer#member_update
|
|
77
|
+
class ServerMemberUpdateEvent < ServerMemberEvent
|
|
78
|
+
# @!visibility private
|
|
79
|
+
# @note Override init_user so we don't make requests all the time on large servers
|
|
80
|
+
def init_user(data, _)
|
|
81
|
+
@user_id = data['user']['id']
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# @return [Member] the member in question.
|
|
85
|
+
def user
|
|
86
|
+
@server&.member(@user_id)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
alias_method :member, :user
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Event handler for {ServerMemberUpdateEvent}
|
|
93
|
+
class ServerMemberUpdateEventHandler < ServerMemberEventHandler; end
|
|
94
|
+
|
|
95
|
+
# Member leaves
|
|
96
|
+
# @see OnyxCord::EventContainer#member_leave
|
|
97
|
+
class ServerMemberDeleteEvent < ServerMemberEvent
|
|
98
|
+
# @!visibility private
|
|
99
|
+
# @note Override init_user to account for the deleted user on the server
|
|
100
|
+
def init_user(data, bot)
|
|
101
|
+
@user = OnyxCord::User.new(data['user'], bot)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# @return [User] the user in question.
|
|
105
|
+
attr_reader :user
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Event handler for {ServerMemberDeleteEvent}
|
|
109
|
+
class ServerMemberDeleteEventHandler < ServerMemberEventHandler; end
|
|
110
|
+
end
|
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'onyxcord/events/generic'
|
|
4
|
+
require 'onyxcord/data'
|
|
5
|
+
|
|
6
|
+
module OnyxCord::Events
|
|
7
|
+
# Module to make sending messages easier with the presence of a text channel in an event
|
|
8
|
+
module Respondable
|
|
9
|
+
# @return [Channel] the channel in which this event occurred
|
|
10
|
+
attr_reader :channel
|
|
11
|
+
|
|
12
|
+
# Sends a message to the channel this message was sent in, right now. It is usually preferable to use {#<<} instead
|
|
13
|
+
# because it avoids rate limiting problems
|
|
14
|
+
# @param content [String] The message to send to the channel
|
|
15
|
+
# @param tts [true, false] Whether or not this message should be sent using Discord text-to-speech.
|
|
16
|
+
# @param embed [Hash, OnyxCord::Webhooks::Embed, nil] The rich embed to append to this message.
|
|
17
|
+
# @param attachments [Array<File>] Files that can be referenced in embeds via `attachment://file.png`
|
|
18
|
+
# @param allowed_mentions [Hash, OnyxCord::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
|
|
19
|
+
# @param message_reference [Message, String, Integer, nil] The message, or message ID, to reply to if any.
|
|
20
|
+
# @param components [View, Array<Hash>, nil] A collection of components to attach to the message.
|
|
21
|
+
# @param flags [Integer] Flags for this message. Currently only SUPPRESS_EMBEDS (1 << 2), SUPPRESS_NOTIFICATIONS (1 << 12), and IS_COMPONENTS_V2 (1 << 15) can be set.
|
|
22
|
+
# @return [OnyxCord::Message] the message that was sent
|
|
23
|
+
def send_message(content, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil, flags = 0)
|
|
24
|
+
channel.send_message(content, tts, embed, attachments, allowed_mentions, message_reference, components, flags)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# The same as {#send_message}, but yields a {Webhooks::Embed} for easy building of embedded content inside a block.
|
|
28
|
+
# @see Channel#send_embed
|
|
29
|
+
# @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.
|
|
30
|
+
# @param embed [OnyxCord::Webhooks::Embed, nil] The embed to start the building process with, or nil if one should be created anew.
|
|
31
|
+
# @param attachments [Array<File>] Files that can be referenced in embeds via `attachment://file.png`
|
|
32
|
+
# @param tts [true, false] Whether or not this message should be sent using Discord text-to-speech.
|
|
33
|
+
# @param allowed_mentions [Hash, OnyxCord::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
|
|
34
|
+
# @param message_reference [Message, String, Integer, nil] The message, or message ID, to reply to if any.
|
|
35
|
+
# @param components [View, Array<Hash>, nil] A collection of components to attach to the message.
|
|
36
|
+
# @param flags [Integer] Flags for this message. Currently only SUPPRESS_EMBEDS (1 << 2), SUPPRESS_NOTIFICATIONS (1 << 12), and IS_COMPONENTS_V2 (1 << 15) can be set.
|
|
37
|
+
# @yield [embed] Yields the embed to allow for easy building inside a block.
|
|
38
|
+
# @yieldparam embed [OnyxCord::Webhooks::Embed] The embed from the parameters, or a new one.
|
|
39
|
+
# @return [Message] The resulting message.
|
|
40
|
+
def send_embed(message = '', embed = nil, attachments = nil, tts = false, allowed_mentions = nil, message_reference = nil, components = nil, flags = 0, &block)
|
|
41
|
+
channel.send_embed(message, embed, attachments, tts, allowed_mentions, message_reference, components, flags, &block)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Sends a temporary message to the channel this message was sent in, right now.
|
|
45
|
+
# @param content [String] The content to send. Should not be longer than 2000 characters or it will result in an error.
|
|
46
|
+
# @param timeout [Float] The amount of time in seconds after which the message sent will be deleted.
|
|
47
|
+
# @param tts [true, false] Whether or not this message should be sent using Discord text-to-speech.
|
|
48
|
+
# @param embed [Hash, OnyxCord::Webhooks::Embed, nil] The rich embed to append to this message.
|
|
49
|
+
# @param attachments [Array<File>] Files that can be referenced in embeds via `attachment://file.png`
|
|
50
|
+
# @param allowed_mentions [Hash, OnyxCord::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
|
|
51
|
+
# @param components [View, Array<Hash>, nil] A collection of components to attach to the message.
|
|
52
|
+
# @param flags [Integer] Flags for this message. Currently only SUPPRESS_EMBEDS (1 << 2), SUPPRESS_NOTIFICATIONS (1 << 12), and IS_COMPONENTS_V2 (1 << 15) can be set.
|
|
53
|
+
def send_temporary_message(content, timeout, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, components = nil, flags = 0)
|
|
54
|
+
channel.send_temporary_message(content, timeout, tts, embed, attachments, allowed_mentions, components, flags)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Sends a message to the channel this message was sent in, right now.
|
|
58
|
+
# @see Channel#send_message!
|
|
59
|
+
def send_message!(...)
|
|
60
|
+
channel.send_message!(...)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Adds a string to be sent after the event has finished execution. Avoids problems with rate limiting because only
|
|
64
|
+
# one message is ever sent. If it is used multiple times, the strings will bunch up into one message (separated by
|
|
65
|
+
# newlines)
|
|
66
|
+
# @param message [String] The message to send to the channel
|
|
67
|
+
def <<(message)
|
|
68
|
+
addition = "#{message}\n"
|
|
69
|
+
@saved_message = @saved_message ? @saved_message + addition : addition
|
|
70
|
+
nil
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Drains the currently saved message, which clears it out, resulting in everything being saved before being
|
|
74
|
+
# thrown away and nothing being sent to the channel (unless there is something saved after this).
|
|
75
|
+
# @see #<<
|
|
76
|
+
def drain
|
|
77
|
+
@saved_message = ''
|
|
78
|
+
nil
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Drains the currently saved message into a result string. This prepends it before that string, clears the saved
|
|
82
|
+
# message and returns the concatenation.
|
|
83
|
+
# @param result [String] The result string to drain into.
|
|
84
|
+
# @return [String] a string formed by concatenating the saved message and the argument.
|
|
85
|
+
def drain_into(result)
|
|
86
|
+
return if result.is_a?(OnyxCord::Message)
|
|
87
|
+
|
|
88
|
+
result = (@saved_message.nil? ? '' : @saved_message.to_s) + (result.nil? ? '' : result.to_s)
|
|
89
|
+
drain
|
|
90
|
+
result
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
alias_method :send, :send_message
|
|
94
|
+
alias_method :respond, :send_message
|
|
95
|
+
alias_method :send_temp, :send_temporary_message
|
|
96
|
+
|
|
97
|
+
alias_method :send!, :send_message!
|
|
98
|
+
alias_method :respond!, :send_message!
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Event raised when a text message is sent to a channel
|
|
102
|
+
class MessageEvent < Event
|
|
103
|
+
include Respondable
|
|
104
|
+
|
|
105
|
+
# @return [Message] the message which triggered this event.
|
|
106
|
+
attr_reader :message
|
|
107
|
+
|
|
108
|
+
# @return [String] the message that has been saved by calls to {#<<} and will be sent to Discord upon completion.
|
|
109
|
+
attr_reader :saved_message
|
|
110
|
+
|
|
111
|
+
# @return [File] the file that has been saved by a call to {#attach_file} and will be sent to Discord upon completion.
|
|
112
|
+
attr_reader :file
|
|
113
|
+
|
|
114
|
+
# @return [String] the filename set in {#attach_file} that will override the original filename when sent.
|
|
115
|
+
attr_reader :filename
|
|
116
|
+
|
|
117
|
+
# @return [true, false] Whether or not this file should appear as a spoiler. Set by {#attach_file}
|
|
118
|
+
attr_reader :file_spoiler
|
|
119
|
+
|
|
120
|
+
# @!attribute [r] author
|
|
121
|
+
# @return [Member, User] who sent this message.
|
|
122
|
+
# @see Message#author
|
|
123
|
+
# @!attribute [r] channel
|
|
124
|
+
# @return [Channel] the channel in which this message was sent.
|
|
125
|
+
# @see Message#channel
|
|
126
|
+
# @!attribute [r] content
|
|
127
|
+
# @return [String] the message's content.
|
|
128
|
+
# @see Message#content
|
|
129
|
+
# @!attribute [r] timestamp
|
|
130
|
+
# @return [Time] the time at which the message was sent.
|
|
131
|
+
# @see Message#timestamp
|
|
132
|
+
delegate :author, :channel, :content, :timestamp, to: :message
|
|
133
|
+
|
|
134
|
+
# @!attribute [r] server
|
|
135
|
+
# @return [Server, nil] the server where this message was sent, or nil if it was sent in PM.
|
|
136
|
+
# @see Channel#server
|
|
137
|
+
delegate :server, to: :channel
|
|
138
|
+
|
|
139
|
+
# @!visibility private
|
|
140
|
+
def initialize(message, bot)
|
|
141
|
+
@bot = bot
|
|
142
|
+
@message = message
|
|
143
|
+
@channel = message.channel
|
|
144
|
+
@saved_message = ''
|
|
145
|
+
@file = nil
|
|
146
|
+
@filename = nil
|
|
147
|
+
@file_spoiler = nil
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Sends file with a caption to the channel this message was sent in, right now.
|
|
151
|
+
# It is usually preferable to use {#<<} and {#attach_file} instead
|
|
152
|
+
# because it avoids rate limiting problems
|
|
153
|
+
# @param file [File] The file to send to the channel
|
|
154
|
+
# @param caption [String] The caption attached to the file
|
|
155
|
+
# @param filename [String] Overrides the filename of the uploaded file
|
|
156
|
+
# @param spoiler [true, false] Whether or not this file should appear as a spoiler.
|
|
157
|
+
# @return [OnyxCord::Message] the message that was sent
|
|
158
|
+
# @example Send a file from disk
|
|
159
|
+
# event.send_file(File.open('rubytaco.png', 'r'))
|
|
160
|
+
def send_file(file, caption: nil, filename: nil, spoiler: nil)
|
|
161
|
+
@message.channel.send_file(file, caption: caption, filename: filename, spoiler: spoiler)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Attaches a file to the message event and converts the message into
|
|
165
|
+
# a caption.
|
|
166
|
+
# @param file [File] The file to be attached
|
|
167
|
+
# @param filename [String] Overrides the filename of the uploaded file
|
|
168
|
+
# @param spoiler [true, false] Whether or not this file should appear as a spoiler.
|
|
169
|
+
def attach_file(file, filename: nil, spoiler: nil)
|
|
170
|
+
raise ArgumentError, 'Argument is not a file!' unless file.is_a?(File)
|
|
171
|
+
|
|
172
|
+
@file = file
|
|
173
|
+
@filename = filename
|
|
174
|
+
@file_spoiler = spoiler
|
|
175
|
+
nil
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Detaches a file from the message event.
|
|
179
|
+
def detach_file
|
|
180
|
+
@file = nil
|
|
181
|
+
@filename = nil
|
|
182
|
+
@file_spoiler = nil
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# @return [true, false] whether or not this message was sent by the bot itself
|
|
186
|
+
def from_bot?
|
|
187
|
+
@message.user.id == @bot.profile.id
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# Utility method to get the voice bot for the current server
|
|
191
|
+
# @return [VoiceBot, nil] the voice bot connected to this message's server, or nil if there is none connected
|
|
192
|
+
def voice
|
|
193
|
+
@bot.voice(@message.channel.server.id)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
alias_method :user, :author
|
|
197
|
+
alias_method :text, :content
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# Event handler for MessageEvent
|
|
201
|
+
class MessageEventHandler < EventHandler
|
|
202
|
+
def matches?(event)
|
|
203
|
+
# Check for the proper event type
|
|
204
|
+
return false unless event.is_a? MessageEvent
|
|
205
|
+
|
|
206
|
+
[
|
|
207
|
+
matches_all(@attributes[:starting_with] || @attributes[:start_with], event.content) do |a, e|
|
|
208
|
+
case a
|
|
209
|
+
when String
|
|
210
|
+
e.start_with? a
|
|
211
|
+
when Regexp
|
|
212
|
+
(e =~ a)&.zero?
|
|
213
|
+
end
|
|
214
|
+
end,
|
|
215
|
+
matches_all(@attributes[:ending_with] || @attributes[:end_with], event.content) do |a, e|
|
|
216
|
+
case a
|
|
217
|
+
when String
|
|
218
|
+
e.end_with? a
|
|
219
|
+
when Regexp
|
|
220
|
+
!(e =~ Regexp.new("#{a}$")).nil?
|
|
221
|
+
end
|
|
222
|
+
end,
|
|
223
|
+
matches_all(@attributes[:containing] || @attributes[:contains], event.content) do |a, e|
|
|
224
|
+
case a
|
|
225
|
+
when String
|
|
226
|
+
e.include? a
|
|
227
|
+
when Regexp
|
|
228
|
+
(e =~ a)
|
|
229
|
+
end
|
|
230
|
+
end,
|
|
231
|
+
matches_all(@attributes[:in], event.channel) do |a, e|
|
|
232
|
+
case a
|
|
233
|
+
when String
|
|
234
|
+
# Make sure to remove the "#" from channel names in case it was specified
|
|
235
|
+
a.delete('#') == e.name
|
|
236
|
+
when Integer
|
|
237
|
+
a == e.id
|
|
238
|
+
else
|
|
239
|
+
a == e
|
|
240
|
+
end
|
|
241
|
+
end,
|
|
242
|
+
matches_all(@attributes[:from], event.message) do |a, e|
|
|
243
|
+
# Resolve the author in the block in order to prevent resolving the author even when the attribute is `nil`
|
|
244
|
+
e = e.author
|
|
245
|
+
case a
|
|
246
|
+
when String
|
|
247
|
+
a == e.name
|
|
248
|
+
when Integer
|
|
249
|
+
a == e.id
|
|
250
|
+
when :bot
|
|
251
|
+
e.current_bot?
|
|
252
|
+
else
|
|
253
|
+
a == e
|
|
254
|
+
end
|
|
255
|
+
end,
|
|
256
|
+
matches_all(@attributes[:with_text] || @attributes[:content] || @attributes[:exact_text], event.content) do |a, e|
|
|
257
|
+
case a
|
|
258
|
+
when String
|
|
259
|
+
e == a
|
|
260
|
+
when Regexp
|
|
261
|
+
match = a.match(e)
|
|
262
|
+
match ? (e == match[0]) : false
|
|
263
|
+
end
|
|
264
|
+
end,
|
|
265
|
+
matches_all(@attributes[:type] || @attributes[:message_type], event.message.type) do |a, e|
|
|
266
|
+
case a
|
|
267
|
+
when String, Symbol
|
|
268
|
+
OnyxCord::Message::TYPES[a.to_sym] == e
|
|
269
|
+
when Integer
|
|
270
|
+
a == e
|
|
271
|
+
end
|
|
272
|
+
end,
|
|
273
|
+
matches_all(@attributes[:after], event.timestamp) { |a, e| a > e },
|
|
274
|
+
matches_all(@attributes[:before], event.timestamp) { |a, e| a < e },
|
|
275
|
+
matches_all(@attributes[:private], event.channel.private?) { |a, e| !e == !a },
|
|
276
|
+
matches_all(@attributes[:server], event.server) { |a, e| a&.resolve_id == e&.resolve_id }
|
|
277
|
+
].reduce(true, &:&)
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
# @see EventHandler#after_call
|
|
281
|
+
def after_call(event)
|
|
282
|
+
if event.file.nil?
|
|
283
|
+
event.send_message(event.saved_message) unless event.saved_message.empty?
|
|
284
|
+
else
|
|
285
|
+
event.send_file(event.file, caption: event.saved_message, filename: event.filename, spoiler: event.file_spoiler)
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
# Event raised when the current bot is mentioned in a message.
|
|
291
|
+
class MentionEvent < MessageEvent
|
|
292
|
+
# @return [true, false] whether this mention event was raised
|
|
293
|
+
# due to a mention of the bot's auto-generated server role.
|
|
294
|
+
attr_reader :role_mention
|
|
295
|
+
alias_method :role_mention?, :role_mention
|
|
296
|
+
|
|
297
|
+
# @!visibility private
|
|
298
|
+
def initialize(message, bot, role_mention)
|
|
299
|
+
super(message, bot)
|
|
300
|
+
|
|
301
|
+
@role_mention = role_mention
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
# Event handler for {MentionEvent}
|
|
306
|
+
class MentionEventHandler < MessageEventHandler
|
|
307
|
+
# @!visibility private
|
|
308
|
+
def matches?(event)
|
|
309
|
+
return false unless super
|
|
310
|
+
return false unless event.is_a?(MentionEvent)
|
|
311
|
+
|
|
312
|
+
[
|
|
313
|
+
matches_all(@attributes[:role_mention], event.role_mention) do |a, e|
|
|
314
|
+
case a
|
|
315
|
+
when TrueClass
|
|
316
|
+
e == true
|
|
317
|
+
when FalseClass
|
|
318
|
+
e == false
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
].reduce(true, &:&)
|
|
322
|
+
end
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
# @see OnyxCord::EventContainer#pm
|
|
326
|
+
class PrivateMessageEvent < MessageEvent; end
|
|
327
|
+
|
|
328
|
+
# Event handler for {PrivateMessageEvent}
|
|
329
|
+
class PrivateMessageEventHandler < MessageEventHandler; end
|
|
330
|
+
|
|
331
|
+
# A subset of MessageEvent that only contains a message ID and a channel
|
|
332
|
+
class MessageIDEvent < Event
|
|
333
|
+
include Respondable
|
|
334
|
+
|
|
335
|
+
# @return [Integer] the ID associated with this event
|
|
336
|
+
attr_reader :id
|
|
337
|
+
|
|
338
|
+
# @return [Server, nil] the server associated with this event
|
|
339
|
+
attr_reader :server
|
|
340
|
+
|
|
341
|
+
# @!visibility private
|
|
342
|
+
def initialize(data, bot)
|
|
343
|
+
@id = data['id'].to_i
|
|
344
|
+
@channel = bot.channel(data['channel_id'].to_i)
|
|
345
|
+
@server = @channel.server
|
|
346
|
+
@saved_message = ''
|
|
347
|
+
@bot = bot
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
# Event handler for {MessageIDEvent}
|
|
352
|
+
class MessageIDEventHandler < EventHandler
|
|
353
|
+
def matches?(event)
|
|
354
|
+
# Check for the proper event type
|
|
355
|
+
return false unless event.is_a? MessageIDEvent
|
|
356
|
+
|
|
357
|
+
[
|
|
358
|
+
matches_all(@attributes[:id], event.id) do |a, e|
|
|
359
|
+
a.resolve_id == e.resolve_id
|
|
360
|
+
end,
|
|
361
|
+
matches_all(@attributes[:in], event.channel) do |a, e|
|
|
362
|
+
case a
|
|
363
|
+
when String
|
|
364
|
+
# Make sure to remove the "#" from channel names in case it was specified
|
|
365
|
+
a.delete('#') == e.name
|
|
366
|
+
when Integer
|
|
367
|
+
a == e.id
|
|
368
|
+
else
|
|
369
|
+
a == e
|
|
370
|
+
end
|
|
371
|
+
end,
|
|
372
|
+
matches_all(@attributes[:server], event.server) do |a, e|
|
|
373
|
+
a&.resolve_id == e&.resolve_id
|
|
374
|
+
end
|
|
375
|
+
].reduce(true, &:&)
|
|
376
|
+
end
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
# Raised when a message is edited
|
|
380
|
+
# @see OnyxCord::EventContainer#message_edit
|
|
381
|
+
class MessageEditEvent < MessageEvent; end
|
|
382
|
+
|
|
383
|
+
# Event handler for {MessageEditEvent}
|
|
384
|
+
class MessageEditEventHandler < MessageEventHandler; end
|
|
385
|
+
|
|
386
|
+
# Raised when a message is deleted
|
|
387
|
+
# @see OnyxCord::EventContainer#message_delete
|
|
388
|
+
class MessageDeleteEvent < MessageIDEvent; end
|
|
389
|
+
|
|
390
|
+
# Event handler for {MessageDeleteEvent}
|
|
391
|
+
class MessageDeleteEventHandler < MessageIDEventHandler; end
|
|
392
|
+
|
|
393
|
+
# Raised whenever a MESSAGE_UPDATE is received
|
|
394
|
+
# @see OnyxCord::EventContainer#message_update
|
|
395
|
+
class MessageUpdateEvent < MessageEvent; end
|
|
396
|
+
|
|
397
|
+
# Event handler for {MessageUpdateEvent}
|
|
398
|
+
class MessageUpdateEventHandler < MessageEventHandler; end
|
|
399
|
+
end
|