discorb 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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,145 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Discorb
|
4
|
+
#
|
5
|
+
# Represents invite of discord.
|
6
|
+
#
|
7
|
+
class Invite < DiscordModel
|
8
|
+
# @return [String] The code of invite.
|
9
|
+
attr_reader :code
|
10
|
+
|
11
|
+
# @return [:voice, :stream, :guild] The type of invite.
|
12
|
+
attr_reader :target_type
|
13
|
+
|
14
|
+
# @return [User] The user of invite.
|
15
|
+
attr_reader :target_user
|
16
|
+
|
17
|
+
# @return [Integer] The approximate number of online users of invite.
|
18
|
+
attr_reader :approximate_presence_count
|
19
|
+
|
20
|
+
# @return [Integer] The approximate number of members of invite.
|
21
|
+
attr_reader :approximate_member_count
|
22
|
+
|
23
|
+
# @return [Time] The time when invite expires.
|
24
|
+
# @return [nil] The invite never expires.
|
25
|
+
# @macro [new] nometa
|
26
|
+
# @return [nil] The invite doesn't have metadata.
|
27
|
+
attr_reader :expires_at
|
28
|
+
|
29
|
+
# @return [Integer] The number of uses of invite.
|
30
|
+
# @macro nometa
|
31
|
+
attr_reader :uses
|
32
|
+
|
33
|
+
# @return [Integer] The maximum number of uses of invite.
|
34
|
+
# @macro nometa
|
35
|
+
attr_reader :max_uses
|
36
|
+
|
37
|
+
# @return [Integer] Duration of invite in seconds.
|
38
|
+
# @macro nometa
|
39
|
+
attr_reader :max_age
|
40
|
+
|
41
|
+
# @return [Time] The time when invite was created.
|
42
|
+
# @macro nometa
|
43
|
+
attr_reader :created_at
|
44
|
+
|
45
|
+
# @!attribute [r] channel
|
46
|
+
# Channel of the invite.
|
47
|
+
#
|
48
|
+
# @return [Discorb::Channel] Channel of invite.
|
49
|
+
# @macro client_cache
|
50
|
+
#
|
51
|
+
# @!attribute [r] guild
|
52
|
+
# Guild of the invite.
|
53
|
+
#
|
54
|
+
# @return [Discorb::Guild] Guild of invite.
|
55
|
+
# @macro client_cache
|
56
|
+
#
|
57
|
+
# @!attribute [r] remain_uses
|
58
|
+
# Number of remaining uses of invite.
|
59
|
+
# @return [Integer] Number of remaining uses of invite.
|
60
|
+
#
|
61
|
+
# @!attribute [r] url
|
62
|
+
# Full url of invite.
|
63
|
+
# @return [String] Full url of invite.
|
64
|
+
#
|
65
|
+
# @!attribute [r] temporary?
|
66
|
+
# Whether the invite is temporary.
|
67
|
+
# @return [Boolean]
|
68
|
+
|
69
|
+
@target_types = {
|
70
|
+
nil => :voice,
|
71
|
+
1 => :stream,
|
72
|
+
2 => :guild,
|
73
|
+
}.freeze
|
74
|
+
|
75
|
+
# @!visibility private
|
76
|
+
def initialize(client, data, gateway)
|
77
|
+
@client = client
|
78
|
+
@data = data[:data]
|
79
|
+
_set_data(data, gateway)
|
80
|
+
end
|
81
|
+
|
82
|
+
def channel
|
83
|
+
@client.channels[@channel_data[:id]]
|
84
|
+
end
|
85
|
+
|
86
|
+
def guild
|
87
|
+
@client.guilds[@guild_data[:id]]
|
88
|
+
end
|
89
|
+
|
90
|
+
def url
|
91
|
+
"https://discord.gg/#{@code}"
|
92
|
+
end
|
93
|
+
|
94
|
+
def remain_uses
|
95
|
+
@max_uses && @max_uses - @uses
|
96
|
+
end
|
97
|
+
|
98
|
+
def temporary?
|
99
|
+
@temporary
|
100
|
+
end
|
101
|
+
|
102
|
+
# Delete the invite.
|
103
|
+
# @macro async
|
104
|
+
# @macro http
|
105
|
+
def delete!(reason: nil)
|
106
|
+
Async do
|
107
|
+
@client.internet.delete("/invites/#{@code}", audit_log_reason: reason)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
|
113
|
+
def _set_data(data, gateway)
|
114
|
+
@code = data[:code]
|
115
|
+
if gateway
|
116
|
+
@channel_data = { id: data[:channel_id] }
|
117
|
+
@guild_data = { id: data[:guild_id] }
|
118
|
+
else
|
119
|
+
@guild_data = data[:guild]
|
120
|
+
@channel_data = data[:channel]
|
121
|
+
@approximate_presence_count = data[:approximate_presence_count]
|
122
|
+
@approximate_member_count = data[:approximate_member_count]
|
123
|
+
@expires_at = data[:expires_at] && Time.iso8601(data[:expires_at])
|
124
|
+
end
|
125
|
+
@inviter_data = data[:inviter]
|
126
|
+
@target_type = self.class.target_types[data[:target_type]]
|
127
|
+
@target_user = @client.users[data[:target_user][:id]] || User.new(@client, data[:target_user]) if data[:target_user]
|
128
|
+
# @target_application = nil
|
129
|
+
|
130
|
+
# @stage_instance = data[:stage_instance] && Invite::StageInstance.new(self, data[:stage_instance])
|
131
|
+
return unless data.key?(:uses)
|
132
|
+
|
133
|
+
@uses = data[:uses]
|
134
|
+
@max_uses = data[:max_uses]
|
135
|
+
@max_age = data[:max_age]
|
136
|
+
@temporary = data[:temporary]
|
137
|
+
@created_at = Time.iso8601(data[:created_at])
|
138
|
+
end
|
139
|
+
|
140
|
+
class << self
|
141
|
+
# @!visibility private
|
142
|
+
attr_reader :target_types
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
data/lib/discorb/log.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Discorb
|
4
|
+
# @!visibility private
|
5
|
+
class Logger
|
6
|
+
attr_reader :out, :colorize_log
|
7
|
+
|
8
|
+
@levels = %i[debug info warn error fatal].freeze
|
9
|
+
|
10
|
+
def initialize(out, colorize_log, level)
|
11
|
+
@out = out
|
12
|
+
@level = self.class.levels.index(level)
|
13
|
+
@colorize_log = colorize_log
|
14
|
+
end
|
15
|
+
|
16
|
+
def level
|
17
|
+
@levels[@level]
|
18
|
+
end
|
19
|
+
|
20
|
+
def level=(level)
|
21
|
+
@level = @levels.index(level)
|
22
|
+
end
|
23
|
+
|
24
|
+
def debug(message)
|
25
|
+
return unless @level <= 0
|
26
|
+
|
27
|
+
write_output("DEBUG", "\e[90m", message)
|
28
|
+
end
|
29
|
+
|
30
|
+
def info(message)
|
31
|
+
return unless @level <= 1
|
32
|
+
|
33
|
+
write_output("INFO", "\e[94m", message)
|
34
|
+
end
|
35
|
+
|
36
|
+
def warn(message)
|
37
|
+
return unless @level <= 2
|
38
|
+
|
39
|
+
write_output("WARN", "\e[93m", message)
|
40
|
+
end
|
41
|
+
|
42
|
+
def error(message)
|
43
|
+
return unless @level <= 3
|
44
|
+
|
45
|
+
write_output("ERROR", "\e[31m", message)
|
46
|
+
end
|
47
|
+
|
48
|
+
def fatal(message)
|
49
|
+
return unless @level <= 4
|
50
|
+
|
51
|
+
write_output("FATAL", "\e[91m", message)
|
52
|
+
end
|
53
|
+
|
54
|
+
class << self
|
55
|
+
attr_reader :levels
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def write_output(name, color, message)
|
61
|
+
return unless @out
|
62
|
+
|
63
|
+
if @colorize_log
|
64
|
+
@out.puts("[#{Time.now.iso8601}] #{color}#{name}\e[m -- #{message}")
|
65
|
+
else
|
66
|
+
@out.puts("[#{Time.now.iso8601}] #{name} -- #{message}")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,232 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Discorb
|
4
|
+
#
|
5
|
+
# Represents a member of a guild.
|
6
|
+
#
|
7
|
+
class Member < User
|
8
|
+
# @return [Time] The time the member boosted the guild.
|
9
|
+
attr_reader :premium_since
|
10
|
+
# @return [String] The nickname of the member.
|
11
|
+
# @return [nil] If the member has no nickname.
|
12
|
+
attr_reader :nick
|
13
|
+
# @return [Time] The time the member joined the guild.
|
14
|
+
attr_reader :joined_at
|
15
|
+
# @return [Discorb::Asset] The custom avatar of the member.
|
16
|
+
# @return [nil] If the member has no custom avatar.
|
17
|
+
attr_reader :custom_avatar
|
18
|
+
# @return [Discorb::Asset] The display avatar of the member.
|
19
|
+
attr_reader :display_avatar
|
20
|
+
# @return [Boolean] Whether the member is muted.
|
21
|
+
attr_reader :mute
|
22
|
+
alias mute? mute
|
23
|
+
# @return [Boolean] Whether the member is deafened.
|
24
|
+
attr_reader :deaf
|
25
|
+
alias deaf? deaf
|
26
|
+
# @return [Boolean] Whether the member is pending (Not passed member screening).
|
27
|
+
attr_reader :pending
|
28
|
+
alias pending? pending
|
29
|
+
|
30
|
+
# @!attribute [r] name
|
31
|
+
# @return [String] The display name of the member.
|
32
|
+
# @!attribute [r] mention
|
33
|
+
# @return [String] The mention of the member.
|
34
|
+
# @!attribute [r] voice_state
|
35
|
+
# @return [Discorb::VoiceState] The voice state of the member.
|
36
|
+
# @!attribute [r] roles
|
37
|
+
# @macro client_cache
|
38
|
+
# @return [Array<Discorb::Role>] The roles of the member.
|
39
|
+
# @!attribute [r] guild
|
40
|
+
# @macro client_cache
|
41
|
+
# @return [Discorb::Guild] The guild the member is in.
|
42
|
+
# @!attribute [r] hoisted_role
|
43
|
+
# @macro client_cache
|
44
|
+
# @return [Discorb::Role] The hoisted role of the member.
|
45
|
+
# @return [nil] If the member has no hoisted role.
|
46
|
+
# @!attribute [r] hoisted?
|
47
|
+
# @return [Boolean] Whether the member has a hoisted role.
|
48
|
+
# @!attribute [r] permissions
|
49
|
+
# @return [Discorb::Permission] The permissions of the member.
|
50
|
+
# @!attribute [r] presence
|
51
|
+
# @macro client_cache
|
52
|
+
# @return [Discorb::Presence] The presence of the member.
|
53
|
+
# @!attribute [r] activity
|
54
|
+
# @macro client_cache
|
55
|
+
# @return [Discorb::Activity] The activity of the member. It's from the {#presence}.
|
56
|
+
# @!attribute [r] activities
|
57
|
+
# @macro client_cache
|
58
|
+
# @return [Array<Discorb::Activity>] The activities of the member. It's from the {#presence}.
|
59
|
+
# @!attribute [r] status
|
60
|
+
# @macro client_cache
|
61
|
+
# @return [Symbol] The status of the member. It's from the {#presence}.
|
62
|
+
|
63
|
+
# @!visibility private
|
64
|
+
def initialize(client, guild_id, user_data, member_data)
|
65
|
+
@guild_id = guild_id
|
66
|
+
@client = client
|
67
|
+
@_member_data = {}
|
68
|
+
@data = {}
|
69
|
+
_set_data(user_data, member_data)
|
70
|
+
end
|
71
|
+
|
72
|
+
#
|
73
|
+
# Format the member to `@name` style.
|
74
|
+
#
|
75
|
+
# @return [String] The formatted member.
|
76
|
+
#
|
77
|
+
def to_s
|
78
|
+
"@#{name}"
|
79
|
+
end
|
80
|
+
|
81
|
+
def name
|
82
|
+
@nick || @username
|
83
|
+
end
|
84
|
+
|
85
|
+
def mention
|
86
|
+
"<@#{@nick.nil? ? "" : "!"}#{@id}>"
|
87
|
+
end
|
88
|
+
|
89
|
+
def voice_state
|
90
|
+
guild.voice_states[@id]
|
91
|
+
end
|
92
|
+
|
93
|
+
def guild
|
94
|
+
@client.guilds[@guild_id]
|
95
|
+
end
|
96
|
+
|
97
|
+
def roles
|
98
|
+
@role_ids.map { |r| guild.roles[r] }
|
99
|
+
end
|
100
|
+
|
101
|
+
def permissions
|
102
|
+
roles.map(&:permissions).sum(Permission.new(0))
|
103
|
+
end
|
104
|
+
|
105
|
+
def hoisted_role
|
106
|
+
@hoisted_role_id && guild.roles[@hoisted_role_id]
|
107
|
+
end
|
108
|
+
|
109
|
+
def hoisted?
|
110
|
+
!@hoisted_role_id.nil?
|
111
|
+
end
|
112
|
+
|
113
|
+
def presence
|
114
|
+
guild.presences[@id]
|
115
|
+
end
|
116
|
+
|
117
|
+
def activity
|
118
|
+
presence&.activity
|
119
|
+
end
|
120
|
+
|
121
|
+
def activities
|
122
|
+
presence&.activities
|
123
|
+
end
|
124
|
+
|
125
|
+
def status
|
126
|
+
presence&.status
|
127
|
+
end
|
128
|
+
|
129
|
+
def inspect
|
130
|
+
"#<#{self.class} #{self} id=#{@id}>"
|
131
|
+
end
|
132
|
+
|
133
|
+
#
|
134
|
+
# Add a role to the member.
|
135
|
+
# @macro http
|
136
|
+
# @macro async
|
137
|
+
#
|
138
|
+
# @param [Discorb::Role] role The role to add.
|
139
|
+
# @param [String] reason The reason for the action.
|
140
|
+
#
|
141
|
+
def add_role(role, reason: nil)
|
142
|
+
Async do
|
143
|
+
@client.internet.put("/guilds/#{@guild_id}/members/#{@id}/roles/#{role.is_a?(Role) ? role.id : role}", nil, audit_log_reason: reason).wait
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
#
|
148
|
+
# Remove a role to the member.
|
149
|
+
# @macro http
|
150
|
+
# @macro async
|
151
|
+
#
|
152
|
+
# @param [Discorb::Role] role The role to add.
|
153
|
+
# @param [String] reason The reason for the action.
|
154
|
+
#
|
155
|
+
def remove_role(role, reason: nil)
|
156
|
+
Async do
|
157
|
+
@client.internet.delete("/guilds/#{@guild_id}/members/#{@id}/roles/#{role.is_a?(Role) ? role.id : role}", audit_log_reason: reason).wait
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
#
|
162
|
+
# Edit the member.
|
163
|
+
# @macro http
|
164
|
+
# @macro async
|
165
|
+
# @macro edit
|
166
|
+
#
|
167
|
+
# @param [String] nick The nickname of the member.
|
168
|
+
# @param [Discorb::Role] role The roles of the member.
|
169
|
+
# @param [Boolean] mute Whether the member is muted.
|
170
|
+
# @param [Boolean] deaf Whether the member is deafened.
|
171
|
+
# @param [Discorb::StageChannel] channel The channel the member is moved to.
|
172
|
+
# @param [String] reason The reason for the action.
|
173
|
+
#
|
174
|
+
def edit(nick: :unset, role: :unset, mute: :unset, deaf: :unset, channel: :unset, reason: nil)
|
175
|
+
Async do
|
176
|
+
payload = {}
|
177
|
+
payload[:nick] = nick if nick != :unset
|
178
|
+
payload[:roles] = role if role != :unset
|
179
|
+
payload[:mute] = mute if mute != :unset
|
180
|
+
payload[:deaf] = deaf if deaf != :unset
|
181
|
+
payload[:channel_id] = channel&.id if channel != :unset
|
182
|
+
@client.internet.patch("/guilds/#{@guild_id}/members/#{@id}", payload, audit_log_reason: reason).wait
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
alias modify edit
|
187
|
+
|
188
|
+
#
|
189
|
+
# Kick the member.
|
190
|
+
#
|
191
|
+
# @param [String] reason The reason for the action.
|
192
|
+
#
|
193
|
+
def kick(reason: nil)
|
194
|
+
Async do
|
195
|
+
guild.kick_member(self, reason: reason).wait
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
#
|
200
|
+
# Ban the member.
|
201
|
+
#
|
202
|
+
# @param [Integer] delete_message_days The number of days to delete messages.
|
203
|
+
# @param [String] reason The reason for the action.
|
204
|
+
#
|
205
|
+
# @return [Discorb::Guild::Ban] The ban.
|
206
|
+
#
|
207
|
+
def ban(delete_message_days: 0, reason: nil)
|
208
|
+
Async do
|
209
|
+
guild.ban_member(self, delete_message_days: delete_message_days, reason: reason).wait
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
private
|
214
|
+
|
215
|
+
def _set_data(user_data, member_data)
|
216
|
+
user_data ||= member_data[:user]
|
217
|
+
@role_ids = member_data[:roles]
|
218
|
+
@premium_since = member_data[:premium_since] && Time.iso8601(member_data[:premium_since])
|
219
|
+
@pending = member_data[:pending]
|
220
|
+
@nick = member_data[:nick]
|
221
|
+
@mute = member_data[:mute]
|
222
|
+
@joined_at = member_data[:joined_at] && Time.iso8601(member_data[:joined_at])
|
223
|
+
@hoisted_role_id = member_data[:hoisted_role]
|
224
|
+
@deaf = member_data[:deaf]
|
225
|
+
@custom_avatar = member_data[:avatar] && Asset.new(member_data[:avatar])
|
226
|
+
@display_avatar = Asset.new(self, member_data[:avatar] || user_data[:avatar])
|
227
|
+
super(user_data)
|
228
|
+
@client.guilds[@guild_id].members[@id] = self unless @guild_id.nil?
|
229
|
+
@_member_data.update(member_data)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
@@ -0,0 +1,583 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Discorb
|
4
|
+
#
|
5
|
+
# Represents a allowed mentions in a message.
|
6
|
+
#
|
7
|
+
class AllowedMentions
|
8
|
+
# @return [Boolean] Whether to allow @everyone or @here.
|
9
|
+
attr_accessor :everyone
|
10
|
+
# @return [Boolean, Array<Discorb::Role>] The roles to allow, or false to disable.
|
11
|
+
attr_accessor :roles
|
12
|
+
# @return [Boolean, Array<Discorb::User>] The users to allow, or false to disable.
|
13
|
+
attr_accessor :users
|
14
|
+
# @return [Boolean] Whether to ping the user that sent the message to reply.
|
15
|
+
attr_accessor :replied_user
|
16
|
+
|
17
|
+
#
|
18
|
+
# Initializes a new instance of the AllowedMentions class.
|
19
|
+
#
|
20
|
+
# @param [Boolean] everyone Whether to allow @everyone or @here.
|
21
|
+
# @param [Boolean, Array<Discorb::Role>] roles The roles to allow, or false to disable.
|
22
|
+
# @param [Boolean, Array<Discorb::User>] users The users to allow, or false to disable.
|
23
|
+
# @param [Boolean] replied_user Whether to ping the user that sent the message to reply.
|
24
|
+
#
|
25
|
+
def initialize(everyone: nil, roles: nil, users: nil, replied_user: nil)
|
26
|
+
@everyone = everyone
|
27
|
+
@roles = roles
|
28
|
+
@users = users
|
29
|
+
@replied_user = replied_user
|
30
|
+
end
|
31
|
+
|
32
|
+
# @!visibility private
|
33
|
+
def to_hash(other = nil)
|
34
|
+
payload = {
|
35
|
+
parse: %w[everyone roles users],
|
36
|
+
}
|
37
|
+
replied_user = nil_merge(@replied_user, other&.replied_user)
|
38
|
+
everyone = nil_merge(@everyone, other&.everyone)
|
39
|
+
roles = nil_merge(@roles, other&.roles)
|
40
|
+
users = nil_merge(@users, other&.users)
|
41
|
+
payload[:replied_user] = replied_user
|
42
|
+
payload[:parse].delete("everyone") if everyone == false
|
43
|
+
if (roles == false) || roles.is_a?(Array)
|
44
|
+
payload[:roles] = roles.map { |u| u.id.to_s } if roles.is_a? Array
|
45
|
+
payload[:parse].delete("roles")
|
46
|
+
end
|
47
|
+
if (users == false) || users.is_a?(Array)
|
48
|
+
payload[:users] = users.map { |u| u.id.to_s } if users.is_a? Array
|
49
|
+
payload[:parse].delete("users")
|
50
|
+
end
|
51
|
+
payload
|
52
|
+
end
|
53
|
+
|
54
|
+
def nil_merge(*args)
|
55
|
+
args.each do |a|
|
56
|
+
return a unless a.nil?
|
57
|
+
end
|
58
|
+
nil
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# Represents a message.
|
64
|
+
#
|
65
|
+
class Message < DiscordModel
|
66
|
+
# @return [Discorb::Snowflake] The ID of the message.
|
67
|
+
attr_reader :id
|
68
|
+
# @return [Discorb::User, Discorb::Member] The user that sent the message.
|
69
|
+
attr_reader :author
|
70
|
+
# @return [String] The content of the message.
|
71
|
+
attr_reader :content
|
72
|
+
alias to_s content
|
73
|
+
# @return [Time] The time the message was created.
|
74
|
+
attr_reader :created_at
|
75
|
+
alias timestamp created_at
|
76
|
+
alias sent_at created_at
|
77
|
+
# @return [Time] The time the message was edited.
|
78
|
+
# @return [nil] If the message was not edited.
|
79
|
+
attr_reader :updated_at
|
80
|
+
alias edited_at updated_at
|
81
|
+
alias edited_timestamp updated_at
|
82
|
+
# @return [Array<Discorb::Attachment>] The attachments of the message.
|
83
|
+
attr_reader :attachments
|
84
|
+
# @return [Array<Discorb::Embed>] The embeds of the message.
|
85
|
+
attr_reader :embeds
|
86
|
+
# @return [Array<Discorb::Reaction>] The reactions of the message.
|
87
|
+
attr_reader :reactions
|
88
|
+
# @return [Discorb::Snowflake] The ID of the channel the message was sent in.
|
89
|
+
attr_reader :webhook_id
|
90
|
+
# @return [Symbol] The type of the message.
|
91
|
+
# Currently, this will be one of:
|
92
|
+
#
|
93
|
+
# * `:default`
|
94
|
+
# * `:recipient_add`
|
95
|
+
# * `:recipient_remove`
|
96
|
+
# * `:call`
|
97
|
+
# * `:channel_name_change`
|
98
|
+
# * `:channel_icon_change`
|
99
|
+
# * `:channel_pinned_message`
|
100
|
+
# * `:guild_member_join`
|
101
|
+
# * `:user_premium_guild_subscription`
|
102
|
+
# * `:user_premium_guild_subscription_tier_1`
|
103
|
+
# * `:user_premium_guild_subscription_tier_2`
|
104
|
+
# * `:user_premium_guild_subscription_tier_3`
|
105
|
+
# * `:channel_follow_add`
|
106
|
+
# * `:guild_discovery_disqualified`
|
107
|
+
# * `:guild_discovery_requalified`
|
108
|
+
# * `:guild_discovery_grace_period_initial_warning`
|
109
|
+
# * `:guild_discovery_grace_period_final_warning`
|
110
|
+
# * `:thread_created`
|
111
|
+
# * `:reply`
|
112
|
+
# * `:application_command`
|
113
|
+
# * `:thread_starter_message`
|
114
|
+
# * `:guild_invite_reminder`
|
115
|
+
attr_reader :type
|
116
|
+
# @return [Discorb::Message::Activity] The activity of the message.
|
117
|
+
attr_reader :activity
|
118
|
+
# @return [Discorb::Application] The application of the message.
|
119
|
+
attr_reader :application_id
|
120
|
+
# @return [Discorb::Message::Reference] The reference of the message.
|
121
|
+
attr_reader :message_reference
|
122
|
+
# @return [Discorb::Message::Flag] The flag of the message.
|
123
|
+
# @see Discorb::Message::Flag
|
124
|
+
attr_reader :flag
|
125
|
+
# @return [Discorb::Message::Sticker] The sticker of the message.
|
126
|
+
attr_reader :stickers
|
127
|
+
# @return [Discorb::Message::Interaction] The interaction of the message.
|
128
|
+
attr_reader :interaction
|
129
|
+
# @return [Discorb::ThreadChannel] The thread channel of the message.
|
130
|
+
attr_reader :thread
|
131
|
+
# @return [Array<Array<Discorb::Components>>] The components of the message.
|
132
|
+
attr_reader :components
|
133
|
+
# @return [Boolean] Whether the message is deleted.
|
134
|
+
attr_reader :deleted
|
135
|
+
alias deleted? deleted
|
136
|
+
# @return [Boolean] Whether the message is tts.
|
137
|
+
attr_reader :tts
|
138
|
+
alias tts? tts
|
139
|
+
# @return [Boolean] Whether the message mentions everyone.
|
140
|
+
attr_reader :mention_everyone
|
141
|
+
alias mention_everyone? mention_everyone
|
142
|
+
# @return [Boolean] Whether the message is pinned.
|
143
|
+
attr_reader :pinned
|
144
|
+
alias pinned? pinned
|
145
|
+
@message_type = {
|
146
|
+
default: 0,
|
147
|
+
recipient_add: 1,
|
148
|
+
recipient_remove: 2,
|
149
|
+
call: 3,
|
150
|
+
channel_name_change: 4,
|
151
|
+
channel_icon_change: 5,
|
152
|
+
channel_pinned_message: 6,
|
153
|
+
guild_member_join: 7,
|
154
|
+
user_premium_guild_subscription: 8,
|
155
|
+
user_premium_guild_subscription_tier_1: 9,
|
156
|
+
user_premium_guild_subscription_tier_2: 10,
|
157
|
+
user_premium_guild_subscription_tier_3: 11,
|
158
|
+
channel_follow_add: 12,
|
159
|
+
guild_discovery_disqualified: 14,
|
160
|
+
guild_discovery_requalified: 15,
|
161
|
+
guild_discovery_grace_period_initial_warning: 16,
|
162
|
+
guild_discovery_grace_period_final_warning: 17,
|
163
|
+
thread_created: 18,
|
164
|
+
reply: 19,
|
165
|
+
application_command: 20,
|
166
|
+
thread_starter_message: 21,
|
167
|
+
guild_invite_reminder: 22,
|
168
|
+
}.freeze
|
169
|
+
|
170
|
+
# @!attribute [r] channel
|
171
|
+
# @macro client_cache
|
172
|
+
# @return [Discorb::Channel] The channel the message was sent in.
|
173
|
+
# @!attribute [r] guild
|
174
|
+
# @macro client_cache
|
175
|
+
# @return [Discorb::Guild] The guild the message was sent in.
|
176
|
+
# @return [nil] If the message was not sent in a guild.
|
177
|
+
# @!attribute [r] webhook?
|
178
|
+
# @return [Boolean] Whether the message was sent by a webhook.
|
179
|
+
# @!attribute [r] edited?
|
180
|
+
# @return [Boolean] Whether the message was edited.
|
181
|
+
# @!attribute [r] jump_url
|
182
|
+
# @return [String] The URL to jump to the message.
|
183
|
+
# @!attribute [r] embed
|
184
|
+
# @return [Discorb::Embed] The embed of the message.
|
185
|
+
# @return [nil] If the message has no embed.
|
186
|
+
|
187
|
+
# @!visibility private
|
188
|
+
def initialize(client, data, no_cache: false)
|
189
|
+
@client = client
|
190
|
+
@data = {}
|
191
|
+
@no_cache = no_cache
|
192
|
+
_set_data(data)
|
193
|
+
@client.messages[@id] = self unless @no_cache
|
194
|
+
end
|
195
|
+
|
196
|
+
def channel
|
197
|
+
@dm || @client.channels[@channel_id]
|
198
|
+
end
|
199
|
+
|
200
|
+
def guild
|
201
|
+
@client.guilds[@guild_id]
|
202
|
+
end
|
203
|
+
|
204
|
+
def webhook?
|
205
|
+
@webhook_id != nil
|
206
|
+
end
|
207
|
+
|
208
|
+
def jump_url
|
209
|
+
"https://discord.com/channels/#{@guild_id || "@me"}/#{@channel_id}/#{@id}"
|
210
|
+
end
|
211
|
+
|
212
|
+
def edited?
|
213
|
+
!@updated_at.nil?
|
214
|
+
end
|
215
|
+
|
216
|
+
#
|
217
|
+
# Convert the message to reference object.
|
218
|
+
#
|
219
|
+
# @param [Boolean] fail_if_not_exists Whether to raise an error if the message does not exist.
|
220
|
+
#
|
221
|
+
# @return [Hash] The reference object.
|
222
|
+
#
|
223
|
+
def to_reference(fail_if_not_exists: true)
|
224
|
+
{
|
225
|
+
message_id: @id,
|
226
|
+
channel_id: @channel_id,
|
227
|
+
guild_id: @guild_id,
|
228
|
+
fail_if_not_exists: fail_if_not_exists,
|
229
|
+
}
|
230
|
+
end
|
231
|
+
|
232
|
+
def embed
|
233
|
+
@embeds[0]
|
234
|
+
end
|
235
|
+
|
236
|
+
# Reply to the message.
|
237
|
+
# @macro async
|
238
|
+
# @macro http
|
239
|
+
# @param (see #post)
|
240
|
+
# @return [Discorb::Message] The message.
|
241
|
+
def reply(*args, **kwargs)
|
242
|
+
Async do |_task|
|
243
|
+
channel.post(*args, reference: self, **kwargs).wait
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
#
|
248
|
+
# Publish the message.
|
249
|
+
# @macro async
|
250
|
+
# @macro http
|
251
|
+
#
|
252
|
+
def publish
|
253
|
+
Async do |_task|
|
254
|
+
channel.post("/channels/#{@channel_id}/messages/#{@id}/crosspost", nil).wait
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
#
|
259
|
+
# Add a reaction to the message.
|
260
|
+
# @macro async
|
261
|
+
# @macro http
|
262
|
+
#
|
263
|
+
# @param [Discorb::Emoji] emoji The emoji to react with.
|
264
|
+
#
|
265
|
+
def add_reaction(emoji)
|
266
|
+
Async do |_task|
|
267
|
+
@client.internet.put("/channels/#{@channel_id}/messages/#{@id}/reactions/#{emoji.to_uri}/@me", nil).wait
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
alias react_with add_reaction
|
272
|
+
|
273
|
+
#
|
274
|
+
# Remove a reaction from the message.
|
275
|
+
# @macro async
|
276
|
+
# @macro http
|
277
|
+
#
|
278
|
+
# @param [Discorb::Emoji] emoji The emoji to remove.
|
279
|
+
#
|
280
|
+
def remove_reaction(emoji)
|
281
|
+
Async do |_task|
|
282
|
+
@client.internet.delete("/channels/#{@channel_id}/messages/#{@id}/reactions/#{emoji.to_uri}/@me").wait
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
alias delete_reaction remove_reaction
|
287
|
+
|
288
|
+
#
|
289
|
+
# Remove other member's reaction from the message.
|
290
|
+
# @macro async
|
291
|
+
# @macro http
|
292
|
+
#
|
293
|
+
# @param [Discorb::Emoji] emoji The emoji to remove.
|
294
|
+
# @param [Discorb::Member] member The member to remove the reaction from.
|
295
|
+
#
|
296
|
+
def remove_reaction_of(emoji, member)
|
297
|
+
Async do |_task|
|
298
|
+
@client.internet.delete("/channels/#{@channel_id}/messages/#{@id}/reactions/#{emoji.to_uri}/#{member.is_a?(Member) ? member.id : member}").wait
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
alias delete_reaction_of remove_reaction_of
|
303
|
+
|
304
|
+
#
|
305
|
+
# Fetch reacted users of reaction.
|
306
|
+
# @macro async
|
307
|
+
# @macro http
|
308
|
+
#
|
309
|
+
# @param [Discorb::Emoji] emoji The emoji to fetch.
|
310
|
+
# @param [Integer, nil] limit The maximum number of users to fetch. `nil` for no limit.
|
311
|
+
# @param [Discorb::Snowflake, nil] after The ID of the user to start fetching from.
|
312
|
+
#
|
313
|
+
# @return [Array<Discorb::User>] The users.
|
314
|
+
#
|
315
|
+
def fetch_reacted_users(emoji, limit: nil, after: 0)
|
316
|
+
Async do |_task|
|
317
|
+
if limit.nil? || !limit.positive?
|
318
|
+
after = 0
|
319
|
+
users = []
|
320
|
+
loop do
|
321
|
+
_resp, data = @client.internet.get("/channels/#{@channel_id}/messages/#{@id}/reactions/#{emoji.to_uri}?limit=100&after=#{after}").wait
|
322
|
+
break if data.empty?
|
323
|
+
|
324
|
+
users += data.map { |r| guild&.members&.[](r[:id]) || @client.users[r[:id]] || User.new(@client, r) }
|
325
|
+
|
326
|
+
break if data.length < 100
|
327
|
+
|
328
|
+
after = data[-1][:id]
|
329
|
+
end
|
330
|
+
next users
|
331
|
+
else
|
332
|
+
_resp, data = @client.internet.get("/channels/#{@channel_id}/messages/#{@id}/reactions/#{emoji.to_uri}?limit=#{limit}&after=#{after}").wait
|
333
|
+
next data.map { |r| guild&.members&.[](r[:id]) || @client.users[r[:id]] || User.new(@client, r) }
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
#
|
339
|
+
# Pin the message.
|
340
|
+
# @macro async
|
341
|
+
# @macro http
|
342
|
+
#
|
343
|
+
# @param [String] reason The reason for pinning the message.
|
344
|
+
#
|
345
|
+
def pin(reason: nil)
|
346
|
+
Async do
|
347
|
+
channel.pin_message(self, reason: reason).wait
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
#
|
352
|
+
# Unpin the message.
|
353
|
+
# @macro async
|
354
|
+
# @macro http
|
355
|
+
#
|
356
|
+
def unpin
|
357
|
+
Async do
|
358
|
+
channel.unpin_message(self, reason: reason).wait
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
#
|
363
|
+
# Start thread from the message.
|
364
|
+
#
|
365
|
+
# @param (see Discorb::Channel#start_thread)
|
366
|
+
#
|
367
|
+
# @return [<Type>] <description>
|
368
|
+
#
|
369
|
+
def start_thread(*args, **kwargs)
|
370
|
+
Async do
|
371
|
+
channel.start_thread(*args, message: self, **kwargs).wait
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
alias create_thread start_thread
|
376
|
+
|
377
|
+
# Meta
|
378
|
+
|
379
|
+
def inspect
|
380
|
+
"#<#{self.class} #{@content.inspect} id=#{@id}>"
|
381
|
+
end
|
382
|
+
|
383
|
+
#
|
384
|
+
# Represents message flag.
|
385
|
+
# ## Flag fields
|
386
|
+
# |Field|Value|
|
387
|
+
# |-|-|
|
388
|
+
# |`1 << 0`|`:crossposted`|
|
389
|
+
# |`1 << 1`|`:crosspost`|
|
390
|
+
# |`1 << 2`|`:supress_embeds`|
|
391
|
+
# |`1 << 3`|`:source_message_deleted`|
|
392
|
+
# |`1 << 4`|`:urgent`|
|
393
|
+
# |`1 << 5`|`:has_thread`|
|
394
|
+
# |`1 << 6`|`:ephemeral`|
|
395
|
+
# |`1 << 7`|`:loading`|
|
396
|
+
#
|
397
|
+
class Flag < Discorb::Flag
|
398
|
+
@bits = {
|
399
|
+
crossposted: 0,
|
400
|
+
crosspost: 1,
|
401
|
+
supress_embeds: 2,
|
402
|
+
source_message_deleted: 3,
|
403
|
+
urgent: 4,
|
404
|
+
has_thread: 5,
|
405
|
+
ephemeral: 6,
|
406
|
+
loading: 7,
|
407
|
+
}.freeze
|
408
|
+
end
|
409
|
+
|
410
|
+
#
|
411
|
+
# Represents reference of message.
|
412
|
+
#
|
413
|
+
class Reference
|
414
|
+
# @return [Discorb::Snowflake] The guild ID.
|
415
|
+
attr_accessor :guild_id
|
416
|
+
# @return [Discorb::Snowflake] The channel ID.
|
417
|
+
attr_accessor :channel_id
|
418
|
+
# @return [Discorb::Snowflake] The message ID.
|
419
|
+
attr_accessor :message_id
|
420
|
+
# @return [Boolean] Whether fail the request if the message is not found.
|
421
|
+
attr_accessor :fail_if_not_exists
|
422
|
+
|
423
|
+
alias fail_if_not_exists? fail_if_not_exists
|
424
|
+
|
425
|
+
#
|
426
|
+
# Initialize a new reference.
|
427
|
+
#
|
428
|
+
# @param [Discorb::Snowflake] guild_id The guild ID.
|
429
|
+
# @param [Discorb::Snowflake] channel_id The channel ID.
|
430
|
+
# @param [Discorb::Snowflake] message_id The message ID.
|
431
|
+
# @param [Boolean] fail_if_not_exists Whether fail the request if the message is not found.
|
432
|
+
#
|
433
|
+
def initialize(guild_id, channel_id, message_id, fail_if_not_exists: true)
|
434
|
+
@guild_id = guild_id
|
435
|
+
@channel_id = channel_id
|
436
|
+
@message_id = message_id
|
437
|
+
@fail_if_not_exists = fail_if_not_exists
|
438
|
+
end
|
439
|
+
|
440
|
+
#
|
441
|
+
# Convert the reference to a hash.
|
442
|
+
#
|
443
|
+
# @return [Hash] The hash.
|
444
|
+
#
|
445
|
+
def to_hash
|
446
|
+
{
|
447
|
+
message_id: @message_id,
|
448
|
+
channel_id: @channel_id,
|
449
|
+
guild_id: @guild_id,
|
450
|
+
fail_if_not_exists: @fail_if_not_exists,
|
451
|
+
}
|
452
|
+
end
|
453
|
+
|
454
|
+
alias to_reference to_hash
|
455
|
+
|
456
|
+
#
|
457
|
+
# Initialize a new reference from a hash.
|
458
|
+
#
|
459
|
+
# @param [Hash] data The hash.
|
460
|
+
#
|
461
|
+
# @return [Discorb::Message::Reference] The reference.
|
462
|
+
# @see https://discord.com/developers/docs/resources/channel#message-reference-object
|
463
|
+
#
|
464
|
+
def self.from_hash(data)
|
465
|
+
new(data[:guild_id], data[:channel_id], data[:message_id], fail_if_not_exists: data[:fail_if_not_exists])
|
466
|
+
end
|
467
|
+
end
|
468
|
+
|
469
|
+
class Sticker
|
470
|
+
attr_reader :id, :name, :format
|
471
|
+
|
472
|
+
def initialize(data)
|
473
|
+
@id = Snowflake.new(data[:id])
|
474
|
+
@name = data[:name]
|
475
|
+
@format = Discorb::Sticker.sticker_format[data[:format]]
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
private
|
480
|
+
|
481
|
+
def _set_data(data)
|
482
|
+
@id = Snowflake.new(data[:id])
|
483
|
+
@channel_id = data[:channel_id]
|
484
|
+
|
485
|
+
if data[:guild_id]
|
486
|
+
@guild_id = data[:guild_id]
|
487
|
+
@dm = nil
|
488
|
+
else
|
489
|
+
@dm = Discorb::DMChannel.new(@client, data[:channel_id])
|
490
|
+
@guild_id = nil
|
491
|
+
end
|
492
|
+
|
493
|
+
if data[:author].nil? && data[:webhook_id]
|
494
|
+
@webhook_id = Snowflake.new(data[:webhook_id])
|
495
|
+
# @author = WebhookAuthor.new(data[:webhook_id])
|
496
|
+
elsif data[:guild_id].nil? || data[:guild_id].empty?
|
497
|
+
@author = @client.users[data[:author][:id]] || User.new(@client, data[:author])
|
498
|
+
else
|
499
|
+
@author = guild.members[data[:author][:id]] || Member.new(@client,
|
500
|
+
@guild_id, data[:author], data[:member])
|
501
|
+
end
|
502
|
+
@content = data[:content]
|
503
|
+
@created_at = Time.iso8601(data[:timestamp])
|
504
|
+
@updated_at = data[:edited_timestamp].nil? ? nil : Time.iso8601(data[:edited_timestamp])
|
505
|
+
|
506
|
+
@tts = data[:tts]
|
507
|
+
@mention_everyone = data[:mention_everyone]
|
508
|
+
@mention_roles = data[:mention_roles].map { |r| guild.roles[r] }
|
509
|
+
@attachments = data[:attachments].map { |a| Attachment.new(a) }
|
510
|
+
@embeds = data[:embeds] ? data[:embeds].map { |e| Embed.new(data: e) } : []
|
511
|
+
@reactions = data[:reactions] ? data[:reactions].map { |r| Reaction.new(self, r) } : []
|
512
|
+
@pinned = data[:pinned]
|
513
|
+
@type = self.class.message_type[data[:type]]
|
514
|
+
@activity = data[:activity] && Activity.new(data[:activity])
|
515
|
+
@application_id = data[:application_id]
|
516
|
+
@message_reference = data[:message_reference] && Reference.from_hash(data[:message_reference])
|
517
|
+
@flag = Flag.new(0b111 - data[:flags])
|
518
|
+
@sticker_items = data[:sticker_items] ? data[:sticker_items].map { |s| Message::Sticker.new(s) } : []
|
519
|
+
# @referenced_message = data[:referenced_message] && Message.new(@client, data[:referenced_message])
|
520
|
+
@interaction = data[:interaction] && Message::Interaction.new(@client, data[:interaction])
|
521
|
+
@thread = data[:thread] && Channel.make_channel(@client, data[:thread])
|
522
|
+
@components = data[:components].map { |c| c[:components].map { |co| Component.from_hash(co) } }
|
523
|
+
@data.update(data)
|
524
|
+
@deleted = false
|
525
|
+
end
|
526
|
+
|
527
|
+
#
|
528
|
+
# Represents a interaction of message.
|
529
|
+
#
|
530
|
+
class Interaction < DiscordModel
|
531
|
+
# @return [Discorb::Snowflake] The user ID.
|
532
|
+
attr_reader :id
|
533
|
+
# @return [String] The name of command.
|
534
|
+
# @return [nil] If the message is not a command.
|
535
|
+
attr_reader :name
|
536
|
+
# @return [Class] The type of interaction.
|
537
|
+
attr_reader :type
|
538
|
+
# @return [Discorb::User] The user.
|
539
|
+
attr_reader :user
|
540
|
+
|
541
|
+
# @!visibility private
|
542
|
+
def initialize(client, data)
|
543
|
+
@id = Snowflake.new(data[:id])
|
544
|
+
@name = data[:name]
|
545
|
+
@type = Discorb::Interaction.descendants.find { |c| c.interaction_type == data[:type] }
|
546
|
+
@user = client.users[data[:user][:id]] || User.new(client, data[:user])
|
547
|
+
end
|
548
|
+
end
|
549
|
+
|
550
|
+
#
|
551
|
+
# Represents a activity of message.
|
552
|
+
#
|
553
|
+
class Activity < DiscordModel
|
554
|
+
# @return [String] The name of activity.
|
555
|
+
attr_reader :name
|
556
|
+
# @return [Symbol] The type of activity.
|
557
|
+
attr_reader :type
|
558
|
+
|
559
|
+
@type = {
|
560
|
+
1 => :join,
|
561
|
+
2 => :spectate,
|
562
|
+
3 => :listen,
|
563
|
+
5 => :join_request,
|
564
|
+
}
|
565
|
+
|
566
|
+
# @!visibility private
|
567
|
+
def initialize(data)
|
568
|
+
@name = data[:name]
|
569
|
+
@type = self.class.type(data[:type])
|
570
|
+
end
|
571
|
+
|
572
|
+
class << self
|
573
|
+
# @!visibility private
|
574
|
+
attr_reader :type
|
575
|
+
end
|
576
|
+
end
|
577
|
+
|
578
|
+
class << self
|
579
|
+
# @!visibility private
|
580
|
+
attr_reader :message_type
|
581
|
+
end
|
582
|
+
end
|
583
|
+
end
|