discordrb 3.1.1 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of discordrb might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/.circleci/config.yml +126 -0
- data/.codeclimate.yml +16 -0
- data/.github/CONTRIBUTING.md +13 -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/.gitignore +5 -0
- data/.rubocop.yml +39 -33
- data/.travis.yml +27 -2
- data/.yardopts +1 -1
- data/CHANGELOG.md +808 -208
- data/Gemfile +4 -1
- data/LICENSE.txt +1 -1
- data/README.md +108 -53
- data/Rakefile +14 -1
- data/bin/console +1 -0
- data/bin/travis_build_docs.sh +17 -0
- data/discordrb-webhooks.gemspec +26 -0
- data/discordrb.gemspec +24 -15
- data/lib/discordrb.rb +75 -2
- data/lib/discordrb/allowed_mentions.rb +36 -0
- data/lib/discordrb/api.rb +126 -27
- data/lib/discordrb/api/channel.rb +165 -43
- data/lib/discordrb/api/invite.rb +10 -7
- data/lib/discordrb/api/server.rb +240 -61
- data/lib/discordrb/api/user.rb +26 -24
- data/lib/discordrb/api/webhook.rb +83 -0
- data/lib/discordrb/await.rb +1 -2
- data/lib/discordrb/bot.rb +417 -149
- data/lib/discordrb/cache.rb +42 -10
- data/lib/discordrb/colour_rgb.rb +43 -0
- data/lib/discordrb/commands/command_bot.rb +186 -31
- data/lib/discordrb/commands/container.rb +30 -16
- data/lib/discordrb/commands/parser.rb +102 -47
- data/lib/discordrb/commands/rate_limiter.rb +18 -17
- data/lib/discordrb/container.rb +245 -41
- data/lib/discordrb/data.rb +27 -2511
- data/lib/discordrb/data/activity.rb +264 -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/errors.rb +36 -2
- data/lib/discordrb/events/bans.rb +7 -5
- data/lib/discordrb/events/channels.rb +2 -0
- data/lib/discordrb/events/generic.rb +19 -3
- data/lib/discordrb/events/guilds.rb +129 -6
- data/lib/discordrb/events/invites.rb +125 -0
- data/lib/discordrb/events/members.rb +6 -2
- data/lib/discordrb/events/message.rb +86 -36
- data/lib/discordrb/events/presence.rb +23 -16
- data/lib/discordrb/events/raw.rb +47 -0
- data/lib/discordrb/events/reactions.rb +159 -0
- data/lib/discordrb/events/roles.rb +7 -6
- data/lib/discordrb/events/typing.rb +9 -5
- data/lib/discordrb/events/voice_server_update.rb +47 -0
- data/lib/discordrb/events/voice_state_update.rb +29 -9
- data/lib/discordrb/events/webhooks.rb +64 -0
- data/lib/discordrb/gateway.rb +219 -88
- data/lib/discordrb/id_object.rb +39 -0
- data/lib/discordrb/light.rb +1 -1
- data/lib/discordrb/light/integrations.rb +1 -1
- data/lib/discordrb/light/light_bot.rb +1 -1
- data/lib/discordrb/logger.rb +12 -11
- data/lib/discordrb/paginator.rb +57 -0
- data/lib/discordrb/permissions.rb +148 -14
- data/lib/discordrb/version.rb +1 -1
- data/lib/discordrb/voice/encoder.rb +14 -15
- data/lib/discordrb/voice/network.rb +86 -45
- data/lib/discordrb/voice/sodium.rb +96 -0
- data/lib/discordrb/voice/voice_bot.rb +52 -40
- data/lib/discordrb/webhooks.rb +12 -0
- data/lib/discordrb/websocket.rb +2 -2
- metadata +137 -34
@@ -0,0 +1,251 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Discordrb
|
4
|
+
# An Embed object that is contained in a message
|
5
|
+
# A freshly generated embed object will not appear in a message object
|
6
|
+
# unless grabbed from its ID in a channel.
|
7
|
+
class Embed
|
8
|
+
# @return [Message] the message this embed object is contained in.
|
9
|
+
attr_reader :message
|
10
|
+
|
11
|
+
# @return [String] the URL this embed object is based on.
|
12
|
+
attr_reader :url
|
13
|
+
|
14
|
+
# @return [String, nil] the title of the embed object. `nil` if there is not a title
|
15
|
+
attr_reader :title
|
16
|
+
|
17
|
+
# @return [String, nil] the description of the embed object. `nil` if there is not a description
|
18
|
+
attr_reader :description
|
19
|
+
|
20
|
+
# @return [Symbol] the type of the embed object. Possible types are:
|
21
|
+
#
|
22
|
+
# * `:link`
|
23
|
+
# * `:video`
|
24
|
+
# * `:image`
|
25
|
+
attr_reader :type
|
26
|
+
|
27
|
+
# @return [Time, nil] the timestamp of the embed object. `nil` if there is not a timestamp
|
28
|
+
attr_reader :timestamp
|
29
|
+
|
30
|
+
# @return [String, nil] the color of the embed object. `nil` if there is not a color
|
31
|
+
attr_reader :color
|
32
|
+
alias_method :colour, :color
|
33
|
+
|
34
|
+
# @return [EmbedFooter, nil] the footer of the embed object. `nil` if there is not a footer
|
35
|
+
attr_reader :footer
|
36
|
+
|
37
|
+
# @return [EmbedProvider, nil] the provider of the embed object. `nil` if there is not a provider
|
38
|
+
attr_reader :provider
|
39
|
+
|
40
|
+
# @return [EmbedImage, nil] the image of the embed object. `nil` if there is not an image
|
41
|
+
attr_reader :image
|
42
|
+
|
43
|
+
# @return [EmbedThumbnail, nil] the thumbnail of the embed object. `nil` if there is not a thumbnail
|
44
|
+
attr_reader :thumbnail
|
45
|
+
|
46
|
+
# @return [EmbedVideo, nil] the video of the embed object. `nil` if there is not a video
|
47
|
+
attr_reader :video
|
48
|
+
|
49
|
+
# @return [EmbedAuthor, nil] the author of the embed object. `nil` if there is not an author
|
50
|
+
attr_reader :author
|
51
|
+
|
52
|
+
# @return [Array<EmbedField>, nil] the fields of the embed object. `nil` if there are no fields
|
53
|
+
attr_reader :fields
|
54
|
+
|
55
|
+
# @!visibility private
|
56
|
+
def initialize(data, message)
|
57
|
+
@message = message
|
58
|
+
|
59
|
+
@url = data['url']
|
60
|
+
@title = data['title']
|
61
|
+
@type = data['type'].to_sym
|
62
|
+
@description = data['description']
|
63
|
+
@timestamp = data['timestamp'].nil? ? nil : Time.parse(data['timestamp'])
|
64
|
+
@color = data['color']
|
65
|
+
@footer = data['footer'].nil? ? nil : EmbedFooter.new(data['footer'], self)
|
66
|
+
@image = data['image'].nil? ? nil : EmbedImage.new(data['image'], self)
|
67
|
+
@video = data['video'].nil? ? nil : EmbedVideo.new(data['video'], self)
|
68
|
+
@provider = data['provider'].nil? ? nil : EmbedProvider.new(data['provider'], self)
|
69
|
+
@thumbnail = data['thumbnail'].nil? ? nil : EmbedThumbnail.new(data['thumbnail'], self)
|
70
|
+
@author = data['author'].nil? ? nil : EmbedAuthor.new(data['author'], self)
|
71
|
+
@fields = data['fields'].nil? ? nil : data['fields'].map { |field| EmbedField.new(field, self) }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# An Embed footer for the embed object.
|
76
|
+
class EmbedFooter
|
77
|
+
# @return [Embed] the embed object this is based on.
|
78
|
+
attr_reader :embed
|
79
|
+
|
80
|
+
# @return [String] the footer text.
|
81
|
+
attr_reader :text
|
82
|
+
|
83
|
+
# @return [String] the URL of the footer icon.
|
84
|
+
attr_reader :icon_url
|
85
|
+
|
86
|
+
# @return [String] the proxied URL of the footer icon.
|
87
|
+
attr_reader :proxy_icon_url
|
88
|
+
|
89
|
+
# @!visibility private
|
90
|
+
def initialize(data, embed)
|
91
|
+
@embed = embed
|
92
|
+
|
93
|
+
@text = data['text']
|
94
|
+
@icon_url = data['icon_url']
|
95
|
+
@proxy_icon_url = data['proxy_icon_url']
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# An Embed image for the embed object.
|
100
|
+
class EmbedImage
|
101
|
+
# @return [Embed] the embed object this is based on.
|
102
|
+
attr_reader :embed
|
103
|
+
|
104
|
+
# @return [String] the source URL of the image.
|
105
|
+
attr_reader :url
|
106
|
+
|
107
|
+
# @return [String] the proxy URL of the image.
|
108
|
+
attr_reader :proxy_url
|
109
|
+
|
110
|
+
# @return [Integer] the width of the image, in pixels.
|
111
|
+
attr_reader :width
|
112
|
+
|
113
|
+
# @return [Integer] the height of the image, in pixels.
|
114
|
+
attr_reader :height
|
115
|
+
|
116
|
+
# @!visibility private
|
117
|
+
def initialize(data, embed)
|
118
|
+
@embed = embed
|
119
|
+
|
120
|
+
@url = data['url']
|
121
|
+
@proxy_url = data['proxy_url']
|
122
|
+
@width = data['width']
|
123
|
+
@height = data['height']
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# An Embed video for the embed object
|
128
|
+
class EmbedVideo
|
129
|
+
# @return [Embed] the embed object this is based on.
|
130
|
+
attr_reader :embed
|
131
|
+
|
132
|
+
# @return [String] the source URL of the video.
|
133
|
+
attr_reader :url
|
134
|
+
|
135
|
+
# @return [Integer] the width of the video, in pixels.
|
136
|
+
attr_reader :width
|
137
|
+
|
138
|
+
# @return [Integer] the height of the video, in pixels.
|
139
|
+
attr_reader :height
|
140
|
+
|
141
|
+
# @!visibility private
|
142
|
+
def initialize(data, embed)
|
143
|
+
@embed = embed
|
144
|
+
|
145
|
+
@url = data['url']
|
146
|
+
@width = data['width']
|
147
|
+
@height = data['height']
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
# An Embed thumbnail for the embed object
|
152
|
+
class EmbedThumbnail
|
153
|
+
# @return [Embed] the embed object this is based on.
|
154
|
+
attr_reader :embed
|
155
|
+
|
156
|
+
# @return [String] the CDN URL this thumbnail can be downloaded at.
|
157
|
+
attr_reader :url
|
158
|
+
|
159
|
+
# @return [String] the thumbnail's proxy URL - I'm not sure what exactly this does, but I think it has something to
|
160
|
+
# do with CDNs.
|
161
|
+
attr_reader :proxy_url
|
162
|
+
|
163
|
+
# @return [Integer] the width of this thumbnail file, in pixels.
|
164
|
+
attr_reader :width
|
165
|
+
|
166
|
+
# @return [Integer] the height of this thumbnail file, in pixels.
|
167
|
+
attr_reader :height
|
168
|
+
|
169
|
+
# @!visibility private
|
170
|
+
def initialize(data, embed)
|
171
|
+
@embed = embed
|
172
|
+
|
173
|
+
@url = data['url']
|
174
|
+
@proxy_url = data['proxy_url']
|
175
|
+
@width = data['width']
|
176
|
+
@height = data['height']
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
# An Embed provider for the embed object
|
181
|
+
class EmbedProvider
|
182
|
+
# @return [Embed] the embed object this is based on.
|
183
|
+
attr_reader :embed
|
184
|
+
|
185
|
+
# @return [String] the provider's name.
|
186
|
+
attr_reader :name
|
187
|
+
|
188
|
+
# @return [String, nil] the URL of the provider, or `nil` if there is no URL.
|
189
|
+
attr_reader :url
|
190
|
+
|
191
|
+
# @!visibility private
|
192
|
+
def initialize(data, embed)
|
193
|
+
@embed = embed
|
194
|
+
|
195
|
+
@name = data['name']
|
196
|
+
@url = data['url']
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
# An Embed author for the embed object
|
201
|
+
class EmbedAuthor
|
202
|
+
# @return [Embed] the embed object this is based on.
|
203
|
+
attr_reader :embed
|
204
|
+
|
205
|
+
# @return [String] the author's name.
|
206
|
+
attr_reader :name
|
207
|
+
|
208
|
+
# @return [String, nil] the URL of the author's website, or `nil` if there is no URL.
|
209
|
+
attr_reader :url
|
210
|
+
|
211
|
+
# @return [String, nil] the icon of the author, or `nil` if there is no icon.
|
212
|
+
attr_reader :icon_url
|
213
|
+
|
214
|
+
# @return [String, nil] the Discord proxy URL, or `nil` if there is no `icon_url`.
|
215
|
+
attr_reader :proxy_icon_url
|
216
|
+
|
217
|
+
# @!visibility private
|
218
|
+
def initialize(data, embed)
|
219
|
+
@embed = embed
|
220
|
+
|
221
|
+
@name = data['name']
|
222
|
+
@url = data['url']
|
223
|
+
@icon_url = data['icon_url']
|
224
|
+
@proxy_icon_url = data['proxy_icon_url']
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# An Embed field for the embed object
|
229
|
+
class EmbedField
|
230
|
+
# @return [Embed] the embed object this is based on.
|
231
|
+
attr_reader :embed
|
232
|
+
|
233
|
+
# @return [String] the field's name.
|
234
|
+
attr_reader :name
|
235
|
+
|
236
|
+
# @return [String] the field's value.
|
237
|
+
attr_reader :value
|
238
|
+
|
239
|
+
# @return [true, false] whether this field is inline.
|
240
|
+
attr_reader :inline
|
241
|
+
|
242
|
+
# @!visibility private
|
243
|
+
def initialize(data, embed)
|
244
|
+
@embed = embed
|
245
|
+
|
246
|
+
@name = data['name']
|
247
|
+
@value = data['value']
|
248
|
+
@inline = data['inline']
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Discordrb
|
4
|
+
# Server emoji
|
5
|
+
class Emoji
|
6
|
+
include IDObject
|
7
|
+
|
8
|
+
# @return [String] the emoji name
|
9
|
+
attr_reader :name
|
10
|
+
|
11
|
+
# @return [Server, nil] the server of this emoji
|
12
|
+
attr_reader :server
|
13
|
+
|
14
|
+
# @return [Array<Role>, nil] roles this emoji is active for, or nil if the emoji's server is unknown
|
15
|
+
attr_reader :roles
|
16
|
+
|
17
|
+
# @return [true, false] if the emoji is animated
|
18
|
+
attr_reader :animated
|
19
|
+
alias_method :animated?, :animated
|
20
|
+
|
21
|
+
# @!visibility private
|
22
|
+
def initialize(data, bot, server = nil)
|
23
|
+
@bot = bot
|
24
|
+
@roles = nil
|
25
|
+
|
26
|
+
@name = data['name']
|
27
|
+
@server = server
|
28
|
+
@id = data['id'].nil? ? nil : data['id'].to_i
|
29
|
+
@animated = data['animated']
|
30
|
+
|
31
|
+
process_roles(data['roles']) if server
|
32
|
+
end
|
33
|
+
|
34
|
+
# ID or name based comparison
|
35
|
+
def ==(other)
|
36
|
+
return false unless other.is_a? Emoji
|
37
|
+
return Discordrb.id_compare(@id, other) if @id
|
38
|
+
|
39
|
+
name == other.name
|
40
|
+
end
|
41
|
+
|
42
|
+
alias_method :eql?, :==
|
43
|
+
|
44
|
+
# @return [String] the layout to mention it (or have it used) in a message
|
45
|
+
def mention
|
46
|
+
return name if id.nil?
|
47
|
+
|
48
|
+
"<#{'a' if animated}:#{name}:#{id}>"
|
49
|
+
end
|
50
|
+
|
51
|
+
alias_method :use, :mention
|
52
|
+
alias_method :to_s, :mention
|
53
|
+
|
54
|
+
# @return [String] the layout to use this emoji in a reaction
|
55
|
+
def to_reaction
|
56
|
+
return name if id.nil?
|
57
|
+
|
58
|
+
"#{name}:#{id}"
|
59
|
+
end
|
60
|
+
|
61
|
+
# @return [String] the icon URL of the emoji
|
62
|
+
def icon_url
|
63
|
+
API.emoji_icon_url(id)
|
64
|
+
end
|
65
|
+
|
66
|
+
# The inspect method is overwritten to give more useful output
|
67
|
+
def inspect
|
68
|
+
"<Emoji name=#{name} id=#{id} animated=#{animated}>"
|
69
|
+
end
|
70
|
+
|
71
|
+
# @!visibility private
|
72
|
+
def process_roles(roles)
|
73
|
+
@roles = []
|
74
|
+
return unless roles
|
75
|
+
|
76
|
+
roles.each do |role_id|
|
77
|
+
role = server.role(role_id)
|
78
|
+
@roles << role
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Discordrb
|
4
|
+
# Integration Account
|
5
|
+
class IntegrationAccount
|
6
|
+
# @return [String] this account's name.
|
7
|
+
attr_reader :name
|
8
|
+
|
9
|
+
# @return [Integer] this account's ID.
|
10
|
+
attr_reader :id
|
11
|
+
|
12
|
+
def initialize(data)
|
13
|
+
@name = data['name']
|
14
|
+
@id = data['id'].to_i
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Server integration
|
19
|
+
class Integration
|
20
|
+
include IDObject
|
21
|
+
|
22
|
+
# @return [String] the integration name
|
23
|
+
attr_reader :name
|
24
|
+
|
25
|
+
# @return [Server] the server the integration is linked to
|
26
|
+
attr_reader :server
|
27
|
+
|
28
|
+
# @return [User] the user the integration is linked to
|
29
|
+
attr_reader :user
|
30
|
+
|
31
|
+
# @return [Role, nil] the role that this integration uses for "subscribers"
|
32
|
+
attr_reader :role
|
33
|
+
|
34
|
+
# @return [true, false] whether emoticons are enabled
|
35
|
+
attr_reader :emoticon
|
36
|
+
alias_method :emoticon?, :emoticon
|
37
|
+
|
38
|
+
# @return [String] the integration type (YouTube, Twitch, etc.)
|
39
|
+
attr_reader :type
|
40
|
+
|
41
|
+
# @return [true, false] whether the integration is enabled
|
42
|
+
attr_reader :enabled
|
43
|
+
|
44
|
+
# @return [true, false] whether the integration is syncing
|
45
|
+
attr_reader :syncing
|
46
|
+
|
47
|
+
# @return [IntegrationAccount] the integration account information
|
48
|
+
attr_reader :account
|
49
|
+
|
50
|
+
# @return [Time] the time the integration was synced at
|
51
|
+
attr_reader :synced_at
|
52
|
+
|
53
|
+
# @return [Symbol] the behaviour of expiring subscribers (:remove = Remove User from role; :kick = Kick User from server)
|
54
|
+
attr_reader :expire_behaviour
|
55
|
+
alias_method :expire_behavior, :expire_behaviour
|
56
|
+
|
57
|
+
# @return [Integer] the grace period before subscribers expire (in days)
|
58
|
+
attr_reader :expire_grace_period
|
59
|
+
|
60
|
+
def initialize(data, bot, server)
|
61
|
+
@bot = bot
|
62
|
+
|
63
|
+
@name = data['name']
|
64
|
+
@server = server
|
65
|
+
@id = data['id'].to_i
|
66
|
+
@enabled = data['enabled']
|
67
|
+
@syncing = data['syncing']
|
68
|
+
@type = data['type']
|
69
|
+
@account = IntegrationAccount.new(data['account'])
|
70
|
+
@synced_at = Time.parse(data['synced_at'])
|
71
|
+
@expire_behaviour = %i[remove kick][data['expire_behavior']]
|
72
|
+
@expire_grace_period = data['expire_grace_period']
|
73
|
+
@user = @bot.ensure_user(data['user'])
|
74
|
+
@role = server.role(data['role_id']) || nil
|
75
|
+
@emoticon = data['enable_emoticons']
|
76
|
+
end
|
77
|
+
|
78
|
+
# The inspect method is overwritten to give more useful output
|
79
|
+
def inspect
|
80
|
+
"<Integration name=#{@name} id=#{@id} type=#{@type} enabled=#{@enabled}>"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Discordrb
|
4
|
+
# A channel referenced by an invite. It has less data than regular channels, so it's a separate class
|
5
|
+
class InviteChannel
|
6
|
+
include IDObject
|
7
|
+
|
8
|
+
# @return [String] this channel's name.
|
9
|
+
attr_reader :name
|
10
|
+
|
11
|
+
# @return [Integer] this channel's type (0: text, 1: private, 2: voice, 3: group).
|
12
|
+
attr_reader :type
|
13
|
+
|
14
|
+
# @!visibility private
|
15
|
+
def initialize(data, bot)
|
16
|
+
@bot = bot
|
17
|
+
|
18
|
+
@id = data['id'].to_i
|
19
|
+
@name = data['name']
|
20
|
+
@type = data['type']
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# A server referenced to by an invite
|
25
|
+
class InviteServer
|
26
|
+
include IDObject
|
27
|
+
|
28
|
+
# @return [String] this server's name.
|
29
|
+
attr_reader :name
|
30
|
+
|
31
|
+
# @return [String, nil] the hash of the server's invite splash screen (for partnered servers) or nil if none is
|
32
|
+
# present
|
33
|
+
attr_reader :splash_hash
|
34
|
+
|
35
|
+
# @!visibility private
|
36
|
+
def initialize(data, bot)
|
37
|
+
@bot = bot
|
38
|
+
|
39
|
+
@id = data['id'].to_i
|
40
|
+
@name = data['name']
|
41
|
+
@splash_hash = data['splash_hash']
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# A Discord invite to a channel
|
46
|
+
class Invite
|
47
|
+
# @return [InviteChannel, Channel] the channel this invite references.
|
48
|
+
attr_reader :channel
|
49
|
+
|
50
|
+
# @return [InviteServer, Server] the server this invite references.
|
51
|
+
attr_reader :server
|
52
|
+
|
53
|
+
# @return [Integer] the amount of uses left on this invite.
|
54
|
+
attr_reader :uses
|
55
|
+
alias_method :max_uses, :uses
|
56
|
+
|
57
|
+
# @return [User, nil] the user that made this invite. May also be nil if the user can't be determined.
|
58
|
+
attr_reader :inviter
|
59
|
+
alias_method :user, :inviter
|
60
|
+
|
61
|
+
# @return [true, false] whether or not this invite grants temporary membership. If someone joins a server with this invite, they will be removed from the server when they go offline unless they've received a role.
|
62
|
+
attr_reader :temporary
|
63
|
+
alias_method :temporary?, :temporary
|
64
|
+
|
65
|
+
# @return [true, false] whether this invite is still valid.
|
66
|
+
attr_reader :revoked
|
67
|
+
alias_method :revoked?, :revoked
|
68
|
+
|
69
|
+
# @return [String] this invite's code
|
70
|
+
attr_reader :code
|
71
|
+
|
72
|
+
# @return [Integer, nil] the amount of members in the server. Will be nil if it has not been resolved.
|
73
|
+
attr_reader :member_count
|
74
|
+
alias_method :user_count, :member_count
|
75
|
+
|
76
|
+
# @return [Integer, nil] the amount of online members in the server. Will be nil if it has not been resolved.
|
77
|
+
attr_reader :online_member_count
|
78
|
+
alias_method :online_user_count, :online_member_count
|
79
|
+
|
80
|
+
# @return [Integer, nil] the invites max age before it expires, or nil if it's unknown. If the max age is 0, the invite will never expire unless it's deleted.
|
81
|
+
attr_reader :max_age
|
82
|
+
|
83
|
+
# @return [Time, nil] when this invite was created, or nil if it's unknown
|
84
|
+
attr_reader :created_at
|
85
|
+
|
86
|
+
# @!visibility private
|
87
|
+
def initialize(data, bot)
|
88
|
+
@bot = bot
|
89
|
+
|
90
|
+
@channel = if data['channel_id'] || bot.channel
|
91
|
+
bot.channel(data['channel_id'])
|
92
|
+
else
|
93
|
+
InviteChannel.new(data['channel'], bot)
|
94
|
+
end
|
95
|
+
|
96
|
+
@server = if data['guild_id']
|
97
|
+
bot.server(data['guild_id'])
|
98
|
+
else
|
99
|
+
InviteServer.new(data['guild'], bot)
|
100
|
+
end
|
101
|
+
|
102
|
+
@uses = data['uses']
|
103
|
+
@inviter = data['inviter'] ? (@bot.user(data['inviter']['id'].to_i) || User.new(data['inviter'], bot)) : nil
|
104
|
+
@temporary = data['temporary']
|
105
|
+
@revoked = data['revoked']
|
106
|
+
@online_member_count = data['approximate_presence_count']
|
107
|
+
@member_count = data['approximate_member_count']
|
108
|
+
@max_age = data['max_age']
|
109
|
+
@created_at = data['created_at']
|
110
|
+
|
111
|
+
@code = data['code']
|
112
|
+
end
|
113
|
+
|
114
|
+
# Code based comparison
|
115
|
+
def ==(other)
|
116
|
+
other.respond_to?(:code) ? (@code == other.code) : (@code == other)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Deletes this invite
|
120
|
+
# @param reason [String] The reason the invite is being deleted.
|
121
|
+
def delete(reason = nil)
|
122
|
+
API::Invite.delete(@bot.token, @code, reason)
|
123
|
+
end
|
124
|
+
|
125
|
+
alias_method :revoke, :delete
|
126
|
+
|
127
|
+
# The inspect method is overwritten to give more useful output
|
128
|
+
def inspect
|
129
|
+
"<Invite code=#{@code} channel=#{@channel} uses=#{@uses} temporary=#{@temporary} revoked=#{@revoked} created_at=#{@created_at} max_age=#{@max_age}>"
|
130
|
+
end
|
131
|
+
|
132
|
+
# Creates an invite URL.
|
133
|
+
def url
|
134
|
+
"https://discord.gg/#{@code}"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|