discordrb 3.3.0 → 3.5.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.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +152 -0
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
  4. data/.github/ISSUE_TEMPLATE/feature_request.md +24 -0
  5. data/.github/pull_request_template.md +37 -0
  6. data/.github/workflows/codeql.yml +65 -0
  7. data/.markdownlint.json +4 -0
  8. data/.rubocop.yml +39 -36
  9. data/CHANGELOG.md +874 -552
  10. data/Gemfile +2 -0
  11. data/LICENSE.txt +1 -1
  12. data/README.md +80 -86
  13. data/Rakefile +2 -0
  14. data/bin/console +1 -0
  15. data/discordrb-webhooks.gemspec +9 -6
  16. data/discordrb.gemspec +21 -18
  17. data/lib/discordrb/allowed_mentions.rb +36 -0
  18. data/lib/discordrb/api/application.rb +202 -0
  19. data/lib/discordrb/api/channel.rb +236 -47
  20. data/lib/discordrb/api/interaction.rb +54 -0
  21. data/lib/discordrb/api/invite.rb +5 -5
  22. data/lib/discordrb/api/server.rb +94 -66
  23. data/lib/discordrb/api/user.rb +17 -11
  24. data/lib/discordrb/api/webhook.rb +63 -6
  25. data/lib/discordrb/api.rb +55 -16
  26. data/lib/discordrb/await.rb +0 -1
  27. data/lib/discordrb/bot.rb +480 -93
  28. data/lib/discordrb/cache.rb +31 -24
  29. data/lib/discordrb/colour_rgb.rb +43 -0
  30. data/lib/discordrb/commands/command_bot.rb +35 -12
  31. data/lib/discordrb/commands/container.rb +21 -24
  32. data/lib/discordrb/commands/parser.rb +20 -20
  33. data/lib/discordrb/commands/rate_limiter.rb +4 -3
  34. data/lib/discordrb/container.rb +209 -20
  35. data/lib/discordrb/data/activity.rb +271 -0
  36. data/lib/discordrb/data/application.rb +50 -0
  37. data/lib/discordrb/data/attachment.rb +71 -0
  38. data/lib/discordrb/data/audit_logs.rb +345 -0
  39. data/lib/discordrb/data/channel.rb +993 -0
  40. data/lib/discordrb/data/component.rb +229 -0
  41. data/lib/discordrb/data/embed.rb +251 -0
  42. data/lib/discordrb/data/emoji.rb +82 -0
  43. data/lib/discordrb/data/integration.rb +122 -0
  44. data/lib/discordrb/data/interaction.rb +800 -0
  45. data/lib/discordrb/data/invite.rb +137 -0
  46. data/lib/discordrb/data/member.rb +372 -0
  47. data/lib/discordrb/data/message.rb +414 -0
  48. data/lib/discordrb/data/overwrite.rb +108 -0
  49. data/lib/discordrb/data/profile.rb +91 -0
  50. data/lib/discordrb/data/reaction.rb +33 -0
  51. data/lib/discordrb/data/recipient.rb +34 -0
  52. data/lib/discordrb/data/role.rb +248 -0
  53. data/lib/discordrb/data/server.rb +1004 -0
  54. data/lib/discordrb/data/user.rb +264 -0
  55. data/lib/discordrb/data/voice_region.rb +45 -0
  56. data/lib/discordrb/data/voice_state.rb +41 -0
  57. data/lib/discordrb/data/webhook.rb +238 -0
  58. data/lib/discordrb/data.rb +28 -4180
  59. data/lib/discordrb/errors.rb +46 -4
  60. data/lib/discordrb/events/bans.rb +7 -5
  61. data/lib/discordrb/events/channels.rb +3 -1
  62. data/lib/discordrb/events/guilds.rb +16 -9
  63. data/lib/discordrb/events/interactions.rb +482 -0
  64. data/lib/discordrb/events/invites.rb +125 -0
  65. data/lib/discordrb/events/members.rb +6 -2
  66. data/lib/discordrb/events/message.rb +72 -27
  67. data/lib/discordrb/events/presence.rb +35 -18
  68. data/lib/discordrb/events/raw.rb +1 -3
  69. data/lib/discordrb/events/reactions.rb +49 -4
  70. data/lib/discordrb/events/threads.rb +96 -0
  71. data/lib/discordrb/events/typing.rb +6 -4
  72. data/lib/discordrb/events/voice_server_update.rb +47 -0
  73. data/lib/discordrb/events/voice_state_update.rb +15 -10
  74. data/lib/discordrb/events/webhooks.rb +9 -6
  75. data/lib/discordrb/gateway.rb +99 -71
  76. data/lib/discordrb/id_object.rb +39 -0
  77. data/lib/discordrb/light/integrations.rb +1 -1
  78. data/lib/discordrb/light/light_bot.rb +1 -1
  79. data/lib/discordrb/logger.rb +4 -4
  80. data/lib/discordrb/paginator.rb +57 -0
  81. data/lib/discordrb/permissions.rb +159 -39
  82. data/lib/discordrb/version.rb +1 -1
  83. data/lib/discordrb/voice/encoder.rb +16 -7
  84. data/lib/discordrb/voice/network.rb +99 -47
  85. data/lib/discordrb/voice/sodium.rb +98 -0
  86. data/lib/discordrb/voice/voice_bot.rb +33 -25
  87. data/lib/discordrb/webhooks.rb +2 -0
  88. data/lib/discordrb.rb +107 -1
  89. metadata +126 -54
  90. data/.codeclimate.yml +0 -16
  91. data/.travis.yml +0 -33
  92. data/bin/travis_build_docs.sh +0 -17
  93. /data/{CONTRIBUTING.md → .github/CONTRIBUTING.md} +0 -0
