Class: Discordrb::Server

Inherits:
Object
  • Object
show all
Includes:
IDObject, ServerAttributes
Defined in:
lib/discordrb/data/server.rb

Overview

A server on Discord

Constant Summary collapse

VERIFICATION_LEVELS =

A map of possible server verification levels to symbol names

{
  none: 0,
  low: 1,
  medium: 2,
  high: 3,
  very_high: 4
}.freeze
NOTIFICATION_LEVELS =

A map of possible message notification levels to symbol names

{
  all_messages: 0,
  only_mentions: 1
}.freeze
FILTER_LEVELS =

A map of possible content filter levels to symbol names

{
  disabled: 0,
  members_without_roles: 1,
  all_members: 2
}.freeze

Instance Attribute Summary collapse

Attributes included from ServerAttributes

#icon_id, #name

Attributes included from IDObject

#id

Instance Method Summary collapse

Methods included from ServerAttributes

#icon_url

Methods included from IDObject

#==, #creation_time, synthesise

Instance Attribute Details

#afk_timeoutInteger



51
52
53
# File 'lib/discordrb/data/server.rb', line 51

def afk_timeout
  @afk_timeout
end

#boost_levelInteger (readonly)

The server's Nitro boost level.



62
63
64
# File 'lib/discordrb/data/server.rb', line 62

def boost_level
  @boost_level
end

#booster_countInteger (readonly)

The server's amount of Nitro boosters.



58
59
60
# File 'lib/discordrb/data/server.rb', line 58

def booster_count
  @booster_count
end

#channelsArray<Channel> (readonly)



30
31
32
# File 'lib/discordrb/data/server.rb', line 30

def channels
  @channels
end

#emojiHash<Integer => Emoji> (readonly) Also known as: emojis



36
37
38
# File 'lib/discordrb/data/server.rb', line 36

def emoji
  @emoji
end

#featuresArray<Symbol> (readonly)



45
46
47
# File 'lib/discordrb/data/server.rb', line 45

def features
  @features
end

#largetrue, false (readonly) Also known as: large?

it means the members list may be inaccurate for a couple seconds after starting up the bot.



41
42
43
# File 'lib/discordrb/data/server.rb', line 41

def large
  @large
end

#member_countInteger (readonly)



48
49
50
# File 'lib/discordrb/data/server.rb', line 48

def member_count
  @member_count
end

#region_idString (readonly)



27
28
29
# File 'lib/discordrb/data/server.rb', line 27

def region_id
  @region_id
end

#rolesArray<Role> (readonly)



33
34
35
# File 'lib/discordrb/data/server.rb', line 33

def roles
  @roles
end

#voice_statesHash<Integer => VoiceState> (readonly)



54
55
56
# File 'lib/discordrb/data/server.rb', line 54

def voice_states
  @voice_states
end

Instance Method Details

#add_emoji(name, image, roles = [], reason: nil) ⇒ Emoji

Adds a new custom emoji on this server.



541
542
543
544
545
546
547
548
549
550
551
# File 'lib/discordrb/data/server.rb', line 541

def add_emoji(name, image, roles = [], reason: nil)
  image_string = image
  if image.respond_to? :read
    image_string = 'data:image/jpg;base64,'
    image_string += Base64.strict_encode64(image.read)
  end

  data = JSON.parse(API::Server.add_emoji(@bot.token, @id, image_string, name, roles.map(&:resolve_id), reason))
  new_emoji = Emoji.new(data, @bot, self)
  @emoji[new_emoji.id] = new_emoji
end

#add_member_using_token(user, access_token, nick: nil, roles: [], deaf: false, mute: false) ⇒ Member?

Note:

Your bot must be present in this server, and have permission to create instant invites for this to work.

Adds a member to this guild that has granted this bot's application an OAuth2 access token with the guilds.join scope. For more information about Discord's OAuth2 implementation, see: https://discord.com/developers/docs/topics/oauth2



274
275
276
277
278
279
280
281
# File 'lib/discordrb/data/server.rb', line 274

def add_member_using_token(user, access_token, nick: nil, roles: [], deaf: false, mute: false)
  user_id = user.resolve_id
  roles = roles.is_a?(Array) ? roles.map(&:resolve_id) : [roles.resolve_id]
  response = API::Server.add_member(@bot.token, @id, user_id, access_token, nick, roles, deaf, mute)
  return nil if response.empty?

  add_member Member.new(JSON.parse(response), self, @bot)
