rubord 0.1.3

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.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +39 -0
  4. data/lib/rubord/components/actionRow.rb +93 -0
  5. data/lib/rubord/components/button.rb +125 -0
  6. data/lib/rubord/components/componentsV2.rb +4 -0
  7. data/lib/rubord/components/containers/base.rb +15 -0
  8. data/lib/rubord/components/containers/container.rb +39 -0
  9. data/lib/rubord/components/containers/section.rb +26 -0
  10. data/lib/rubord/components/containers/separator.rb +51 -0
  11. data/lib/rubord/components/containers/text.rb +23 -0
  12. data/lib/rubord/components/modal.rb +134 -0
  13. data/lib/rubord/components/select_menu.rb +147 -0
  14. data/lib/rubord/models/channel.rb +50 -0
  15. data/lib/rubord/models/collection.rb +70 -0
  16. data/lib/rubord/models/commands/base.rb +111 -0
  17. data/lib/rubord/models/commands/command.rb +3 -0
  18. data/lib/rubord/models/commands/loader.rb +36 -0
  19. data/lib/rubord/models/commands/registry.rb +26 -0
  20. data/lib/rubord/models/components.rb +5 -0
  21. data/lib/rubord/models/embed.rb +87 -0
  22. data/lib/rubord/models/flags.rb +249 -0
  23. data/lib/rubord/models/guild.rb +78 -0
  24. data/lib/rubord/models/interaction.rb +136 -0
  25. data/lib/rubord/models/member.rb +63 -0
  26. data/lib/rubord/models/mention.rb +47 -0
  27. data/lib/rubord/models/message.rb +88 -0
  28. data/lib/rubord/models/role.rb +15 -0
  29. data/lib/rubord/models/user.rb +21 -0
  30. data/lib/rubord/structs/client.rb +364 -0
  31. data/lib/rubord/structs/gateway.rb +363 -0
  32. data/lib/rubord/structs/logger.rb +19 -0
  33. data/lib/rubord/structs/models.rb +19 -0
  34. data/lib/rubord/structs/parser.rb +68 -0
  35. data/lib/rubord/structs/rate_limiter.rb +163 -0
  36. data/lib/rubord/structs/rest.rb +353 -0
  37. data/lib/rubord.rb +8 -0
  38. metadata +105 -0
