discordrb 3.3.0 → 3.5.0

Sign up to get free protection for your applications and to get access to all the features.
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