end

#afk_channelChannel?



808
809
810
# File 'lib/discordrb/data/server.rb', line 808

def afk_channel
  @bot.channel(@afk_channel_id) if @afk_channel_id
end

#afk_channel=(afk_channel) ⇒ Object

Sets the server's AFK channel.



683
684
685
# File 'lib/discordrb/data/server.rb', line 683

def afk_channel=(afk_channel)
  update_server_data(afk_channel_id: afk_channel.resolve_id)
end

#any_emoji?true, false Also known as: has_emoji?, emoji?



771
772
773
# File 'lib/discordrb/data/server.rb', line 771

def any_emoji?
  @emoji.any?
end

#audit_logs(action: nil, user: nil, limit: 50, before: nil) ⇒ AuditLogs



175
176
177
178
179
180
181
182
# File 'lib/discordrb/data/server.rb', line 175

def audit_logs(action: nil, user: nil, limit: 50, before: nil)
  raise 'Invalid audit log action!' if action && AuditLogs::ACTIONS.key(action).nil?

  action = AuditLogs::ACTIONS.key(action)
  user = user.resolve_id if user
  before = before.resolve_id if before
  AuditLogs.new(self, @bot, JSON.parse(API::Server.audit_logs(@bot.token, @id, limit, user, action, before)))
end

#available_voice_regionsArray<VoiceRegion>



648
649
650
651
652
653
654
655
# File 'lib/discordrb/data/server.rb', line 648

def available_voice_regions
  return @available_voice_regions if @available_voice_regions

  @available_voice_regions = {}

  data = JSON.parse API::Server.regions(@bot.token, @id)
  @available_voice_regions = data.map { |e| VoiceRegion.new e }
end

#ban(user, message_days = 0, reason: nil) ⇒ Object

Bans a user from this server.



600
601
602
# File 'lib/discordrb/data/server.rb', line 600

def ban(user, message_days = 0, reason: nil)
  API::Server.ban_user(@bot.token, @id, user.resolve_id, message_days, reason)
end


368
369
370
# File 'lib/discordrb/data/server.rb', line 368

def banner_id
  @banner_id ||= JSON.parse(API::Server.resolve(@bot.token, @id))['banner']
end


374
375
376
377
378
379
# File 'lib/discordrb/data/server.rb', line 374

def banner_url
  banner_id if @banner_id.nil?
  return unless banner_id

  API.banner_url(@id, @banner_id)
end

#bansArray<ServerBan>



589
590
591
592
593
594
# File 'lib/discordrb/data/server.rb', line 589

def bans
  response = JSON.parse(API::Server.bans(@bot.token, @id))
  response.map do |e|
    ServerBan.new(self, User.new(e['user'], @bot), e['reason'])
  end
end

#begin_prune(days, reason = nil) ⇒ Integer Also known as: prune

Prunes (kicks) an amount of members for inactivity

Raises:

  • (ArgumentError)

    if days is not between 1 and 30 (inclusive)



299
300
301
302
303
304
# File 'lib/discordrb/data/server.rb', line 299

def begin_prune(days, reason = nil)
  raise ArgumentError, 'Days must be between 1 and 30' unless days.between?(1, 30)

  response = JSON.parse API::Server.begin_prune(@bot.token, @id, days, reason)
  response['pruned']
end

#botMember



160
161
162
# File 'lib/discordrb/data/server.rb', line 160

def bot
  member(@bot.profile)
end

#bot_membersArray<Member>



150
151
152
# File 'lib/discordrb/data/server.rb', line 150

def bot_members
  members.select(&:bot_account?)
end

#categoriesArray<Channel>



319
320
321
# File 'lib/discordrb/data/server.rb', line 319

def categories
  @channels.select(&:category?)
end

#create_channel(name, type = 0, topic: nil, bitrate: nil, user_limit: nil, permission_overwrites: nil, parent: nil, nsfw: false, rate_limit_per_user: nil, position: nil, reason: nil) ⇒ Channel

Note:

