discorb 0.0.1
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/.gitignore +56 -0
- data/.yardopts +6 -0
- data/Changelog.md +5 -0
- data/Gemfile +23 -0
- data/Gemfile.lock +70 -0
- data/LICENSE.txt +21 -0
- data/README.md +53 -0
- data/Rakefile +46 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/discorb.gemspec +37 -0
- data/docs/Examples.md +26 -0
- data/docs/events.md +480 -0
- data/docs/voice_events.md +283 -0
- data/examples/components/authorization_button.rb +43 -0
- data/examples/components/select_menu.rb +61 -0
- data/examples/extension/main.rb +12 -0
- data/examples/extension/message_expander.rb +41 -0
- data/examples/simple/eval.rb +32 -0
- data/examples/simple/ping_pong.rb +16 -0
- data/examples/simple/rolepanel.rb +65 -0
- data/examples/simple/wait_for_message.rb +30 -0
- data/lib/discorb/application.rb +157 -0
- data/lib/discorb/asset.rb +57 -0
- data/lib/discorb/audit_logs.rb +323 -0
- data/lib/discorb/channel.rb +1101 -0
- data/lib/discorb/client.rb +363 -0
- data/lib/discorb/color.rb +173 -0
- data/lib/discorb/common.rb +123 -0
- data/lib/discorb/components.rb +290 -0
- data/lib/discorb/dictionary.rb +119 -0
- data/lib/discorb/embed.rb +345 -0
- data/lib/discorb/emoji.rb +218 -0
- data/lib/discorb/emoji_table.rb +3799 -0
- data/lib/discorb/error.rb +98 -0
- data/lib/discorb/event.rb +35 -0
- data/lib/discorb/extend.rb +18 -0
- data/lib/discorb/extension.rb +54 -0
- data/lib/discorb/file.rb +69 -0
- data/lib/discorb/flag.rb +109 -0
- data/lib/discorb/gateway.rb +967 -0
- data/lib/discorb/gateway_requests.rb +47 -0
- data/lib/discorb/guild.rb +1244 -0
- data/lib/discorb/guild_template.rb +211 -0
- data/lib/discorb/image.rb +43 -0
- data/lib/discorb/integration.rb +111 -0
- data/lib/discorb/intents.rb +137 -0
- data/lib/discorb/interaction.rb +333 -0
- data/lib/discorb/internet.rb +285 -0
- data/lib/discorb/invite.rb +145 -0
- data/lib/discorb/log.rb +70 -0
- data/lib/discorb/member.rb +232 -0
- data/lib/discorb/message.rb +583 -0
- data/lib/discorb/modules.rb +138 -0
- data/lib/discorb/permission.rb +270 -0
- data/lib/discorb/presence.rb +308 -0
- data/lib/discorb/reaction.rb +48 -0
- data/lib/discorb/role.rb +189 -0
- data/lib/discorb/sticker.rb +157 -0
- data/lib/discorb/user.rb +163 -0
- data/lib/discorb/utils.rb +16 -0
- data/lib/discorb/voice_state.rb +251 -0
- data/lib/discorb/webhook.rb +420 -0
- data/lib/discorb.rb +51 -0
- metadata +120 -0
@@ -0,0 +1,138 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Discorb
|
4
|
+
#
|
5
|
+
# Module for sending and reading messages.
|
6
|
+
#
|
7
|
+
module Messageable
|
8
|
+
#
|
9
|
+
# Post a message to the channel.
|
10
|
+
#
|
11
|
+
# @param [String] content The message content.
|
12
|
+
# @param [Boolean] tts Whether the message is tts.
|
13
|
+
# @param [Discorb::Embed] embed The embed to send.
|
14
|
+
# @param [Array<Discorb::Embed>] embeds The embeds to send.
|
15
|
+
# @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions.
|
16
|
+
# @param [Discorb::Message, Discorb::Message::Reference] reference The message to reply to.
|
17
|
+
# @param [Array<Discorb::Components>, Array<Array<Discorb::Components>>] components The components to send.
|
18
|
+
# @param [Discorb::File] file The file to send.
|
19
|
+
# @param [Array<Discorb::File>] files The files to send.
|
20
|
+
#
|
21
|
+
# @return [Discorb::Message] The message sent.
|
22
|
+
#
|
23
|
+
def post(content = nil, tts: false, embed: nil, embeds: nil, allowed_mentions: nil,
|
24
|
+
reference: nil, components: nil, file: nil, files: nil)
|
25
|
+
Async do |_task|
|
26
|
+
payload = {}
|
27
|
+
payload[:content] = content if content
|
28
|
+
payload[:tts] = tts
|
29
|
+
tmp_embed = if embed
|
30
|
+
[embed]
|
31
|
+
elsif embeds
|
32
|
+
embeds
|
33
|
+
end
|
34
|
+
payload[:embeds] = tmp_embed.map(&:to_hash) if tmp_embed
|
35
|
+
payload[:allowed_mentions] =
|
36
|
+
allowed_mentions ? allowed_mentions.to_hash(@client.allowed_mentions) : @client.allowed_mentions.to_hash
|
37
|
+
payload[:message_reference] = reference.to_reference if reference
|
38
|
+
if components
|
39
|
+
tmp_components = []
|
40
|
+
tmp_row = []
|
41
|
+
components.each do |c|
|
42
|
+
case c
|
43
|
+
when Array
|
44
|
+
tmp_components << tmp_row
|
45
|
+
tmp_row = []
|
46
|
+
tmp_components << c
|
47
|
+
when SelectMenu
|
48
|
+
tmp_components << tmp_row
|
49
|
+
tmp_row = []
|
50
|
+
tmp_components << [c]
|
51
|
+
else
|
52
|
+
tmp_row << c
|
53
|
+
end
|
54
|
+
end
|
55
|
+
tmp_components << tmp_row
|
56
|
+
payload[:components] = tmp_components.filter { |c| c.length.positive? }.map { |c| { type: 1, components: c.map(&:to_hash) } }
|
57
|
+
end
|
58
|
+
files = [file] if file
|
59
|
+
if files
|
60
|
+
headers, payload = Internet.multipart(payload, files)
|
61
|
+
else
|
62
|
+
headers = {}
|
63
|
+
end
|
64
|
+
_resp, data = @client.internet.post("#{base_url.wait}/messages", payload, headers: headers).wait
|
65
|
+
Message.new(@client, data.merge({ guild_id: @guild_id.to_s }))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# Fetch a message from ID.
|
71
|
+
#
|
72
|
+
# @param [Discorb::Snowflake] id The ID of the message.
|
73
|
+
#
|
74
|
+
# @return [Discorb::Message] The message.
|
75
|
+
# @raise [Discorb::NotFoundError] If the message is not found.
|
76
|
+
#
|
77
|
+
def fetch_message(id)
|
78
|
+
Async do
|
79
|
+
_resp, data = @client.internet.get("#{base_url.wait}/messages/#{id}").wait
|
80
|
+
Message.new(@client, data.merge({ guild_id: @guild_id.to_s }))
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
#
|
85
|
+
# Fetch a message history.
|
86
|
+
#
|
87
|
+
# @param [Integer] limit The number of messages to fetch.
|
88
|
+
# @param [Discorb::Snowflake] before The ID of the message to fetch before.
|
89
|
+
# @param [Discorb::Snowflake] after The ID of the message to fetch after.
|
90
|
+
# @param [Discorb::Snowflake] around The ID of the message to fetch around.
|
91
|
+
#
|
92
|
+
# @return [Array<Discorb::Message>] The messages.
|
93
|
+
#
|
94
|
+
def fetch_messages(limit = 50, before: nil, after: nil, around: nil)
|
95
|
+
Async do
|
96
|
+
params = {
|
97
|
+
limit: limit,
|
98
|
+
before: Discorb::Utils.try(after, :id),
|
99
|
+
after: Discorb::Utils.try(around, :id),
|
100
|
+
around: Discorb::Utils.try(before, :id),
|
101
|
+
}.filter { |_k, v| !v.nil? }.to_h
|
102
|
+
_resp, messages = @client.internet.get("#{base_url.wait}/messages?#{URI.encode_www_form(params)}").wait
|
103
|
+
messages.map { |m| Message.new(@client, m.merge({ guild_id: @guild_id.to_s })) }
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
#
|
108
|
+
# Trigger the typing indicator in the channel.
|
109
|
+
# @macro async
|
110
|
+
# @macro http
|
111
|
+
#
|
112
|
+
# If block is given, trigger typing indicator during executing block.
|
113
|
+
# @example
|
114
|
+
# channel.typing do
|
115
|
+
# channel.post("Waiting for 60 seconds...")
|
116
|
+
# sleep 60
|
117
|
+
# channel.post("Done!")
|
118
|
+
# end
|
119
|
+
#
|
120
|
+
def typing
|
121
|
+
Async do |task|
|
122
|
+
if block_given?
|
123
|
+
begin
|
124
|
+
post_task = task.async do
|
125
|
+
@client.internet.post("/channels/#{@id}/typing", {})
|
126
|
+
sleep(5)
|
127
|
+
end
|
128
|
+
yield
|
129
|
+
ensure
|
130
|
+
post_task.stop
|
131
|
+
end
|
132
|
+
else
|
133
|
+
@client.internet.post("/channels/#{@id}/typing", {})
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,270 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Discorb
|
4
|
+
#
|
5
|
+
# Represents a permission per guild.
|
6
|
+
# ## Flag fields
|
7
|
+
# |`1 << 0`|`:create_instant_invite`|
|
8
|
+
# |`1 << 1`|`:kick_members`|
|
9
|
+
# |`1 << 2`|`:ban_members`|
|
10
|
+
# |`1 << 3`|`:administrator`|
|
11
|
+
# |`1 << 4`|`:manage_channels`|
|
12
|
+
# |`1 << 5`|`:manage_guild`|
|
13
|
+
# |`1 << 6`|`:add_reactions`|
|
14
|
+
# |`1 << 7`|`:view_audit_log`|
|
15
|
+
# |`1 << 8`|`:priority_speaker`|
|
16
|
+
# |`1 << 9`|`:stream`|
|
17
|
+
# |`1 << 10`|`:view_channel`|
|
18
|
+
# |`1 << 11`|`:send_messages`|
|
19
|
+
# |`1 << 12`|`:send_tts_messages`|
|
20
|
+
# |`1 << 13`|`:manage_messages`|
|
21
|
+
# |`1 << 14`|`:embed_links`|
|
22
|
+
# |`1 << 15`|`:attach_files`|
|
23
|
+
# |`1 << 16`|`:read_message_history`|
|
24
|
+
# |`1 << 17`|`:mention_everyone`|
|
25
|
+
# |`1 << 18`|`:use_external_emojis`|
|
26
|
+
# |`1 << 19`|`:view_guild_insights`|
|
27
|
+
# |`1 << 20`|`:connect`|
|
28
|
+
# |`1 << 21`|`:speak`|
|
29
|
+
# |`1 << 22`|`:mute_members`|
|
30
|
+
# |`1 << 23`|`:deafen_members`|
|
31
|
+
# |`1 << 24`|`:move_members`|
|
32
|
+
# |`1 << 25`|`:use_vad`|
|
33
|
+
# |`1 << 26`|`:change_nickname`|
|
34
|
+
# |`1 << 27`|`:manage_nicknames`|
|
35
|
+
# |`1 << 28`|`:manage_roles`|
|
36
|
+
# |`1 << 29`|`:manage_webhooks`|
|
37
|
+
# |`1 << 30`|`:manage_emojis`|
|
38
|
+
# |`1 << 31`|`:use_slash_commands`|
|
39
|
+
# |`1 << 32`|`:request_to_speak`|
|
40
|
+
# |`1 << 34`|`:manage_threads`|
|
41
|
+
# |`1 << 35`|`:use_public_threads`|
|
42
|
+
# |`1 << 36`|`:use_private_threads`|
|
43
|
+
#
|
44
|
+
class Permission < Flag
|
45
|
+
@bits = {
|
46
|
+
create_instant_invite: 0,
|
47
|
+
kick_members: 1,
|
48
|
+
ban_members: 2,
|
49
|
+
administrator: 3,
|
50
|
+
manage_channels: 4,
|
51
|
+
manage_guild: 5,
|
52
|
+
add_reactions: 6,
|
53
|
+
view_audit_log: 7,
|
54
|
+
priority_speaker: 8,
|
55
|
+
stream: 9,
|
56
|
+
view_channel: 10,
|
57
|
+
send_messages: 11,
|
58
|
+
send_tts_messages: 12,
|
59
|
+
manage_messages: 13,
|
60
|
+
embed_links: 14,
|
61
|
+
attach_files: 15,
|
62
|
+
read_message_history: 16,
|
63
|
+
mention_everyone: 17,
|
64
|
+
use_external_emojis: 18,
|
65
|
+
view_guild_insights: 19,
|
66
|
+
connect: 20,
|
67
|
+
speak: 21,
|
68
|
+
mute_members: 22,
|
69
|
+
deafen_members: 23,
|
70
|
+
move_members: 24,
|
71
|
+
use_vad: 25,
|
72
|
+
change_nickname: 26,
|
73
|
+
manage_nicknames: 27,
|
74
|
+
manage_roles: 28,
|
75
|
+
manage_webhooks: 29,
|
76
|
+
manage_emojis: 30,
|
77
|
+
use_slash_commands: 31,
|
78
|
+
request_to_speak: 32,
|
79
|
+
manage_threads: 34,
|
80
|
+
use_public_threads: 35,
|
81
|
+
use_private_threads: 36,
|
82
|
+
}.freeze
|
83
|
+
end
|
84
|
+
|
85
|
+
#
|
86
|
+
# Represents a permission per channel.
|
87
|
+
#
|
88
|
+
class PermissionOverwrite
|
89
|
+
# @!attribute [r] allow
|
90
|
+
# @return [Discorb::Permission] The allowed permissions.
|
91
|
+
# @!attribute [r] deny
|
92
|
+
# @return [Discorb::Permission] The denied permissions.
|
93
|
+
# @!attribute [r] allow_value
|
94
|
+
# @return [Integer] The allowed permissions as an integer.
|
95
|
+
# @!attribute [r] deny_value
|
96
|
+
# @return [Integer] The denied permissions as an integer.
|
97
|
+
|
98
|
+
@raw_bits = {
|
99
|
+
create_instant_invite: 0,
|
100
|
+
kick_members: 1,
|
101
|
+
ban_members: 2,
|
102
|
+
administrator: 3,
|
103
|
+
manage_channels: 4,
|
104
|
+
manage_guild: 5,
|
105
|
+
add_reactions: 6,
|
106
|
+
view_audit_log: 7,
|
107
|
+
priority_speaker: 8,
|
108
|
+
stream: 9,
|
109
|
+
view_channel: 10,
|
110
|
+
send_messages: 11,
|
111
|
+
send_tts_messages: 12,
|
112
|
+
manage_messages: 13,
|
113
|
+
embed_links: 14,
|
114
|
+
attach_files: 15,
|
115
|
+
read_message_history: 16,
|
116
|
+
mention_everyone: 17,
|
117
|
+
use_external_emojis: 18,
|
118
|
+
view_guild_insights: 19,
|
119
|
+
connect: 20,
|
120
|
+
speak: 21,
|
121
|
+
mute_members: 22,
|
122
|
+
deafen_members: 23,
|
123
|
+
move_members: 24,
|
124
|
+
use_vad: 25,
|
125
|
+
change_nickname: 26,
|
126
|
+
manage_nicknames: 27,
|
127
|
+
manage_roles: 28,
|
128
|
+
manage_webhooks: 29,
|
129
|
+
manage_emojis: 30,
|
130
|
+
use_slash_commands: 31,
|
131
|
+
request_to_speak: 32,
|
132
|
+
manage_threads: 34,
|
133
|
+
use_public_threads: 35,
|
134
|
+
use_private_threads: 36,
|
135
|
+
}.freeze
|
136
|
+
@bits = @raw_bits.transform_values { |v| 1 << v }.freeze
|
137
|
+
|
138
|
+
# @!visibility private
|
139
|
+
def initialize(allow, deny)
|
140
|
+
@allow = allow
|
141
|
+
@deny = deny
|
142
|
+
end
|
143
|
+
|
144
|
+
def allow
|
145
|
+
self.class.bits.keys.filter { |field| @allow & self.class.bits[field] != 0 }
|
146
|
+
end
|
147
|
+
|
148
|
+
alias +@ allow
|
149
|
+
|
150
|
+
def deny
|
151
|
+
self.class.bits.keys.filter { |field| @deny & self.class.bits[field] != 0 }
|
152
|
+
end
|
153
|
+
|
154
|
+
alias -@ deny
|
155
|
+
|
156
|
+
def allow_value
|
157
|
+
@allow
|
158
|
+
end
|
159
|
+
|
160
|
+
def deny_value
|
161
|
+
@deny
|
162
|
+
end
|
163
|
+
|
164
|
+
#
|
165
|
+
# Converts the permission overwrite to a hash.
|
166
|
+
#
|
167
|
+
# @return [Hash] The permission overwrite as a hash.
|
168
|
+
#
|
169
|
+
def to_hash
|
170
|
+
self.class.bits.keys.map do |field|
|
171
|
+
[field, if @allow & self.class.bits[field] != 0
|
172
|
+
true
|
173
|
+
elsif @deny & self.class.bits[method] != 0
|
174
|
+
false
|
175
|
+
end]
|
176
|
+
end.to_h
|
177
|
+
end
|
178
|
+
|
179
|
+
#
|
180
|
+
# Union of the permission overwrites.
|
181
|
+
#
|
182
|
+
# @param [Discorb::PermissionOverwrite] other The other permission overwrite.
|
183
|
+
#
|
184
|
+
# @return [Discorb::PermissionOverwrite] The union of the permission overwrites.
|
185
|
+
#
|
186
|
+
def +(other)
|
187
|
+
result = to_hash
|
188
|
+
self.class.bits.each_key do |field|
|
189
|
+
result[field] = other[field] unless other[field].nil?
|
190
|
+
end
|
191
|
+
self.class.from_hash(result)
|
192
|
+
end
|
193
|
+
|
194
|
+
#
|
195
|
+
# Returns whether overwrite of the given field.
|
196
|
+
#
|
197
|
+
# @param [Symbol] field The field to check.
|
198
|
+
#
|
199
|
+
# @return [true, false, nil] Whether the field is allowed, denied or not set.
|
200
|
+
#
|
201
|
+
def [](field)
|
202
|
+
if @allow & self.class.bits[field] != 0
|
203
|
+
true
|
204
|
+
elsif @deny & self.class.bits[field] != 0
|
205
|
+
false
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
#
|
210
|
+
# Sets the given field to the given value.
|
211
|
+
#
|
212
|
+
# @param [Symbol] key The field to set.
|
213
|
+
# @param [Boolean] bool The value to set.
|
214
|
+
#
|
215
|
+
def []=(key, bool)
|
216
|
+
case bool
|
217
|
+
when true
|
218
|
+
@allow |= self.class.bits[key]
|
219
|
+
@deny &= ~self.class.bits[key]
|
220
|
+
when false
|
221
|
+
@allow &= ~self.class.bits[key]
|
222
|
+
@deny |= self.class.bits[key]
|
223
|
+
else
|
224
|
+
@allow &= ~self.class.bits[key]
|
225
|
+
@deny &= ~self.class.bits[key]
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
def method_missing(method, bool = nil)
|
230
|
+
if self.class.bits.key?(method)
|
231
|
+
self[method]
|
232
|
+
elsif self.class.bits.key?(method.to_s.delete_suffix("=").to_sym)
|
233
|
+
key = method.to_s.delete_suffix("=").to_sym
|
234
|
+
self[key] = bool
|
235
|
+
else
|
236
|
+
super
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
def respond_to_missing?(method, _arg)
|
241
|
+
self.class.bits.key?(method.to_s.delete_suffix("=").to_sym) ? true : super
|
242
|
+
end
|
243
|
+
|
244
|
+
class << self
|
245
|
+
# @!visibility private
|
246
|
+
attr_reader :bits
|
247
|
+
|
248
|
+
#
|
249
|
+
# Initializes a permission overwrite from a hash.
|
250
|
+
#
|
251
|
+
# @param [Hash] hash The hash to initialize the permission overwrite from.
|
252
|
+
#
|
253
|
+
# @return [Discorb::PermissionOverwrite] The permission overwrite.
|
254
|
+
#
|
255
|
+
def from_hash(hash)
|
256
|
+
allow = 0
|
257
|
+
deny = 0
|
258
|
+
hash.filter { |k, v| self.class.bits.keys.include?(k) && [true, false].include?(v) }.each do |k, v|
|
259
|
+
if v
|
260
|
+
allow += self.class.bits[k]
|
261
|
+
else
|
262
|
+
deny += self.class.bits[k]
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
new(allow, deny)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
@@ -0,0 +1,308 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Discorb
|
4
|
+
#
|
5
|
+
# Represents a presence of user.
|
6
|
+
#
|
7
|
+
class Presence < DiscordModel
|
8
|
+
# @return [:online, :idle, :dnd, :offline] The status of the user.
|
9
|
+
attr_reader :status
|
10
|
+
# @return [Array<Discorb::Presence::Activity>] The activities of the user.
|
11
|
+
attr_reader :activities
|
12
|
+
# @return [Discorb::Presence::ClientStatus] The client status of the user.
|
13
|
+
attr_reader :client_status
|
14
|
+
|
15
|
+
# @!attribute [r] user
|
16
|
+
# @return [Discorb::User] The user of the presence.
|
17
|
+
# @!attribute [r] guild
|
18
|
+
# @return [Discorb::Guild] The guild of the presence.
|
19
|
+
# @!attribute [r] activity
|
20
|
+
# @return [Discorb::Presence::Activity] The activity of the presence.
|
21
|
+
|
22
|
+
# @!visibility private
|
23
|
+
def initialize(client, data)
|
24
|
+
@client = client
|
25
|
+
@data = data
|
26
|
+
_set_data(data)
|
27
|
+
end
|
28
|
+
|
29
|
+
def user
|
30
|
+
@client.users[@user_id]
|
31
|
+
end
|
32
|
+
|
33
|
+
def guild
|
34
|
+
@client.guilds[@guild_id]
|
35
|
+
end
|
36
|
+
|
37
|
+
def activity
|
38
|
+
@activities[0]
|
39
|
+
end
|
40
|
+
|
41
|
+
def inspect
|
42
|
+
"#<#{self.class} @status=#{@status.inspect} @activity=#{activity.inspect}>"
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Represents an activity of a user.
|
47
|
+
#
|
48
|
+
class Activity < DiscordModel
|
49
|
+
# @return [String] The name of the activity.
|
50
|
+
attr_reader :name
|
51
|
+
# @return [:game, :streaming, :listening, :watching, :custom, :competing] The type of the activity.
|
52
|
+
attr_reader :type
|
53
|
+
# @return [String] The url of the activity.
|
54
|
+
attr_reader :url
|
55
|
+
# @return [Time] The time the activity was created.
|
56
|
+
attr_reader :created_at
|
57
|
+
alias started_at created_at
|
58
|
+
# @return [Discorb::Presence::Activity::Timestamps] The timestamps of the activity.
|
59
|
+
attr_reader :timestamps
|
60
|
+
# @return [Discorb::Snowflake] The application id of the activity.
|
61
|
+
attr_reader :application_id
|
62
|
+
# @return [String] The details of the activity.
|
63
|
+
attr_reader :details
|
64
|
+
# @return [String] The state of party.
|
65
|
+
attr_reader :state
|
66
|
+
# @return [Discorb::Emoji] The emoji of the activity.
|
67
|
+
attr_reader :emoji
|
68
|
+
# @return [Discorb::Presence::Activity::Party] The party of the activity.
|
69
|
+
# @return [nil] If the activity is not a party activity.
|
70
|
+
attr_reader :party
|
71
|
+
# @return [Discorb::Presence::Activity::Asset] The assets of the activity.
|
72
|
+
# @return [nil] If the activity has no assets.
|
73
|
+
attr_reader :assets
|
74
|
+
# @return [Discorb::StageInstance] The instance of the activity.
|
75
|
+
# @return [nil] If the activity is not a stage activity.
|
76
|
+
attr_reader :instance
|
77
|
+
# @return [Array<Discorb::Presence::Activity::Button>] The buttons of the activity.
|
78
|
+
# @return [nil] If the activity has no buttons.
|
79
|
+
attr_reader :buttons
|
80
|
+
# @return [Discorb::Presence::Activity::Flag] The flags of the activity.
|
81
|
+
attr_reader :flags
|
82
|
+
|
83
|
+
@activity_types = {
|
84
|
+
0 => :game,
|
85
|
+
1 => :streaming,
|
86
|
+
2 => :listening,
|
87
|
+
3 => :watching,
|
88
|
+
4 => :custom,
|
89
|
+
5 => :competing,
|
90
|
+
}
|
91
|
+
|
92
|
+
# @!visibility private
|
93
|
+
def initialize(data)
|
94
|
+
@name = data[:name]
|
95
|
+
@type = self.class.activity_types[data[:type]]
|
96
|
+
@url = data[:url]
|
97
|
+
@created_at = Time.at(data[:created_at])
|
98
|
+
@timestamps = data[:timestamps] && Timestamps.new(data[:timestamps])
|
99
|
+
@application_id = data[:application_id] && Snowflake.new(data[:application_id])
|
100
|
+
@details = data[:details]
|
101
|
+
@state = data[:state]
|
102
|
+
@emoji = if data[:emoji]
|
103
|
+
data[:emoji][:id].nil? ? UnicodeEmoji.new(data[:emoji][:name]) : PartialEmoji.new(data[:emoji])
|
104
|
+
end
|
105
|
+
@party = data[:party] && Party.new(data[:party])
|
106
|
+
@assets = data[:assets] && Asset.new(data[:assets])
|
107
|
+
@instance = data[:instance]
|
108
|
+
@buttons = data[:buttons] && data[:buttons].map { |b| Button.new(b) }
|
109
|
+
@flags = data[:flags] && Flag.new(data[:flags])
|
110
|
+
end
|
111
|
+
|
112
|
+
#
|
113
|
+
# Convert the activity to a string.
|
114
|
+
#
|
115
|
+
# @return [String] The string representation of the activity.
|
116
|
+
#
|
117
|
+
def to_s
|
118
|
+
case @type
|
119
|
+
when :game
|
120
|
+
"Playing #{@name}"
|
121
|
+
when :streaming
|
122
|
+
"Streaming #{@details}"
|
123
|
+
when :listening
|
124
|
+
"Listening to #{@name}"
|
125
|
+
when :watching
|
126
|
+
"Watching #{@name}"
|
127
|
+
when :custom
|
128
|
+
"#{@emoji} #{@state}"
|
129
|
+
when :competing
|
130
|
+
"Competing in #{@name}"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
#
|
135
|
+
# Represents the timestamps of an activity.
|
136
|
+
#
|
137
|
+
class Timestamps < DiscordModel
|
138
|
+
# @return [Time] The start time of the activity.
|
139
|
+
attr_reader :start
|
140
|
+
# @return [Time] The end time of the activity.
|
141
|
+
attr_reader :end
|
142
|
+
|
143
|
+
# @!visibility private
|
144
|
+
def initialize(data)
|
145
|
+
@start = data[:start] && Time.at(data[:start])
|
146
|
+
@end = data[:end] && Time.at(data[:end])
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
class Party < DiscordModel
|
151
|
+
# @return [String] The id of the party.
|
152
|
+
attr_reader :id
|
153
|
+
|
154
|
+
# @!attribute [r] current_size
|
155
|
+
# @return [Integer] The current size of the party.
|
156
|
+
# @!attribute [r] max_size
|
157
|
+
# @return [Integer] The max size of the party.
|
158
|
+
|
159
|
+
# @!visibility private
|
160
|
+
def initialize(data)
|
161
|
+
@id = data[:id]
|
162
|
+
@size = data[:size]
|
163
|
+
end
|
164
|
+
|
165
|
+
def current_size
|
166
|
+
@size[0]
|
167
|
+
end
|
168
|
+
|
169
|
+
def max_size
|
170
|
+
@size[1]
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
#
|
175
|
+
# Represents the assets of an activity.
|
176
|
+
#
|
177
|
+
class Asset < DiscordModel
|
178
|
+
# @return [String] The large image ID of the asset.
|
179
|
+
attr_reader :large_image
|
180
|
+
alias large_id large_image
|
181
|
+
# @return [String] The large text of the activity.
|
182
|
+
attr_reader :large_text
|
183
|
+
# @return [String] The small image ID of the activity.
|
184
|
+
attr_reader :small_image
|
185
|
+
alias small_id small_image
|
186
|
+
# @return [String] The small text of the activity.
|
187
|
+
attr_reader :small_text
|
188
|
+
|
189
|
+
def initialize(data)
|
190
|
+
@large_image = data[:large_image]
|
191
|
+
@large_text = data[:large_text]
|
192
|
+
@small_image = data[:small_image]
|
193
|
+
@small_text = data[:small_text]
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
#
|
198
|
+
# Represents the flags of an activity.
|
199
|
+
# ## Flag fields
|
200
|
+
# |`1 << 0`|`:instance`|
|
201
|
+
# |`1 << 1`|`:join`|
|
202
|
+
# |`1 << 2`|`:spectate`|
|
203
|
+
# |`1 << 3`|`:join_request`|
|
204
|
+
# |`1 << 4`|`:sync`|
|
205
|
+
# |`1 << 5`|`:play`|
|
206
|
+
#
|
207
|
+
class Flag < Discorb::Flag
|
208
|
+
@bits = {
|
209
|
+
instance: 0,
|
210
|
+
join: 1,
|
211
|
+
spectate: 2,
|
212
|
+
join_request: 3,
|
213
|
+
sync: 4,
|
214
|
+
play: 5,
|
215
|
+
}
|
216
|
+
end
|
217
|
+
|
218
|
+
#
|
219
|
+
# Represents a secrets of an activity.
|
220
|
+
#
|
221
|
+
class Secrets < DiscordModel
|
222
|
+
# @return [String] The join secret of the activity.
|
223
|
+
attr_reader :join
|
224
|
+
# @return [String] The spectate secret of the activity.
|
225
|
+
attr_reader :spectate
|
226
|
+
# @return [String] The match secret of the activity.
|
227
|
+
attr_reader :match
|
228
|
+
|
229
|
+
# @!visibility private
|
230
|
+
def initialize(data)
|
231
|
+
@join = data[:join]
|
232
|
+
@spectate = data[:spectate]
|
233
|
+
@match = data[:match]
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
#
|
238
|
+
# Represents a button of an activity.
|
239
|
+
#
|
240
|
+
class Button < DiscordModel
|
241
|
+
# @return [String] The text of the button.
|
242
|
+
attr_reader :label
|
243
|
+
# @return [String] The URL of the button.
|
244
|
+
attr_reader :url
|
245
|
+
alias text label
|
246
|
+
|
247
|
+
# @!visibility private
|
248
|
+
def initialize(data)
|
249
|
+
@label = data[0]
|
250
|
+
@url = data[1]
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
class << self
|
255
|
+
# @!visibility private
|
256
|
+
attr_reader :activity_types
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
#
|
261
|
+
# Represents a user's client status.
|
262
|
+
#
|
263
|
+
class ClientStatus < DiscordModel
|
264
|
+
# @return [Symbol] The desktop status of the user.
|
265
|
+
attr_reader :desktop
|
266
|
+
# @return [Symbol] The mobile status of the user.
|
267
|
+
attr_reader :mobile
|
268
|
+
# @return [Symbol] The web status of the user.
|
269
|
+
attr_reader :web
|
270
|
+
|
271
|
+
# @!attribute [r] desktop?
|
272
|
+
# @return [Boolean] Whether the user is not offline on desktop.
|
273
|
+
# @!attribute [r] mobile?
|
274
|
+
# @return [Boolean] Whether the user is not offline on mobile.
|
275
|
+
# @!attribute [r] web?
|
276
|
+
# @return [Boolean] Whether the user is not offline on web.
|
277
|
+
|
278
|
+
# @!visibility private
|
279
|
+
def initialize(data)
|
280
|
+
@desktop = data[:desktop]&.to_sym || :offline
|
281
|
+
@mobile = data[:mobile]&.to_sym || :offline
|
282
|
+
@web = data[:web]&.to_sym || :offline
|
283
|
+
end
|
284
|
+
|
285
|
+
def desktop?
|
286
|
+
@desktop != :offline
|
287
|
+
end
|
288
|
+
|
289
|
+
def mobile?
|
290
|
+
@mobile != :offline
|
291
|
+
end
|
292
|
+
|
293
|
+
def web?
|
294
|
+
@web != :offline
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
private
|
299
|
+
|
300
|
+
def _set_data(data)
|
301
|
+
@user_id = data[:user][:id]
|
302
|
+
@guild_id = data[:guild_id]
|
303
|
+
@status = data[:status].to_sym
|
304
|
+
@activities = data[:activities].map { |a| Activity.new(a) }
|
305
|
+
@client_status = ClientStatus.new(data[:client_status])
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|