@@ -0,0 +1,248 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Discordrb
4
+ # A Discord role that contains permissions and applies to certain users
5
+ class Role
6
+ include IDObject
7
+
8
+ # @return [Permissions] this role's permissions.
9
+ attr_reader :permissions
10
+
11
+ # @return [String] this role's name ("new role" if it hasn't been changed)
12
+ attr_reader :name
13
+
14
+ # @return [Server] the server this role belongs to
15
+ attr_reader :server
16
+
17
+ # @return [true, false] whether or not this role should be displayed separately from other users
18
+ attr_reader :hoist
19
+
20
+ # @return [true, false] whether or not this role is managed by an integration or a bot
21
+ attr_reader :managed
22
+ alias_method :managed?, :managed
23
+
24
+ # @return [true, false] whether this role can be mentioned using a role mention
25
+ attr_reader :mentionable
26
+ alias_method :mentionable?, :mentionable
27
+
28
+ # @return [ColourRGB] the role colour
29
+ attr_reader :colour
30
+ alias_method :color, :colour
31
+
32
+ # @return [Integer] the position of this role in the hierarchy
33
+ attr_reader :position
34
+
35
+ # @return [String, nil] The icon hash for this role.
36
+ attr_reader :icon
37
+
38
+ # @return [Tags, nil] The role tags
39
+ attr_reader :tags
40
+
41
+ # Wrapper for the role tags
42
+ class Tags
43
+ # @return [Integer, nil] The ID of the bot this role belongs to
44
+ attr_reader :bot_id
45
+
46
+ # @return [Integer, nil] The ID of the integration this role belongs to
47
+ attr_reader :integration_id
48
+
49
+ # @return [true, false] Whether this is the guild's Booster role
50
+ attr_reader :premium_subscriber
51
+
52
+ # @return [Integer, nil] The id of this role's subscription sku and listing
53
+ attr_reader :subscription_listing_id
54
+
55
+ # @return [true, false] Whether this role is available for purchase
56
+ attr_reader :available_for_purchase
57
+
58
+ # @return [true, false] Whether this role is a guild's linked role
59
+ attr_reader :guild_connections
60
+
61
+ def initialize(data)
62
+ @bot_id = data['bot_id']&.resolve_id
63
+ @integration_id = data['integration_id']&.resolve_id
64
+ @premium_subscriber = data.key?('premium_subscriber')
65
+ @subscription_listing_id = data['subscription_listing_id']&.resolve_id
66
+ @available_for_purchase = data.key?('available_for_purchase')
67
+ @guild_connections = data.key?('guild_connections')
68
+ end
69
+ end
70
+
71
+ # This class is used internally as a wrapper to a Role object that allows easy writing of permission data.
72
+ class RoleWriter
73
+ # @!visibility private
74
+ def initialize(role, token)
75
+ @role = role
76
+ @token = token
77
+ end
78
+
79
+ # Write the specified permission data to the role, without updating the permission cache
80
+ # @param bits [Integer] The packed permissions to write.
81
+ def write(bits)
82
+ @role.send(:packed=, bits, false)
83
+ end
84
+
85
+ # The inspect method is overridden, in this case to prevent the token being leaked
86
+ def inspect
87
+ "<RoleWriter role=#{@role} token=...>"
88
+ end
89
+ end
90
+
91
+ # @!visibility private
92
+ def initialize(data, bot, server = nil)
93
+ @bot = bot
94
+ @server = server
95
+ @permissions = Permissions.new(data['permissions'], RoleWriter.new(self, @bot.token))
96
+ @name = data['name']
97
+ @id = data['id'].to_i
98
+
99
+ @position = data['position']
100
+
101
+ @hoist = data['hoist']
102
+ @mentionable = data['mentionable']
103
+ @managed = data['managed']
104
+
105
+ @colour = ColourRGB.new(data['color'])
106
+
107
+ @icon = data['icon']
108
+
109
+ @tags = Tags.new(data['tags']) if data['tags']
110
+ end
111
+
112
+ # @return [String] a string that will mention this role, if it is mentionable.
113
+ def mention
114
+ "<@&#{@id}>"
115
+ end
116
+
117
+ # @return [Array<Member>] an array of members who have this role.
118
+ # @note This requests a member chunk if it hasn't for the server before, which may be slow initially
119
+ def members
120
+ @server.members.select { |m| m.role? self }
121
+ end
122
+
123
+ alias_method :users, :members
124
+
125
+ # Updates the data cache from another Role object
126
+ # @note For internal use only
127
+ # @!visibility private
128
+ def update_from(other)
129
+ @permissions = other.permissions
130
+ @name = other.name
131
+ @hoist = other.hoist
132
+ @colour = other.colour
133
+ @position = other.position
134
+ @managed = other.managed
135
+ @icon = other.icon
136
+ end
137
+
138
+ # Updates the data cache from a hash containing data
139
+ # @note For internal use only
140
+ # @!visibility private
141
+ def update_data(new_data)
142
+ @name = new_data[:name] || new_data['name'] || @name
143
+ @hoist = new_data['hoist'] unless new_data['hoist'].nil?
144
+ @hoist = new_data[:hoist] unless new_data[:hoist].nil?
145
+ @colour = new_data[:colour] || (new_data['color'] ? ColourRGB.new(new_data['color']) : @colour)
146
+ end
147
+
148
+ # Sets the role name to something new
149
+ # @param name [String] The name that should be set
150
+ def name=(name)
151
+ update_role_data(name: name)
152
+ end
153
+
154
+ # Changes whether or not this role is displayed at the top of the user list
155
+ # @param hoist [true, false] The value it should be changed to
156
+ def hoist=(hoist)
157
+ update_role_data(hoist: hoist)
158
+ end
159
+
160
+ # Changes whether or not this role can be mentioned
161
+ # @param mentionable [true, false] The value it should be changed to
162
+ def mentionable=(mentionable)
163
+ update_role_data(mentionable: mentionable)
164
+ end
165
+
166
+ # Sets the role colour to something new
167
+ # @param colour [ColourRGB] The new colour
168
+ def colour=(colour)
169
+ update_role_data(colour: colour)
170
+ end
171
+
172
+ # Upload a role icon for servers with the ROLE_ICONS feature.
173
+ # @param file [File]
174
+ def icon=(file)
175
+ update_role_data(icon: file)
176
+ end
177
+
178
+ # @param format ['webp', 'png', 'jpeg']
179
+ # @return [String] URL to the icon on Discord's CDN.
180
+ def icon_url(format = 'webp')
181
+ return nil unless @icon
182
+
183
+ Discordrb::API.role_icon_url(@id, @icon, format)
184
+ end
185
+
186
+ alias_method :color=, :colour=
187
+
188
+ # Changes this role's permissions to a fixed bitfield. This allows setting multiple permissions at once with just
189
+ # one API call.
190
+ #
191
+ # Information on how this bitfield is structured can be found at
192
+ # https://discord.com/developers/docs/topics/permissions.
193
+ # @example Remove all permissions from a role
194
+ # role.packed = 0
195
+ # @param packed [Integer] A bitfield with the desired permissions value.
196
+ # @param update_perms [true, false] Whether the internal data should also be updated. This should always be true
197
+ # when calling externally.
198
+ def packed=(packed, update_perms = true)
199
+ update_role_data(permissions: packed)
200
+ @permissions.bits = packed if update_perms
201
+ end
202
+
203
+ # Moves this role above another role in the list.
204
+ # @param other [Role, String, Integer, nil] The role, or its ID, above which this role should be moved. If it is `nil`,
205
+ # the role will be moved above the @everyone role.
206
+ # @return [Integer] the new position of this role
207
+ def sort_above(other = nil)
208
+ other = @server.role(other.resolve_id) if other
209
+ roles = @server.roles.sort_by(&:position)
210
+ roles.delete_at(@position)
211
+
212
+ index = other ? roles.index { |role| role.id == other.id } + 1 : 1
213
+ roles.insert(index, self)
214
+
215
+ updated_roles = roles.map.with_index { |role, position| { id: role.id, position: position } }
216
+ @server.update_role_positions(updated_roles)
217
+ index
218
+ end
219
+
220
+ alias_method :move_above, :sort_above
221
+
222
+ # Deletes this role. This cannot be undone without recreating the role!
223
+ # @param reason [String] the reason for this role's deletion
224
+ def delete(reason = nil)
225
+ API::Server.delete_role(@bot.token, @server.id, @id, reason)
226
+ @server.delete_role(@id)
227
+ end
228
+
229
+ # The inspect method is overwritten to give more useful output
230
+ def inspect
231
+ "<Role name=#{@name} permissions=#{@permissions.inspect} hoist=#{@hoist} colour=#{@colour.inspect} server=#{@server.inspect} position=#{@position} mentionable=#{@mentionable}>"
232
+ end
233
+
234
+ private
235
+
236
+ def update_role_data(new_data)
237
+ API::Server.update_role(@bot.token, @server.id, @id,
238
+ new_data[:name] || @name,
239
+ (new_data[:colour] || @colour).combined,
240
+ new_data[:hoist].nil? ? @hoist : new_data[:hoist],
241
+ new_data[:mentionable].nil? ? @mentionable : new_data[:mentionable],
242
+ new_data[:permissions] || @permissions.bits,
243
+ nil,
244
+ new_data.key?(:icon) ? new_data[:icon] : :undef)
245
+ update_data(new_data)
246
+ end
247
+ end
248
+ end