If parent is provided, permission overwrites have the follow behavior:

  1. If overwrites is null, the new channel inherits the parent's permissions.
  2. If overwrites is [], the new channel inherits the parent's permissions.
  3. If you supply one or more overwrites, the channel will be created with those permissions and ignore the parents.

Creates a channel on this server with the given name.

Raises:

  • (ArgumentError)

    if type is not 0 (text), 2 (voice), 4 (category), 5 (news), or 6 (store)



497
498
499
500
501
502
503
504
505
# File 'lib/discordrb/data/server.rb', line 497

def create_channel(name, type = 0, topic: nil, bitrate: nil, user_limit: nil, permission_overwrites: nil, parent: nil, nsfw: false, rate_limit_per_user: nil, position: nil, reason: nil)
  type = Channel::TYPES[type] if type.is_a?(Symbol)
  raise ArgumentError, 'Channel type must be either 0 (text), 2 (voice), 4 (category), news (5), or store (6)!' unless [0, 2, 4, 5, 6].include?(type)

  permission_overwrites.map! { |e| e.is_a?(Overwrite) ? e.to_hash : e } if permission_overwrites.is_a?(Array)
  parent_id = parent.respond_to?(:resolve_id) ? parent.resolve_id : nil
  response = API::Server.create_channel(@bot.token, @id, name, type, topic, bitrate, user_limit, permission_overwrites, parent_id, nsfw, rate_limit_per_user, position, reason)
  Channel.new(JSON.parse(response), @bot)
end

#create_role(name: 'new role', colour: 0, hoist: false, mentionable: false, permissions: 104_324_161, reason: nil) ⇒ Role

Creates a role on this server which can then be modified. It will be initialized with the regular role defaults the client uses unless specified, i.e. name is "new role", permissions are the default, colour is the default etc.



517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
# File 'lib/discordrb/data/server.rb', line 517

def create_role(name: 'new role', colour: 0, hoist: false, mentionable: false, permissions: 104_324_161, reason: nil)
  colour = colour.respond_to?(:combined) ? colour.combined : colour

  permissions = if permissions.is_a?(Array)
                  Permissions.bits(permissions)
                elsif permissions.respond_to?(:bits)
                  permissions.bits
                else
                  permissions
                end

  response = API::Server.create_role(@bot.token, @id, name, colour, hoist, mentionable, permissions, reason)

  role = Role.new(JSON.parse(response), @bot, self)
  @roles << role
  role
end

#default_channel(send_messages = false) ⇒ Channel? Also known as: general_channel

The default channel is the text channel on this server with the highest position that the bot has Read Messages permission on.



92
93
94
95
96
97
98
99
100
101
# File 'lib/discordrb/data/server.rb', line 92

def default_channel(send_messages = false)
  bot_member = member(@bot.profile)
  text_channels.sort_by { |e| [e.position, e.id] }.find do |e|
    if send_messages
      bot_member.can_read_messages?(e) && bot_member.can_send_messages?(e)
    else
      bot_member.can_read_messages?(e)
    end
  end
end

#default_message_notificationsSymbol



728
729
730
# File 'lib/discordrb/data/server.rb', line 728

def default_message_notifications
  NOTIFICATION_LEVELS.key @default_message_notifications
end

#default_message_notifications=(notification_level) ⇒ Object Also known as: notification_level=

Sets the default message notification level



734
735
736
737
738
# File 'lib/discordrb/data/server.rb', line 734

def default_message_notifications=(notification_level)
  notification_level = NOTIFICATION_LEVELS[notification_level] if notification_level.is_a?(Symbol)

  update_server_data(default_message_notifications: notification_level)
end

#deleteObject

Deletes this server. Be aware that this is permanent and impossible to undo, so be careful!



626
627
628
# File 'lib/discordrb/data/server.rb', line 626

def delete
  API::Server.delete(@bot.token, @id)
end

#delete_emoji(emoji, reason: nil) ⇒ Object

Delete a custom emoji on this server



556
557
558
# File 'lib/discordrb/data/server.rb', line 556

def delete_emoji(emoji, reason: nil)
  API::Server.delete_emoji(@bot.token, @id, emoji.resolve_id, reason)
end

#edit_emoji(emoji, name: nil, roles: nil, reason: nil) ⇒ Emoji

Changes the name and/or role whitelist of an emoji on this server.



566
567
568
569
570
571
# File 'lib/discordrb/data/server.rb', line 566

