discordrb 3.3.0 → 3.4.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +126 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +39 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +25 -0
- data/.github/pull_request_template.md +37 -0
- data/.rubocop.yml +34 -37
- data/.travis.yml +5 -6
- data/CHANGELOG.md +504 -347
- data/Gemfile +2 -0
- data/LICENSE.txt +1 -1
- data/README.md +61 -79
- data/Rakefile +2 -0
- data/bin/console +1 -0
- data/discordrb-webhooks.gemspec +6 -6
- data/discordrb.gemspec +18 -18
- data/lib/discordrb/allowed_mentions.rb +36 -0
- data/lib/discordrb/api/channel.rb +62 -39
- data/lib/discordrb/api/invite.rb +3 -3
- data/lib/discordrb/api/server.rb +57 -50
- data/lib/discordrb/api/user.rb +9 -8
- data/lib/discordrb/api/webhook.rb +6 -6
- data/lib/discordrb/api.rb +40 -15
- data/lib/discordrb/await.rb +0 -1
- data/lib/discordrb/bot.rb +175 -73
- data/lib/discordrb/cache.rb +4 -2
- data/lib/discordrb/colour_rgb.rb +43 -0
- data/lib/discordrb/commands/command_bot.rb +30 -9
- data/lib/discordrb/commands/container.rb +20 -23
- data/lib/discordrb/commands/parser.rb +18 -18
- data/lib/discordrb/commands/rate_limiter.rb +3 -2
- data/lib/discordrb/container.rb +77 -17
- data/lib/discordrb/data/activity.rb +271 -0
- data/lib/discordrb/data/application.rb +50 -0
- data/lib/discordrb/data/attachment.rb +56 -0
- data/lib/discordrb/data/audit_logs.rb +345 -0
- data/lib/discordrb/data/channel.rb +849 -0
- data/lib/discordrb/data/embed.rb +251 -0
- data/lib/discordrb/data/emoji.rb +82 -0
- data/lib/discordrb/data/integration.rb +83 -0
- data/lib/discordrb/data/invite.rb +137 -0
- data/lib/discordrb/data/member.rb +297 -0
- data/lib/discordrb/data/message.rb +334 -0
- data/lib/discordrb/data/overwrite.rb +102 -0
- data/lib/discordrb/data/profile.rb +91 -0
- data/lib/discordrb/data/reaction.rb +33 -0
- data/lib/discordrb/data/recipient.rb +34 -0
- data/lib/discordrb/data/role.rb +191 -0
- data/lib/discordrb/data/server.rb +1002 -0
- data/lib/discordrb/data/user.rb +204 -0
- data/lib/discordrb/data/voice_region.rb +45 -0
- data/lib/discordrb/data/voice_state.rb +41 -0
- data/lib/discordrb/data/webhook.rb +145 -0
- data/lib/discordrb/data.rb +25 -4180
- data/lib/discordrb/errors.rb +2 -1
- data/lib/discordrb/events/bans.rb +7 -5
- data/lib/discordrb/events/channels.rb +2 -0
- data/lib/discordrb/events/guilds.rb +16 -9
- data/lib/discordrb/events/invites.rb +125 -0
- data/lib/discordrb/events/members.rb +6 -2
- data/lib/discordrb/events/message.rb +69 -27
- data/lib/discordrb/events/presence.rb +14 -4
- data/lib/discordrb/events/raw.rb +1 -3
- data/lib/discordrb/events/reactions.rb +49 -3
- data/lib/discordrb/events/typing.rb +6 -4
- data/lib/discordrb/events/voice_server_update.rb +47 -0
- data/lib/discordrb/events/voice_state_update.rb +15 -10
- data/lib/discordrb/events/webhooks.rb +9 -6
- data/lib/discordrb/gateway.rb +72 -57
- data/lib/discordrb/id_object.rb +39 -0
- data/lib/discordrb/light/integrations.rb +1 -1
- data/lib/discordrb/light/light_bot.rb +1 -1
- data/lib/discordrb/logger.rb +4 -4
- data/lib/discordrb/paginator.rb +57 -0
- data/lib/discordrb/permissions.rb +103 -8
- data/lib/discordrb/version.rb +1 -1
- data/lib/discordrb/voice/encoder.rb +16 -7
- data/lib/discordrb/voice/network.rb +84 -43
- data/lib/discordrb/voice/sodium.rb +96 -0
- data/lib/discordrb/voice/voice_bot.rb +34 -26
- data/lib/discordrb.rb +73 -0
- metadata +98 -60
- /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
|