@@ -0,0 +1,249 @@
1
+ module Rubord
2
+ module Permissions
3
+ FLAGS = {
4
+ create_instant_invite: 1 << 0,
5
+ kick_members: 1 << 1,
6
+ ban_members: 1 << 2,
7
+ administrator: 1 << 3,
8
+ manage_channels: 1 << 4,
9
+ manage_guild: 1 << 5,
10
+ add_reactions: 1 << 6,
11
+ view_audit_log: 1 << 7,
12
+ priority_speaker: 1 << 8,
13
+ stream: 1 << 9,
14
+ view_channel: 1 << 10,
15
+ send_messages: 1 << 11,
16
+ send_tts_messages: 1 << 12,
17
+ manage_messages: 1 << 13,
18
+ embed_links: 1 << 14,
19
+ attach_files: 1 << 15,
20
+ read_message_history: 1 << 16,
21
+ mention_everyone: 1 << 17,
22
+ use_external_emojis: 1 << 18,
23
+ view_guild_insights: 1 << 19,
24
+ connect: 1 << 20,
25
+ speak: 1 << 21,
26
+ mute_members: 1 << 22,
27
+ deafen_members: 1 << 23,
28
+ move_members: 1 << 24,
29
+ use_vad: 1 << 25,
30
+ change_nickname: 1 << 26,
31
+ manage_nicknames: 1 << 27,
32
+ manage_roles: 1 << 28,
33
+ manage_webhooks: 1 << 29,
34
+ manage_emojis_and_stickers: 1 << 30,
35
+ use_application_commands: 1 << 31,
36
+ manage_events: 1 << 32,
37
+ moderate_members: 1 << 40,
38
+ }.freeze
39
+
40
+ ALL = FLAGS.values.reduce(0, :|)
41
+
42
+ def self.combine(*perms)
43
+ perms.map { |p| FLAGS[p] }.compact.reduce(0, :|)
44
+ end
45
+ end
46
+
47
+ module Intents
48
+ FLAGS = {
49
+ guilds: 1 << 0,
50
+ guild_members: 1 << 1,
51
+ guild_bans: 1 << 2,
52
+ guild_emojis: 1 << 3,
53
+ guild_integrations: 1 << 4,
54
+ guild_webhooks: 1 << 5,
55
+ guild_invites: 1 << 6,
56
+ guild_voice_states: 1 << 7,
57
+ guild_presences: 1 << 8,
58
+ guild_messages: 1 << 9,
59
+ guild_message_reactions: 1 << 10,
60
+ guild_message_typing: 1 << 11,
61
+ direct_messages: 1 << 12,
62
+ direct_message_reactions: 1 << 13,
63
+ direct_message_typing: 1 << 14,
64
+ message_content: 1 << 15,
65
+ guild_scheduled_events: 1 << 16,
66
+ auto_moderation_configuration: 1 << 20,
67
+ auto_moderation_execution: 1 << 21,
68
+ }.freeze
69
+
70
+ class << self
71
+ def [](intent_name)
72
+ FLAGS[intent_name.to_sym] if intent_name
73
+ end
74
+
75
+ def all = FLAGS.values.reduce(0, :|)
76
+
77
+ def exists?(intent_name)
78
+ FLAGS.key?(intent_name.to_sym)
79
+ end
80
+
81
+ def names
82
+ FLAGS.keys
83
+ end
84
+
85
+ def values
86
+ FLAGS.values
87
+ end
88
+
89
+ def combine(*intents)
90
+ intents.flatten.reduce(0) do |sum, intent|
91
+ case intent
92
+ when Integer
93
+ sum | intent
94
+ when Symbol, String
95
+ value = FLAGS[intent.to_sym]
96
+ unless value
97
+ Rubord::Logger.warn "[Rubord:Intents] Unknown intent: #{intent.inspect}"
98
+ next sum
99
+ end
100
+ sum | value
101
+ else
102
+ Rubord::Logger.warn "[Rubord:Intents] Invalid intent type: #{intent.class}"
103
+ sum
104
+ end
105
+ end
106
+ end
107
+
108
+ def guilds
109
+ FLAGS[:guilds]
110
+ end
111
+
112
+ def guild_members
113
+ FLAGS[:guild_members]
114
+ end
115
+
116
+ def guild_bans
117
+ FLAGS[:guild_bans]
118
+ end
119
+
120
+ def guild_emojis
121
+ FLAGS[:guild_emojis]
122
+ end
123
+
124
+ def guild_integrations
125
+ FLAGS[:guild_integrations]
126
+ end
127
+
128
+ def guild_webhooks
129
+ FLAGS[:guild_webhooks]
130
+ end
131
+
132
+ def guild_invites
133
+ FLAGS[:guild_invites]
134
+ end
135
+
136
+ def guild_voice_states
137
+ FLAGS[:guild_voice_states]
138
+ end
139
+
140
+ def guild_presences
141
+ FLAGS[:guild_presences]
142
+ end
143
+
144
+ def guild_messages
145
+ FLAGS[:guild_messages]
146
+ end
147
+
148
+ def guild_message_reactions
149
+ FLAGS[:guild_message_reactions]
150
+ end
151
+
152
+ def guild_message_typing
153
+ FLAGS[:guild_message_typing]
154
+ end
155
+
156
+ def direct_messages
157
+ FLAGS[:direct_messages]
158
+ end
159
+
160
+ def direct_message_reactions
161
+ FLAGS[:direct_message_reactions]
162
+ end
163
+
164
+ def direct_message_typing
165
+ FLAGS[:direct_message_typing]
166
+ end
167
+
168
+ def message_content
169
+ FLAGS[:message_content]
170
+ end
171
+
172
+ def guild_scheduled_events
173
+ FLAGS[:guild_scheduled_events]
174
+ end
175
+
176
+ def auto_moderation_configuration
177
+ FLAGS[:auto_moderation_configuration]
178
+ end
179
+
180
+ def auto_moderation_execution
181
+ FLAGS[:auto_moderation_execution]
182
+ end
183
+
184
+ def default
185
+ combine(
186
+ :guilds,
187
+ :guild_members,
188
+ :guild_messages,
189
+ :guild_message_reactions,
190
+ :direct_messages,
191
+ :direct_message_reactions
192
+ )
193
+ end
194
+
195
+ def privileged
196
+ combine(
197
+ :guild_members,
198
+ :guild_presences,
199
+ :message_content
200
+ )
201
+ end
202
+
203
+ def include?(intent_value, intent_name)
204
+ intent_value & self[intent_name] != 0
205
+ end
206
+
207
+ def method_missing(name, *args)
208
+ if FLAGS.key?(name)
209
+ FLAGS[name]
210
+ elsif name.to_s.end_with?("?") && FLAGS.key?(name.to_s[0...-1].to_sym)
211
+ intent_name = name.to_s[0...-1].to_sym
212
+ if args.first.is_a?(Integer)
213
+ args.first & FLAGS[intent_name] != 0
214
+ else
215
+ super
216
+ end
217
+ else
218
+ super
219
+ end
220
+ end
221
+
222
+ def respond_to_missing?(name, include_private = false)
223
+ FLAGS.key?(name) ||
224
+ (name.to_s.end_with?("?") && FLAGS.key?(name.to_s[0...-1].to_sym)) ||
225
+ super
226
+ end
227
+ end
228
+ end
229
+
230
+ module MessageFlags
231
+ FLAGS = {
232
+ crossposted: 1 << 0,
233
+ is_crosspost: 1 << 1,
234
+ suppress_embeds: 1 << 2,
235
+ source_message_deleted: 1 << 3,
236
+ urgent: 1 << 4,
237
+ ephemeral: 1 << 6,
238
+ loading: 1 << 7,
239
+ components_v2: 1 << 15,
240
+ }.freeze
241
+
242
+ def self.combine(*flags)
243
+ flags.map { |f| FLAGS[f] }.compact.reduce(0, :|)
244
+ end
245
+
246
+ EPHEMERAL = FLAGS[:ephemeral]
247
+ COMPONENTS_V2 = FLAGS[:components_v2]
248
+ end
249
+ end
@@ -0,0 +1,78 @@
1
+ module Rubord
2
+ class Guild
3
+ attr_reader :id,
4
+ :members,
5
+ :roles,
6
+ :client
7
+
8
+ def initialize(data, client)
9
+ @client = client
10
+ @id = data["id"]
11
+ @members = Rubord::Collection.new
12
+ @roles = Rubord::Collection.new
13
+ @owner = data["owner"] || false
14
+ @owner_id = data["owner_id"]
15
+
16
+ client.guilds.set(@id, self)
17
+ load_roles(data["roles"]) if data["roles"]
18
+ end
19
+
20
+ def is_owner?(user_id)
21
+ @owner_id.to_i == user_id.to_i
22
+ end
23
+
24
+ def owner_id
25
+ @owner_id
26
+ end
27
+
28
+ def fetch_owner
29
+ return nil unless @owner_id
30
+ @client.users.get(@owner_id) ||
31
+ begin
32
+ data = @client.rest.get_user(@owner_id)
33
+ user = Rubord::User.new(data)
34
+ @client.users.set(user.id, user)
35
+ user
36
+ rescue Rubord::HTTPError
37
+ nil
38
+ end
39
+ end
40
+
41
+ def members_count
42
+ @members.size
43
+ end
44
+
45
+ def load_roles(raw_roles)
46
+ raw_roles.each do |role_data|
47
+ role = Rubord::Role.new(role_data)
48
+ @roles.set(role.id, role)
49
+ end
50
+ end
51
+
52
+ def add_member(data)
53
+ member = Rubord::Member.new(
54
+ data.merge("guild_id" => @id),
55
+ @client
56
+ )
57
+
58
+ @members.set(member.id, member)
59
+ member
60
+ end
61
+
62
+ def fetch_member(user_id)
63
+ cached = @members.get(user_id)
64
+ return cached if cached
65
+
66
+ data = @client.rest.get_guild_member(@id, user_id)
67
+ return nil unless data
68
+
69
+ add_member(data)
70
+ rescue Rubord::HTTPError
71
+ nil
72
+ end
73
+
74
+ def inspect
75
+ "#<Rubord::Guild id=#{@id} members=#{@members.size} roles=#{@roles.size}>"
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,136 @@
1
+ module Rubord
2
+ class Interaction
3
+ TYPES = {
4
+ ping: 1,
5
+ application_command: 2,
6
+ message_component: 3,
7
+ modal_submit: 5
8
+ }
9
+
10
+ COMPONENT_TYPES = {
11
+ button: 2,
12
+ select_menu: 3
13
+ }
14
+
15
+ attr_reader :id,
16
+ :application_id,
17
+ :type,
18
+ :data,
19
+ :guild_id,
20
+ :channel_id,
21
+ :member,
22
+ :user,
23
+ :token,
24
+ :version,
25
+ :message,
26
+ :client
27
+
28
+ def initialize(data, client)
29
+ @client = client
30
+ @id = data["id"]
31
+ @application_id = data["application_id"]
32
+ @type = data["type"]
33
+ @data = data["data"] || {}
34
+ @guild_id = data["guild_id"]
35
+ @channel_id = data["channel_id"]
36
+ @token = data["token"]
37
+ @version = data["version"]
38
+ @message = if data["message"]
39
+ Rubord::Message.new(data["message"], client)
40
+ end
41
+
42
+ member_data = data["member"]
43
+ member_data["guild_id"] = data["guild_id"]
44
+ @member = Rubord::Member.new(member_data, client)
45
+ end
46
+
47
+ def post(content = nil, embeds: nil, components: nil, flags: nil)
48
+ data = {}
49
+ data[:content] = content if content
50
+ data[:embeds] = Array(embeds).map(&:to_h) if embeds
51
+ data[:components] = Array(components).map(&:to_h) if components
52
+ data[:flags] = flags
53
+
54
+ client.rest.interactions_response(
55
+ @id,
56
+ @token,
57
+ type: 4,
58
+ data: data
59
+ )
60
+ end
61
+
62
+ def edit(content = nil, embeds: nil, components: nil, flags: nil)
63
+ client.rest.interaction_edit(
64
+ @application_id,
65
+ @token,
66
+ content: content,
67
+ embeds: embeds,
68
+ components: components,
69
+ flags: ephemeral ? 64 : nil
70
+ )
71
+ end
72
+
73
+ def defer(flags: nil)
74
+ data = {}
75
+ data[:flags] = flags
76
+
77
+ client.rest.interactions_response(
78
+ @id,
79
+ @token,
80
+ type: 5,
81
+ data: data
82
+ )
83
+ end
84
+
85
+ def deferUpdate
86
+ client.rest.interactions_response(
87
+ @id,
88
+ @token,
89
+ type: 6
90
+ )
91
+ end
92
+
93
+ def update(content = nil, embeds: nil, components: nil)
94
+ deferUpdate
95
+
96
+ client.rest.interaction_edit(
97
+ @application_id,
98
+ @token,
99
+ content: content,
100
+ embeds: embeds,
101
+ components: components
102
+ )
103
+ end
104
+
105
+ def followUp(content = nil, embeds: nil, components: nil, flags: nil)
106
+ client.rest.interaction_followup(
107
+ @application_id,
108
+ @token,
109
+ content: content,
110
+ embeds: embeds,
111
+ components: components,
112
+ flags: flags
113
+ )
114
+ end
115
+
116
+ def command?
117
+ @type == TYPES[:application_command]
118
+ end
119
+
120
+ def component?
121
+ @type == TYPES[:message_component]
122
+ end
123
+
124
+ def is_type?(type)
125
+ component? && @data["component_type"] == COMPONENT_TYPES[type.to_sym]
126
+ end
127
+
128
+ def custom_id
129
+ @data["custom_id"]
130
+ end
131
+
132
+ def inspect
133
+ "#<Rubord::Interaction id=#{@id} type=#{@type} guild_id=#{@guild_id} channel_id=#{@channel_id}>"
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,63 @@
1
+ module Rubord
2
+ class Member
3
+ attr_reader :id,
4
+ :user,
5
+ :roles,
6
+ :guild_id,
7
+ :client
8
+
9
+ def initialize(data, client)
10
+ @client = client
11
+ @guild_id = data["guild_id"]
12
+ @roles = data["roles"] || []
13
+
14
+ @user = Rubord::User.new(data["user"])
15
+ @id = @user.id
16
+
17
+ client.users.set(@id, @user)
18
+ guild&.members&.set(@id, self)
19
+ end
20
+
21
+ def guild
22
+ client.guilds.get(@guild_id)
23
+ end
24
+
25
+ def role_objects
26
+ return [] unless guild && guild.roles
27
+
28
+ @roles
29
+ .map { |role_id| guild.roles.get(role_id) }
30
+ .compact
31
+ end
32
+
33
+ def permissions
34
+ return [] unless guild && guild.roles
35
+
36
+ bitfield = 0
37
+
38
+ if (everyone = guild.roles.get(guild.id))
39
+ bitfield |= everyone.permissions
40
+ end
41
+
42
+ role_objects.each do |role|
43
+ bitfield |= role.permissions
44
+ end
45
+
46
+ if (bitfield & Rubord::Permissions::FLAGS[:administrator]) != 0
47
+ return Rubord::Permissions::FLAGS.keys
48
+ end
49
+
50
+ Rubord::Permissions::FLAGS
51
+ .select { |_name, flag| (bitfield & flag) != 0 }
52
+ .keys
53
+ end
54
+
55
+ def has_permission?(perm)
56
+ permissions.include?(perm.to_sym)
57
+ end
58
+
59
+ def inspect
60
+ "#<Rubord::Member id=#{@id} guild_id=#{@guild_id} roles=#{@roles}>"
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,47 @@
1
+ module Rubord
2
+ class Mention
3
+ attr_reader :users,
4
+ :roles,
5
+ :channels,
6
+ :everyone
7
+
8
+ def initialize(data, client, guild)
9
+ @everyone = data["mention_everyone"] || false
10
+
11
+ @users = (data["mentions"] || []).map do |user_data|
12
+ user = Rubord::User.new(user_data)
13
+ client.users.set(user.id, user)
14
+ user
15
+ end
16
+
17
+ @roles = (data["mention_roles"] || []).map do |role_id|
18
+ guild&.roles&.get(role_id)
19
+ end
20
+
21
+ @channels =
22
+ if data["mention_channels"]
23
+ data["mention_channels"].map do |channel_data|
24
+ channel = Rubord::Channel.new(channel_data, client)
25
+ client.channels.set(channel.id, channel)
26
+ channel
27
+ end
28
+ else
29
+ Rubord.Parser.channel_mentions(data["content"] || "").map do |channel_id|
30
+ client.channels.get(channel_id) || Rubord::Channel.new({ "id" => channel_id }, client)
31
+ end
32
+ end
33
+ end
34
+
35
+ def mention_everyone?
36
+ @everyone
37
+ end
38
+
39
+ def empty?
40
+ users.empty? && roles.empty? && channels.empty? && !everyone
41
+ end
42
+
43
+ def inspect
44
+ "#<Rubord::Mention users=#{users.size} roles=#{roles.size} channels=#{channels.size} everyone=#{everyone}>"
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,88 @@
1
+ module Rubord
2
+ class Message
3
+ attr_reader :id,
4
+ :content,
5
+ :author,
6
+ :channel_id,
7
+ :guild_id,
8
+ :channel,
9
+ :mentions
10
+
11
+ def initialize(data, client)
12
+ @client = client
13
+ @id = data["id"]
14
+ @content = data["content"]
15
+ @channel_id = data["channel_id"]
16
+ @guild_id = data["guild_id"]
17
+
18
+ @author = Rubord::User.new(data["author"])
19
+ client.users.set(@author.id, @author)
20
+
21
+ @channel =
22
+ client.channels.get(@channel_id) ||
23
+ Rubord::Channel.new({ "id" => @channel_id }, client)
24
+
25
+ @mentions = Rubord::Mention.new(
26
+ data,
27
+ client,
28
+ guild
29
+ )
30
+ end
31
+
32
+ def guild
33
+ return nil unless @guild_id
34
+
35
+ @guild ||=
36
+ @client.guilds.get(@guild_id) ||
37
+ Rubord::Guild.new(@client.rest.get_guild(@guild_id), @client)
38
+ end
39
+
40
+ def member
41
+ return nil unless guild
42
+ guild.fetch_member(@author.id)
43
+ end
44
+
45
+ def post(content = nil, embeds: nil, components: nil, flags: nil)
46
+ @client.rest.send_message(
47
+ @channel_id,
48
+ content: content,
49
+ embeds: embeds,
50
+ components: components,
51
+ flags: flags
52
+ )
53
+ end
54
+
55
+ def reply(content = nil, embeds: nil, components: nil, flags: nil)
56
+ @client.rest.reply_message(
57
+ @channel_id,
58
+ @id,
59
+ content: content,
60
+ embeds: embeds,
61
+ components: components,
62
+ flags: flags
63
+ )
64
+ end
65
+
66
+ def edit(content = nil, embeds: nil, components: nil, flags: nil)
67
+ @client.rest.edit_message(
68
+ @channel_id,
69
+ @id,
70
+ content: content,
71
+ embeds: embeds,
72
+ components: components,
73
+ flags: flags
74
+ )
75
+ end
76
+
77
+ def delete
78
+ @client.rest.delete_message(
79
+ @channel_id,
80
+ @id
81
+ )
82
+ end
83
+
84
+ def inspect
85
+ "#<Rubord::Message id=#{@id} mentions=#{mentions.inspect}>"
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,15 @@
1
+ module Rubord
2
+ class Role
3
+ attr_reader :id,
4
+ :name,
5
+ :permissions,
6
+ :position
7
+
8
+ def initialize(data)
9
+ @id = data["id"]
10
+ @name = data["name"]
11
+ @permissions = data["permissions"].to_i
12
+ @position = data["position"]
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ module Rubord
2
+ class User
3
+ attr_reader :id,
4
+ :username,
5
+ :globalname,
6
+ :discriminator,
7
+ :creationDate,
8
+ :bot,
9
+ :tag
10
+
11
+ def initialize(data)
12
+ @id = data["id"]
13
+ @username = data["username"]
14
+ @globalname = data["global_name"]
15
+ @discriminator = data["discriminator"]
16
+ @creationDate = ((@id.to_i >> 22) + 1420070400000) / 1000
17
+ @bot = data["bot"] || false
18
+ @tag = "#{@username}##{@discriminator}"
19
+ end
20
+ end
21
+ end