def edit_emoji(emoji, name: nil, roles: nil, reason: nil)
  emoji = @emoji[emoji.resolve_id]
  data = JSON.parse(API::Server.edit_emoji(@bot.token, @id, emoji.resolve_id, name || emoji.name, (roles || emoji.roles).map(&:resolve_id), reason))
  new_emoji = Emoji.new(data, @bot, self)
  @emoji[new_emoji.id] = new_emoji
end

#everyone_roleRole



106
107
108
# File 'lib/discordrb/data/server.rb', line 106

def everyone_role
  role(@id)
end

#explicit_content_filterSymbol Also known as: content_filter_level



756
757
758
# File 'lib/discordrb/data/server.rb', line 756

def explicit_content_filter
  FILTER_LEVELS.key @explicit_content_filter
end

#explicit_content_filter=(filter_level) ⇒ Object

Sets the server content filter.



764
765
766
767
768
# File 'lib/discordrb/data/server.rb', line 764

def explicit_content_filter=(filter_level)
  filter_level = FILTER_LEVELS[filter_level] if filter_level.is_a?(Symbol)

  update_server_data(explicit_content_filter: filter_level)
end

#icon=(icon) ⇒ Object

Sets the server's icon.



671
672
673
674
675
676
677
678
679
# File 'lib/discordrb/data/server.rb', line 671

def icon=(icon)
  if icon.respond_to? :read
    icon_string = 'data:image/jpg;base64,'
    icon_string += Base64.strict_encode64(icon.read)
    update_server_data(icon_id: icon_string)
  else
    update_server_data(icon_id: icon)
  end
end

#inspectObject

The inspect method is overwritten to give more useful output



880
881
882
# File 'lib/discordrb/data/server.rb', line 880

def inspect
  "<Server name=#{@name} id=#{@id} large=#{@large} region=#{@region} owner=#{@owner} afk_channel_id=#{@afk_channel_id} system_channel_id=#{@system_channel_id} afk_timeout=#{@afk_timeout}>"
end

#integrationsArray<Integration>



165
166
167
168
# File 'lib/discordrb/data/server.rb', line 165

def integrations
  integration = JSON.parse(API::Server.integrations(@bot.token, @id))
  integration.map { |element| Integration.new(element, @bot, self) }
end

#invitesArray<Invite>

Requests a list of Invites to the server.



787
788
789
790
# File 'lib/discordrb/data/server.rb', line 787

def invites
  invites = JSON.parse(API::Server.invites(@bot.token, @id))
  invites.map { |invite| Invite.new(invite, @bot) }
end

#kick(user, reason = nil) ⇒ Object

Kicks a user from this server.



614
615
616
# File 'lib/discordrb/data/server.rb', line 614

def kick(user, reason = nil)
  API::Server.remove_member(@bot.token, @id, user.resolve_id, reason)
end

#leaveObject

Leave the server.



631
632
633
# File 'lib/discordrb/data/server.rb', line 631

def leave
  API::User.leave_server(@bot.token, @id)
end


382
383
384
# File 'lib/discordrb/data/server.rb', line 382

def link
  "https://discord.com/channels/#{@id}"
end

#max_emojiInteger

The amount of emoji the server can have, based on its current Nitro Boost Level.



575
576
577
578
579
580
581
582
583
584
585
586
# File 'lib/discordrb/data/server.rb', line 575

def max_emoji
  case @level
  when 1
    100
  when 2
    150
  when 3
    250
  else
    50
  end
end

#member(id, request = true) ⇒ Object

Gets a member on this server based on user ID



121
122
123
124
125
126
127
128
129
130
# File 'lib/discordrb/data/server.rb', line 121

def member(id, request = true)
  id = id.resolve_id
  return @members[id] if member_cached?(id)
  return nil unless request

  member = @bot.member(self, id)
  @members[id] = member unless member.nil?
rescue StandardError
  nil
end

#membersArray<Member> Also known as: users

Returns an array of all the members on this server.

Raises:

  • (RuntimeError)

    if the bot was not started with the :server_member intent



134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/discordrb/data/server.rb', line 134

