discordrb 3.3.0 → 3.4.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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +126 -0
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +39 -0
  4. data/.github/ISSUE_TEMPLATE/feature_request.md +25 -0
  5. data/.github/pull_request_template.md +37 -0
  6. data/.rubocop.yml +34 -37
  7. data/.travis.yml +5 -6
  8. data/CHANGELOG.md +504 -347
  9. data/Gemfile +2 -0
  10. data/LICENSE.txt +1 -1
  11. data/README.md +61 -79
  12. data/Rakefile +2 -0
  13. data/bin/console +1 -0
  14. data/discordrb-webhooks.gemspec +6 -6
  15. data/discordrb.gemspec +18 -18
  16. data/lib/discordrb/allowed_mentions.rb +36 -0
  17. data/lib/discordrb/api/channel.rb +62 -39
  18. data/lib/discordrb/api/invite.rb +3 -3
  19. data/lib/discordrb/api/server.rb +57 -50
  20. data/lib/discordrb/api/user.rb +9 -8
  21. data/lib/discordrb/api/webhook.rb +6 -6
  22. data/lib/discordrb/api.rb +40 -15
  23. data/lib/discordrb/await.rb +0 -1
  24. data/lib/discordrb/bot.rb +175 -73
  25. data/lib/discordrb/cache.rb +4 -2
  26. data/lib/discordrb/colour_rgb.rb +43 -0
  27. data/lib/discordrb/commands/command_bot.rb +30 -9
  28. data/lib/discordrb/commands/container.rb +20 -23
  29. data/lib/discordrb/commands/parser.rb +18 -18
  30. data/lib/discordrb/commands/rate_limiter.rb +3 -2
  31. data/lib/discordrb/container.rb +77 -17
  32. data/lib/discordrb/data/activity.rb +271 -0
  33. data/lib/discordrb/data/application.rb +50 -0
  34. data/lib/discordrb/data/attachment.rb +56 -0
  35. data/lib/discordrb/data/audit_logs.rb +345 -0
  36. data/lib/discordrb/data/channel.rb +849 -0
  37. data/lib/discordrb/data/embed.rb +251 -0
  38. data/lib/discordrb/data/emoji.rb +82 -0
  39. data/lib/discordrb/data/integration.rb +83 -0
  40. data/lib/discordrb/data/invite.rb +137 -0
  41. data/lib/discordrb/data/member.rb +297 -0
  42. data/lib/discordrb/data/message.rb +334 -0
  43. data/lib/discordrb/data/overwrite.rb +102 -0
  44. data/lib/discordrb/data/profile.rb +91 -0
  45. data/lib/discordrb/data/reaction.rb +33 -0
  46. data/lib/discordrb/data/recipient.rb +34 -0
  47. data/lib/discordrb/data/role.rb +191 -0
  48. data/lib/discordrb/data/server.rb +1002 -0
  49. data/lib/discordrb/data/user.rb +204 -0
  50. data/lib/discordrb/data/voice_region.rb +45 -0
  51. data/lib/discordrb/data/voice_state.rb +41 -0
  52. data/lib/discordrb/data/webhook.rb +145 -0
  53. data/lib/discordrb/data.rb +25 -4180
  54. data/lib/discordrb/errors.rb +2 -1
  55. data/lib/discordrb/events/bans.rb +7 -5
  56. data/lib/discordrb/events/channels.rb +2 -0
  57. data/lib/discordrb/events/guilds.rb +16 -9
  58. data/lib/discordrb/events/invites.rb +125 -0
  59. data/lib/discordrb/events/members.rb +6 -2
  60. data/lib/discordrb/events/message.rb +69 -27
  61. data/lib/discordrb/events/presence.rb +14 -4
  62. data/lib/discordrb/events/raw.rb +1 -3
  63. data/lib/discordrb/events/reactions.rb +49 -3
  64. data/lib/discordrb/events/typing.rb +6 -4
  65. data/lib/discordrb/events/voice_server_update.rb +47 -0
  66. data/lib/discordrb/events/voice_state_update.rb +15 -10
  67. data/lib/discordrb/events/webhooks.rb +9 -6
  68. data/lib/discordrb/gateway.rb +72 -57
  69. data/lib/discordrb/id_object.rb +39 -0
  70. data/lib/discordrb/light/integrations.rb +1 -1
  71. data/lib/discordrb/light/light_bot.rb +1 -1
  72. data/lib/discordrb/logger.rb +4 -4
  73. data/lib/discordrb/paginator.rb +57 -0
  74. data/lib/discordrb/permissions.rb +103 -8
  75. data/lib/discordrb/version.rb +1 -1
  76. data/lib/discordrb/voice/encoder.rb +16 -7
  77. data/lib/discordrb/voice/network.rb +84 -43
  78. data/lib/discordrb/voice/sodium.rb +96 -0
  79. data/lib/discordrb/voice/voice_bot.rb +34 -26
  80. data/lib/discordrb.rb +73 -0
  81. metadata +98 -60
  82. /data/{CONTRIBUTING.md → .github/CONTRIBUTING.md} +0 -0