def members
  return @members.values if @chunked

  @bot.debug("Members for server #{@id} not chunked yet - initiating")

  # If the SERVER_MEMBERS intent flag isn't set, the gateway won't respond when we ask for members.
  raise 'The :server_members intent is required to get server members' if (@bot.gateway.intents & INTENTS[:server_members]).zero?

  @bot.request_chunks(@id)
  sleep 0.05 until @chunked
  @members.values
end

#modify_widget(enabled, channel, reason = nil) ⇒ Object Also known as: modify_embed

Changes the channel on the server's widget, and sets whether it is enabled.



243
244
245
246
247
248
249
# File 'lib/discordrb/data/server.rb', line 243

def modify_widget(enabled, channel, reason = nil)
  cache_widget_data if @widget_enabled.nil?
  channel_id = channel ? channel.resolve_id : @widget_channel_id
  response = JSON.parse(API::Server.modify_widget(@bot.token, @id, enabled, channel_id, reason))
  @widget_enabled = response['enabled']
  @widget_channel_id = response['channel_id']
end

#move(user, channel) ⇒ Object

Forcibly moves a user into a different voice channel. Only works if the bot has the permission needed.



621
622
623
# File 'lib/discordrb/data/server.rb', line 621

def move(user, channel)
  API::Server.update_member(@bot.token, @id, user.resolve_id, channel_id: channel.resolve_id)
end

#name=(name) ⇒ Object

Sets the server's name.



643
644
645
# File 'lib/discordrb/data/server.rb', line 643

def name=(name)
  update_server_data(name: name)
end

#non_bot_membersArray<Member>



155
156
157
# File 'lib/discordrb/data/server.rb', line 155

def non_bot_members
  members.reject(&:bot_account?)
end

#online_members(include_idle: false, include_bots: true) ⇒ Array<Member> Also known as: online_users



255
256
257
258
259
# File 'lib/discordrb/data/server.rb', line 255

def online_members(include_idle: false, include_bots: true)
  @members.values.select do |e|
    ((include_idle ? e.idle? : false) || e.online?) && (include_bots ? true : !e.bot_account?)
  end
end

#orphan_channelsArray<Channel>



324
325
326
# File 'lib/discordrb/data/server.rb', line 324

def orphan_channels
  @channels.reject { |c| c.parent || c.category? }
end

#ownerMember



84
85
86
# File 'lib/discordrb/data/server.rb', line 84

def owner
  @owner ||= member(@owner_id)
end

#owner=(user) ⇒ Object

Transfers server ownership to another user.



637
638
639
# File 'lib/discordrb/data/server.rb', line 637

def owner=(user)
  API::Server.transfer_ownership(@bot.token, @id, user.resolve_id)
end

#prune_count(days) ⇒ Integer

Returns the amount of members that are candidates for pruning

Raises:

  • (ArgumentError)

    if days is not between 1 and 30 (inclusive)



287
288
289
290
291
292
# File 'lib/discordrb/data/server.rb', line 287

def prune_count(days)
  raise ArgumentError, 'Days must be between 1 and 30' unless days.between?(1, 30)

  response = JSON.parse API::Server.prune_count(@bot.token, @id, days)
  response['pruned']
end

#regionVoiceRegion?

Note:

This may return nil if this server's voice region is deprecated.

Returns voice region data for this server's region.



659
660
661
# File 'lib/discordrb/data/server.rb', line 659

def region
  available_voice_regions.find { |e| e.id == @region_id }
end

#region=(region) ⇒ Object

Moves the server to another region. This will cause a voice interruption of at most a second.



665
666
667
# File 'lib/discordrb/data/server.rb', line 665

def region=(region)
  update_server_data(region: region.to_s)
end

#role(id) ⇒ Role?

Gets a role on this server based on its ID.



113
114
115
116
# File 'lib/discordrb/data/server.rb', line 113

def role(id)
  id = id.resolve_id
  @roles.find { |e| e.id == id }
end

#set_widget_channel(channel, reason = nil) ⇒ Object Also known as: set_embed_channel

Changes the channel on the server's widget



234
235
236
# File 'lib/discordrb/data/server.rb', line 234

def set_widget_channel(channel, reason = nil)
  modify_widget(widget?, channel, reason)
end

#set_widget_enabled(value, reason = nil) ⇒ Object Also known as: set_embed_enabled

Sets whether this server's widget is enabled



219
220
221
# File 'lib/discordrb/data/server.rb', line 219

def set_widget_enabled(value, reason = nil)
  modify_widget(value, widget_channel, reason)
end

#splash=(splash_hash) ⇒ Object

Sets the server splash



744
745
746
# File 'lib/discordrb/data/server.rb', line 744

def splash=(splash_hash)
  update_server_data(splash: splash_hash)
end

#splash_idString Also known as: splash_hash



353
354
355
# File 'lib/discordrb/data/server.rb', line 353

def splash_id
  @splash_id ||= JSON.parse(API::Server.resolve(@bot.token, @id))['splash']
end

#splash_urlString?



360
361
362
363
364
365
# File 'lib/discordrb/data/server.rb', line 360

def splash_url
  splash_id if @splash_id.nil?
  return nil unless @splash_id

  API.splash_url(@id, @splash_id)
end

#system_channelChannel?



813
814
815
# File 'lib/discordrb/data/server.rb', line 813

def system_channel
  @bot.channel(@system_channel_id) if @system_channel_id
end

#system_channel=(system_channel) ⇒ Object

Sets the server's system channel.



689
690
691
# File 'lib/discordrb/data/server.rb', line 689

def system_channel=(system_channel)
  update_server_data(system_channel_id: system_channel.resolve_id)
end

#text_channelsArray<Channel>



309
310
311
# File 'lib/discordrb/data/server.rb', line 309

def text_channels
  @channels.select(&:text?)
end

#unban(user, reason = nil) ⇒ Object

Unbans a previously banned user from this server.



607
608
609
# File 'lib/discordrb/data/server.rb', line 607

def unban(user, reason = nil)
  API::Server.unban_user(@bot.token, @id, user.resolve_id, reason)
end

#verification_levelSymbol



709
710
711
# File 'lib/discordrb/data/server.rb', line 709

def verification_level
  VERIFICATION_LEVELS.key @verification_level
end

#verification_level=(level) ⇒ Object

Sets the verification level of the server



715
716
717
718
719
# File 'lib/discordrb/data/server.rb', line 715

def verification_level=(level)
  level = VERIFICATION_LEVELS[level] if level.is_a?(Symbol)

  update_server_data(verification_level: level)
end

#voice_channelsArray<Channel>



314
315
316
# File 'lib/discordrb/data/server.rb', line 314

def voice_channels
  @channels.select(&:voice?)
end

#webhooksArray<Webhook>

Requests a list of Webhooks on the server.



780
781
782
783
# File 'lib/discordrb/data/server.rb', line 780

def webhooks
  webhooks = JSON.parse(API::Server.webhooks(@bot.token, @id))
  webhooks.map { |webhook| Webhook.new(webhook, @bot) }
end

#widget_banner_url(style) ⇒ String?



345
346
347
348
349
350
# File 'lib/discordrb/data/server.rb', line 345

def widget_banner_url(style)
  update_data if @embed_enabled.nil?
  return unless @embed_enabled

  API.widget_url(@id, style)
end

#widget_channelChannel? Also known as: embed_channel



203
204
205
206
# File 'lib/discordrb/data/server.rb', line 203

def widget_channel
  cache_widget_data if @widget_enabled.nil?
  @bot.channel(@widget_channel_id) if @widget_channel_id
end

#widget_channel=(channel) ⇒ Object Also known as: embed_channel=

Changes the channel on the server's widget



226
227
228
# File 'lib/discordrb/data/server.rb', line 226

def widget_channel=(channel)
  modify_widget(widget?, channel)
end

#widget_enabled=(value) ⇒ Object Also known as: embed_enabled=

Sets whether this server's widget is enabled



211
212
213
# File 'lib/discordrb/data/server.rb', line 211

def widget_enabled=(value)
  modify_widget(value, widget_channel)
end

#widget_enabled?true, false Also known as: widget?, embed_enabled, embed?



194
195
196
197
# File 'lib/discordrb/data/server.rb', line 194

def widget_enabled?
  cache_widget_data if @widget_enabled.nil?
  @widget_enabled
end

#widget_urlString?



330
331
332
333
334
335
# File 'lib/discordrb/data/server.rb', line 330

def widget_url
  update_data if @embed_enabled.nil?
  return unless @embed_enabled

  API.widget_url(@id)
end