@@ -0,0 +1,271 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Discordrb
4
+ # Contains information about user activities such as the game they are playing,
5
+ # music they are listening to, or their live stream.
6
+ class Activity
7
+ # Values corresponding to the flags bitmask
8
+ FLAGS = {
9
+ instance: 1 << 0, # this activity is an instanced game session
10
+ join: 1 << 1, # this activity is joinable
11
+ spectate: 1 << 2, # this activity can be spectated
12
+ join_request: 1 << 3, # this activity allows asking to join
13
+ sync: 1 << 4, # this activity is a spotify track
14
+ play: 1 << 5 # this game can be played or opened from discord
15
+ }.freeze
16
+
17
+ # @return [String] the activity's name
18
+ attr_reader :name
19
+
20
+ # @return [Integer, nil] activity type. Can be {GAME}, {STREAMING}, {LISTENING}, {CUSTOM}, or {COMPETING}
21
+ attr_reader :type
22
+
23
+ # @return [String, nil] stream URL, when the activity type is {STREAMING}
24
+ attr_reader :url
25
+
26
+ # @return [String, nil] the application ID for the game
27
+ attr_reader :application_id
28
+
29
+ # @return [String, nil] details about what the player is currently doing
30
+ attr_reader :details
31
+
32
+ # @return [String, nil] the user's current party status
33
+ attr_reader :state
34
+
35
+ # @return [true, false] whether or not the activity is an instanced game session
36
+ attr_reader :instance
37
+
38
+ # @return [Integer] a bitmask of activity flags
39
+ # @see FLAGS
40
+ attr_reader :flags
41
+
42
+ # @return [Timestamps, nil] times for the start and/or end of the activity
43
+ attr_reader :timestamps
44
+
45
+ # @return [Secrets, nil] secrets for rich presence, joining, and spectating
46
+ attr_reader :secrets
47
+
48
+ # @return [Assets, nil] images for the presence and their texts
49
+ attr_reader :assets
50
+
51
+ # @return [Party, nil] information about the player's current party
52
+ attr_reader :party
53
+
54
+ # @return [Emoji, nil] emoji data for custom statuses
55
+ attr_reader :emoji
56
+
57
+ # @return [Time] the time when the activity was added to the user's session
58
+ attr_reader :created_at
59
+
60
+ # Type indicating the activity is for a game
61
+ GAME = 0
62
+ # Type indicating the activity is a stream
63
+ STREAMING = 1
64
+ # Type indicating the activity is for music
65
+ LISTENING = 2
66
+ # This type is currently unused in the client but can be reported by bots
67
+ WATCHING = 3
68
+ # Type indicating the activity is a custom status
69
+ CUSTOM = 4
70
+ # Type indicating the activity is for a competitive game
71
+ COMPETING = 5
72
+
73
+ # @!visibility private
74
+ def initialize(data, bot)
75
+ @name = data['name']
76
+ @type = data['type']
77
+ @url = data['url']
78
+ @application_id = data['application_id']
79
+ @details = data['details']
80
+ @state = data['state']
81
+ @instance = data['instance']
82
+ @flags = data['flags'] || 0
83
+ @created_at = Time.at(data['created_at'].to_i)
84
+
85
+ @timestamps = Timestamps.new(data['timestamps']) if data['timestamps']
86
+ @secrets = Secret.new(data['secrets']) if data['secrets']
87
+ @assets = Assets.new(data['assets'], @application_id) if data['assets']
88
+ @party = Party.new(data['party']) if data['party']
89
+ @emoji = Emoji.new(data['emoji'], bot, nil) if data['emoji']
90
+ end
91
+
92
+ # @return [true, false] Whether or not the `join` flag is set for this activity
93
+ def join?
94
+ flag_set? :join
95
+ end
96
+
97
+ # @return [true, false] Whether or not the `spectate` flag is set for this activity
98
+ def spectate?
99
+ flag_set? :spectate
100
+ end
101
+
102
+ # @return [true, false] Whether or not the `join_request` flag is set for this activity
103
+ def join_request?
104
+ flag_set? :join_request
105
+ end
106
+
107
+ # @return [true, false] Whether or not the `sync` flag is set for this activity
108
+ def sync?
109
+ flag_set? :sync
110
+ end
111
+
112
+ # @return [true, false] Whether or not the `play` flag is set for this activity
113
+ def play?
114
+ flag_set? :play
115
+ end
116
+
117
+ # @return [true, false] Whether or not the `instance` flag is set for this activity
118
+ def instance?
119
+ @instance || flag_set?(:instance)
120
+ end
121
+
122
+ # @!visibility private
123
+ def flag_set?(sym)
124
+ !(@flags & FLAGS[sym]).zero?
125
+ end
126
+
127
+ # Timestamps for the start and end of instanced activities
128
+ class Timestamps
129
+ # @return [Time, nil]
130
+ attr_reader :start
131
+
132
+ # @return [Time, nil]
133
+ attr_reader :end
134
+
135
+ # @!visibility private
136
+ def initialize(data)
137
+ @start = Time.at(data['start'] / 1000) if data['start']
138
+ @end = Time.at(data['end'] / 1000) if data['end']
139
+ end
140
+ end
141
+
142
+ # Contains secrets used for rich presence
143
+ class Secrets
144
+ # @return [String, nil] secret for joining a party
145
+ attr_reader :join
146
+
147
+ # @return [String, nil] secret for spectating
148
+ attr_reader :spectate
149
+
150
+ # @return [String, nil] secret for a specific instanced match
151
+ attr_reader :match
152
+
153
+ # @!visibility private
154
+ def initialize(data)
155
+ @join = data['join']
156
+ @spectate = data['spectate']
157
+ @match = data['match']
158
+ end
159
+ end
160
+
161
+ # Assets for rich presence images and hover text
162
+ class Assets
163
+ # @return [String, nil] the asset ID for the large image of this activity
164
+ attr_reader :large_image_id
165
+
166
+ # @return [String, nil] text displayed when hovering over the large iamge
167
+ attr_reader :large_text
168
+
169
+ # @return [String, nil] the asset ID for the small image of this activity
170
+ attr_reader :small_image_id
171
+
172
+ # @return [String, nil]
173
+ attr_reader :small_text
174
+
175
+ # @return [String, nil] the application ID for these assets.
176
+ attr_reader :application_id
177
+
178
+ # @!visibility private
179
+ def initialize(data, application_id)
180
+ @application_id = application_id
181
+ @large_image_id = data['large_image']
182
+ @large_text = data['large_text']
183
+ @small_image_id = data['small_image']
184
+ @small_text = data['small_text']
185
+ end
186
+
187
+ # Utility function to get an Asset's large image URL.
188
+ # @param format [String, nil] If `nil`, the URL will default to `webp`. You can otherwise specify one of `webp`, `jpg`, or `png`.
189
+ # @return [String] the URL to the large image asset.
190
+ def large_image_url(format = 'webp')
191
+ API.asset_url(@application_id, @large_image_id, format)
192
+ end
193
+
194
+ # Utility function to get an Asset's large image URL.
195
+ # @param format [String, nil] If `nil`, the URL will default to `webp`. You can otherwise specify one of `webp`, `jpg`, or `png`.
196
+ # @return [String] the URL to the small image asset.
197
+ def small_image_url(format = 'webp')
198
+ API.asset_url(@application_id, @small_image_id, format)
199
+ end
200
+ end
201
+
202
+ # Contains information about an activity's party
203
+ class Party
204
+ # @return [String, nil]
205
+ attr_reader :id
206
+
207
+ # @return [Integer, nil]
208
+ attr_reader :current_size
209
+
210
+ # @return [Integer, nil]
211
+ attr_reader :max_size
212
+
213
+ # @!visibility private
214
+ def initialize(data)
215
+ @id = data['id']
216
+ @current_size, @max_size = data['size']
217
+ end
218
+ end
219
+ end
220
+
221
+ # A collection of the user's activities.
222
+ class ActivitySet
223
+ include Enumerable
224
+
225
+ # @!visibility private
226
+ def initialize(activities = [])
227
+ @activities = activities
228
+ end
229
+
230
+ # @!visibility private
231
+ # Implement each for Enumerable
232
+ def each(&block)
233
+ @activities.each(&block)
234
+ end
235
+
236
+ # @return [Array<Activity>] all activities
237
+ def to_a
238
+ @activities
239
+ end
240
+
241
+ # @return [Array<Activity>] all activities of type {Activity::GAME}
242
+ def games
243
+ @activities.select { |act| act.type == Activity::GAME }
244
+ end
245
+
246
+ # @return [Array<Activity>] all activities of type {Activity::STREAMING}
247
+ def streaming
248
+ @activities.select { |act| act.type == Activity::STREAMING }
249
+ end
250
+
251
+ # @return [Array<Activity>] all activities of type {Activity::LISTENING}
252
+ def listening
253
+ @activities.select { |act| act.type == Activity::LISTENING }
254
+ end
255
+
256
+ # @return [Array<Activity>] all activities of type {Activity::WATCHING}
257
+ def watching
258
+ @activities.select { |act| act.type == Activity::WATCHING }
259
+ end
260
+
261
+ # @return [Array<Activity>] all activities of type {Activity::CUSTOM}
262
+ def custom_status
263
+ @activities.select { |act| act.type == Activity::CUSTOM }
264
+ end
265
+
266
+ # @return [Array<Activity>] all activities of type {Activity::COMPETING}
267
+ def competing
268
+ @activities.select { |act| act.type == Activity::COMPETING }
269
+ end
270
+ end
271
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Discordrb
4
+ # OAuth Application information
5
+ class Application
6
+ include IDObject
7
+
8
+ # @return [String] the application name
9
+ attr_reader :name
10
+
11
+ # @return [String] the application description
12
+ attr_reader :description
13
+
14
+ # @return [Array<String>] the application's origins permitted to use RPC
15
+ attr_reader :rpc_origins
16
+
17
+ # @return [Integer]
18
+ attr_reader :flags
19
+
20
+ # Gets the user object of the owner. May be limited to username, discriminator,
21
+ # ID, and avatar if the bot cannot reach the owner.
22
+ # @return [User] the user object of the owner
23
+ attr_reader :owner
24
+
25
+ def initialize(data, bot)
26
+ @bot = bot
27
+
28
+ @name = data['name']
29
+ @id = data['id'].to_i
30
+ @description = data['description']
31
+ @icon_id = data['icon']
32
+ @rpc_origins = data['rpc_origins']
33
+ @flags = data['flags']
34
+ @owner = @bot.ensure_user(data['owner'])
35
+ end
36
+
37
+ # Utility function to get a application's icon URL.
38
+ # @return [String, nil] the URL of the icon image (nil if no image is set).
39
+ def icon_url
40
+ return nil if @icon_id.nil?
41
+
42
+ API.app_icon_url(@id, @icon_id)
43
+ end
44
+
45
+ # The inspect method is overwritten to give more useful output
46
+ def inspect
47
+ "<Application name=#{@name} id=#{@id}>"
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Discordrb
4
+ # An attachment to a message
5
+ class Attachment
6
+ include IDObject
7
+
8
+ # @return [Message] the message this attachment belongs to.
9
+ attr_reader :message
10
+
11
+ # @return [String] the CDN URL this attachment can be downloaded at.
12
+ attr_reader :url
13
+
14
+ # @return [String] the attachment's proxy URL - I'm not sure what exactly this does, but I think it has something to
15
+ # do with CDNs.
16
+ attr_reader :proxy_url
17
+
18
+ # @return [String] the attachment's filename.
19
+ attr_reader :filename
20
+
21
+ # @return [Integer] the attachment's file size in bytes.
22
+ attr_reader :size
23
+
24
+ # @return [Integer, nil] the width of an image file, in pixels, or `nil` if the file is not an image.
25
+ attr_reader :width
26
+
27
+ # @return [Integer, nil] the height of an image file, in pixels, or `nil` if the file is not an image.
28
+ attr_reader :height
29
+
30
+ # @!visibility private
31
+ def initialize(data, message, bot)
32
+ @bot = bot
33
+ @message = message
34
+
35
+ @id = data['id'].to_i
36
+ @url = data['url']
37
+ @proxy_url = data['proxy_url']
38
+ @filename = data['filename']
39
+
40
+ @size = data['size']
41
+
42
+ @width = data['width']
43
+ @height = data['height']
44
+ end
45
+
46
+ # @return [true, false] whether this file is an image file.
47
+ def image?
48
+ !(@width.nil? || @height.nil?)
49
+ end
50
+
51
+ # @return [true, false] whether this file is tagged as a spoiler.
52
+ def spoiler?
53
+ @filename.start_with? 'SPOILER_'
54
+ end
55
+ end
56
+ end