class Discordrb::Server

A server on Discord

Constants

FILTER_LEVELS

A map of possible content filter levels to symbol names

NOTIFICATION_LEVELS

A map of possible message notification levels to symbol names

VERIFICATION_LEVELS

A map of possible server verification levels to symbol names

Attributes

afk_timeout[R]

@return [Integer] the amount of time after which a voice user gets moved into the AFK channel, in seconds.

boost_level[R]

The server’s Nitro boost level. @return [Integer] the boost level, 0 if no level.

booster_count[R]

The server’s amount of Nitro boosters. @return [Integer] the amount of boosters, 0 if no one has boosted.

channels[R]

@return [Array<Channel>] an array of all the channels (text and voice) on this server.

emoji[R]

@return [Hash<Integer => Emoji>] a hash of all the emoji available on this server.

emojis[R]

@return [Hash<Integer => Emoji>] a hash of all the emoji available on this server.

features[R]

@return [Array<Symbol>] the features of the server (eg. “INVITE_SPLASH”)

large[R]

@return [true, false] whether or not this server is large (members > 100). If it is, it means the members list may be inaccurate for a couple seconds after starting up the bot.

large?[R]

@return [true, false] whether or not this server is large (members > 100). If it is, it means the members list may be inaccurate for a couple seconds after starting up the bot.

member_count[R]

@return [Integer] the absolute number of members on this server, offline or not.

region_id[R]

@return [String] the ID of the region the server is on (e.g. ‘amsterdam`).

roles[R]

@return [Array<Role>] an array of all the roles created on this server.

voice_states[R]

@return [Hash<Integer => VoiceState>] the hash (user ID => voice state) of voice states of members on this server

Public Class Methods

new(data, bot) click to toggle source

@!visibility private

# File lib/discordrb/data/server.rb, line 65
def initialize(data, bot)
  @bot = bot
  @owner_id = data['owner_id'].to_i
  @id = data['id'].to_i
  @members = {}
  @voice_states = {}
  @emoji = {}

  process_channels(data['channels'])
  update_data(data)

  # Whether this server's members have been chunked (resolved using op 8 and GUILD_MEMBERS_CHUNK) yet
  @chunked = false

  @booster_count = data['premium_subscription_count'] || 0
  @boost_level = data['premium_tier']
end

Public Instance Methods

add_channel(channel) click to toggle source

Adds a channel to this server’s cache @note For internal use only @!visibility private

# File lib/discordrb/data/server.rb, line 863
def add_channel(channel)
  @channels << channel
  @channels_by_id[channel.id] = channel
end
add_emoji(name, image, roles = [], reason: nil) click to toggle source

Adds a new custom emoji on this server. @param name [String] The name of emoji to create. @param image [String, read] A base64 encoded string with the image data, or an object that responds to ‘#read`, such as `File`. @param roles [Array<Role, String, Integer>] An array of roles, or role IDs to be whitelisted for this emoji. @param reason [String] The reason the for the creation of this emoji. @return [Emoji] The emoji that has been added.

# 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(member) click to toggle source

Adds a member to the member cache. @note For internal use only @!visibility private

# File lib/discordrb/data/server.rb, line 424
def add_member(member)
  @member_count += 1
  @members[member.id] = member
end
add_member_using_token(user, access_token, nick: nil, roles: [], deaf: false, mute: false) click to toggle source

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: discord.com/developers/docs/topics/oauth2 @note Your bot must be present in this server, and have permission to create instant invites for this to work. @param user [User, String, Integer] the user, or ID of the user to add to this server @param access_token [String] the OAuth2 Bearer token that has been granted the ‘guilds.join` scope @param nick [String] the nickname to give this member upon joining @param roles [Role, Array<Role, String, Integer>] the role (or roles) to give this member upon joining @param deaf [true, false] whether this member will be server deafened upon joining @param mute [true, false] whether this member will be server muted upon joining @return [Member, nil] the created member, or `nil` if the user is already a member of this server.

# 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
add_role(role) click to toggle source

Adds a role to the role cache @note For internal use only @!visibility private

# File lib/discordrb/data/server.rb, line 391
def add_role(role)
  @roles << role
end
afk_channel() click to toggle source

@return [Channel, nil] the AFK voice channel of this server, or ‘nil` if none is set.

# File lib/discordrb/data/server.rb, line 813
def afk_channel
  @bot.channel(@afk_channel_id) if @afk_channel_id
end
afk_channel=(afk_channel) click to toggle source

Sets the server’s AFK channel. @param afk_channel [Channel, nil] The new AFK channel, or ‘nil` if there should be none set.

# File lib/discordrb/data/server.rb, line 688
def afk_channel=(afk_channel)
  update_server_data(afk_channel_id: afk_channel.resolve_id)
end
afk_timeout=(afk_timeout) click to toggle source

Sets the amount of time after which a user gets moved into the AFK channel. @param afk_timeout [Integer] The AFK timeout, in seconds.

# File lib/discordrb/data/server.rb, line 700
def afk_timeout=(afk_timeout)
  update_server_data(afk_timeout: afk_timeout)
end
any_emoji?() click to toggle source

@return [true, false] whether this server has any emoji or not.

# File lib/discordrb/data/server.rb, line 776
def any_emoji?
  @emoji.any?
end
Also aliased as: has_emoji?, emoji?
audit_logs(action: nil, user: nil, limit: 50, before: nil) click to toggle source

@param action [Symbol] The action to only include. @param user [User, String, Integer] The user, or their ID, to filter entries to. @param limit [Integer] The amount of entries to limit it to. @param before [Entry, String, Integer] The entry, or its ID, to use to not include all entries after it. @return [AuditLogs] The server’s audit logs.

# 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_regions() click to toggle source

@return [Array<VoiceRegion>] collection of available voice regions to this guild

# File lib/discordrb/data/server.rb, line 653
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) click to toggle source

Bans a user from this server. @param user [User, String, Integer] The user to ban. @param message_days [Integer] How many days worth of messages sent by the user should be deleted. @param reason [String] The reason the user is being banned.

# File lib/discordrb/data/server.rb, line 604
def ban(user, message_days = 0, reason: nil)
  API::Server.ban_user(@bot.token, @id, user.resolve_id, message_days, reason)
end
banner_id() click to toggle source

@return [String] the hexadecimal ID used to identify this server’s banner image, shown by the server name.

banner_url() click to toggle source

@return [String, nil] the banner image URL for the server’s banner image, or

`nil` if there is no banner image.
bans(limit: nil, before_id: nil, after_id: nil) click to toggle source

Retrieve banned users from this server. @param limit [Integer] Number of users to return (up to maximum 1000, default 1000). @param before_id [Integer] Consider only users before given user id. @param after_id [Integer] Consider only users after given user id. @return [Array<ServerBan>] a list of banned users on this server and the reason they were banned.

# File lib/discordrb/data/server.rb, line 593
def bans(limit: nil, before_id: nil, after_id: nil)
  response = JSON.parse(API::Server.bans(@bot.token, @id, limit, before_id, after_id))
  response.map do |e|
    ServerBan.new(self, User.new(e['user'], @bot), e['reason'])
  end
end
begin_prune(days, reason = nil) click to toggle source

Prunes (kicks) an amount of members for inactivity @param days [Integer] the number of days to consider for inactivity (between 1 and 30) @param reason [String] The reason the for the prune. @return [Integer] the number of members removed at the end of the operation @raise [ArgumentError] if days is not between 1 and 30 (inclusive)

# 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
Also aliased as: prune
bot() click to toggle source

@return [Member] the bot’s own ‘Member` on this server

# File lib/discordrb/data/server.rb, line 160
def bot
  member(@bot.profile)
end
bot_members() click to toggle source

@return [Array<Member>] an array of all the bot members on this server.

# File lib/discordrb/data/server.rb, line 150
def bot_members
  members.select(&:bot_account?)
end
cache_member(member) click to toggle source

Adds a member to the cache @note For internal use only @!visibility private

# File lib/discordrb/data/server.rb, line 447
def cache_member(member)
  @members[member.id] = member
end
cache_widget_data() click to toggle source

Cache @widget @note For internal use only @!visibility private

# File lib/discordrb/data/server.rb, line 187
def cache_widget_data
  data = JSON.parse(API::Server.widget(@bot.token, @id))
  @widget_enabled = data['enabled']
  @widget_channel_id = data['channel_id']
end
categories() click to toggle source

@return [Array<Channel>] an array of category channels on this server

# File lib/discordrb/data/server.rb, line 319
def categories
  @channels.select(&:category?)
end
content_filter_level()
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) click to toggle source

Creates a channel on this server with the given name. @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.

@param name [String] Name of the channel to create @param type [Integer, Symbol] Type of channel to create (0: text, 2: voice, 4: category, 5: news, 6: store) @param topic [String] the topic of this channel, if it will be a text channel @param bitrate [Integer] the bitrate of this channel, if it will be a voice channel @param user_limit [Integer] the user limit of this channel, if it will be a voice channel @param permission_overwrites [Array<Hash>, Array<Overwrite>] permission overwrites for this channel @param parent [Channel, String, Integer] parent category, or its ID, for this channel to be created in. @param nsfw [true, false] whether this channel should be created as nsfw @param rate_limit_per_user [Integer] how many seconds users need to wait in between messages. @param reason [String] The reason the for the creation of this channel. @return [Channel] the created channel. @raise [ArgumentError] if type is not 0 (text), 2 (voice), 4 (category), 5 (news), or 6 (store)

# 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) click to toggle source

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. @param name [String] Name of the role to create @param colour [Integer, ColourRGB, combined] The roles colour @param hoist [true, false] @param mentionable [true, false] @param permissions [Integer, Array<Symbol>, Permissions, bits] The permissions to write to the new role. @param reason [String] The reason the for the creation of this role. @return [Role] the created role.

# 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) click to toggle source

The default channel is the text channel on this server with the highest position that the bot has Read Messages permission on. @param send_messages [true, false] whether to additionally consider if the bot has Send Messages permission @return [Channel, nil] The default channel on this server, or ‘nil` if there are no channels that the bot can read.

# 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
Also aliased as: general_channel
default_message_notifications() click to toggle source

@return [Symbol] the default message notifications settings of the server (:all = ‘All messages’, :mentions = ‘Only @mentions’).

# File lib/discordrb/data/server.rb, line 733
def default_message_notifications
  NOTIFICATION_LEVELS.key @default_message_notifications
end
default_message_notifications=(notification_level) click to toggle source

Sets the default message notification level @param notification_level [Integer, Symbol] The default message notification 0-1 or Symbol (see {NOTIFICATION_LEVELS})

# File lib/discordrb/data/server.rb, line 739
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
Also aliased as: notification_level=
delete() click to toggle source

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

# File lib/discordrb/data/server.rb, line 631
def delete
  API::Server.delete(@bot.token, @id)
end
delete_channel(id) click to toggle source

Deletes a channel from this server’s cache @note For internal use only @!visibility private

# File lib/discordrb/data/server.rb, line 871
def delete_channel(id)
  @channels.reject! { |e| e.id == id }
  @channels_by_id.delete(id)
end
delete_emoji(emoji, reason: nil) click to toggle source

Delete a custom emoji on this server @param emoji [Emoji, String, Integer] The emoji or emoji ID to be deleted. @param reason [String] The reason the for the deletion of this emoji.

# 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
delete_member(user_id) click to toggle source

Removes a member from the member cache. @note For internal use only @!visibility private

# File lib/discordrb/data/server.rb, line 432
def delete_member(user_id)
  @members.delete(user_id)
  @member_count -= 1 unless @member_count <= 0
end
delete_role(role_id) click to toggle source

Removes a role from the role cache @note For internal use only @!visibility private

# File lib/discordrb/data/server.rb, line 398
def delete_role(role_id)
  @roles.reject! { |r| r.id == role_id }
  @members.each do |_, member|
    new_roles = member.roles.reject { |r| r.id == role_id }
    member.update_roles(new_roles)
  end
  @channels.each do |channel|
    overwrites = channel.permission_overwrites.reject { |id, _| id == role_id }
    channel.update_overwrites(overwrites)
  end
end
edit_emoji(emoji, name: nil, roles: nil, reason: nil) click to toggle source

Changes the name and/or role whitelist of an emoji on this server. @param emoji [Emoji, String, Integer] The emoji or emoji ID to edit. @param name [String] The new name for the emoji. @param roles [Array<Role, String, Integer>] A new array of roles, or role IDs, to whitelist. @param reason [String] The reason for the editing of this emoji. @return [Emoji] The edited emoji.

# 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
embed?()
Alias for: widget_enabled?
embed_channel()
Alias for: widget_channel
embed_channel=(channel)
Alias for: widget_channel=
embed_enabled()
Alias for: widget_enabled?
embed_enabled=(value)
Alias for: widget_enabled=
emoji?()
Alias for: any_emoji?
everyone_role() click to toggle source

@return [Role] The @everyone role on this server

# File lib/discordrb/data/server.rb, line 106
def everyone_role
  role(@id)
end
explicit_content_filter() click to toggle source

@return [Symbol] the explicit content filter level of the server (:none = ‘Don’t scan any messages.‘, :exclude_roles = ’Scan messages for members without a role.‘, :all = ’Scan messages sent by all members.‘).

# File lib/discordrb/data/server.rb, line 761
def explicit_content_filter
  FILTER_LEVELS.key @explicit_content_filter
end
Also aliased as: content_filter_level
explicit_content_filter=(filter_level) click to toggle source

Sets the server content filter. @param filter_level [Integer, Symbol] The content filter from 0-2 or Symbol (see {FILTER_LEVELS})

# File lib/discordrb/data/server.rb, line 769
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
general_channel(send_messages = false)
Alias for: default_channel
has_emoji?()
Alias for: any_emoji?
icon=(icon) click to toggle source

Sets the server’s icon. @param icon [String, read] The new icon, in base64-encoded JPG format.

# File lib/discordrb/data/server.rb, line 676
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
inspect() click to toggle source

The inspect method is overwritten to give more useful output

# File lib/discordrb/data/server.rb, line 885
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
integrations() click to toggle source

@return [Array<Integration>] an array of all the integrations connected to this server.

# 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
invites() click to toggle source

Requests a list of Invites to the server. @return [Array<Invite>] invites to the server.

# File lib/discordrb/data/server.rb, line 792
def invites
  invites = JSON.parse(API::Server.invites(@bot.token, @id))
  invites.map { |invite| Invite.new(invite, @bot) }
end
kick(user, reason = nil) click to toggle source

Kicks a user from this server. @param user [User, String, Integer] The user to kick. @param reason [String] The reason the user is being kicked.

# File lib/discordrb/data/server.rb, line 618
def kick(user, reason = nil)
  API::Server.remove_member(@bot.token, @id, user.resolve_id, reason)
end
leave() click to toggle source

Leave the server.

# File lib/discordrb/data/server.rb, line 636
def leave
  API::User.leave_server(@bot.token, @id)
end
max_emoji() click to toggle source

The amount of emoji the server can have, based on its current Nitro Boost Level. @return [Integer] the max amount of emoji

# File lib/discordrb/data/server.rb, line 575
def max_emoji
  case @boost_level
  when 1
    100
  when 2
    150
  when 3
    250
  else
    50
  end
end
member(id, request = true) click to toggle source

Gets a member on this server based on user ID @param id [Integer] The user ID to look for @param request [true, false] Whether the member should be requested from Discord if it’s not cached

# 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
member_cached?(user_id) click to toggle source

Checks whether a member is cached @note For internal use only @!visibility private

# File lib/discordrb/data/server.rb, line 440
def member_cached?(user_id)
  @members.include?(user_id)
end
members() click to toggle source

@return [Array<Member>] an array of all the members on this server. @raise [RuntimeError] if the bot was not started with the :server_member intent

# 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
Also aliased as: users
modify_embed(enabled, channel, reason = nil)
Alias for: modify_widget
modify_widget(enabled, channel, reason = nil) click to toggle source

Changes the channel on the server’s widget, and sets whether it is enabled. @param enabled [true, false] whether the widget is enabled @param channel [Channel, String, Integer] the channel, or its ID, to be referenced by the widget @param reason [String, nil] the reason to be shown in the audit log for this action

# 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
Also aliased as: modify_embed
move(user, channel) click to toggle source

Forcibly moves a user into a different voice channel. Only works if the bot has the permission needed and if the user is already connected to some voice channel on this server. @param user [User, String, Integer] The user to move. @param channel [Channel, String, Integer, nil] The voice channel to move into. (If nil, the user is disconnected from the voice channel)

# File lib/discordrb/data/server.rb, line 626
def move(user, channel)
  API::Server.update_member(@bot.token, @id, user.resolve_id, channel_id: channel&.resolve_id)
end
name=(name) click to toggle source

Sets the server’s name. @param name [String] The new server name.

# File lib/discordrb/data/server.rb, line 648
def name=(name)
  update_server_data(name: name)
end
non_bot_members() click to toggle source

@return [Array<Member>] an array of all the non bot members on this server.

# File lib/discordrb/data/server.rb, line 155
def non_bot_members
  members.reject(&:bot_account?)
end
notification_level=(notification_level)
online_members(include_idle: false, include_bots: true) click to toggle source

@param include_idle [true, false] Whether to count idle members as online. @param include_bots [true, false] Whether to include bot accounts in the count. @return [Array<Member>] an array of online members on this server.

# 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
Also aliased as: online_users
online_users(include_idle: false, include_bots: true)
Alias for: online_members
orphan_channels() click to toggle source

@return [Array<Channel>] an array of channels on this server that are not in a category

# File lib/discordrb/data/server.rb, line 324
def orphan_channels
  @channels.reject { |c| c.parent || c.category? }
end
owner() click to toggle source

@return [Member] The server owner.

# File lib/discordrb/data/server.rb, line 84
def owner
  @owner ||= member(@owner_id)
end
owner=(user) click to toggle source

Transfers server ownership to another user. @param user [User, String, Integer] The user who should become the new owner.

# File lib/discordrb/data/server.rb, line 642
def owner=(user)
  API::Server.transfer_ownership(@bot.token, @id, user.resolve_id)
end
process_chunk(members, chunk_index, chunk_count) click to toggle source

Processes a GUILD_MEMBERS_CHUNK packet, specifically the members field @note For internal use only @!visibility private

# File lib/discordrb/data/server.rb, line 800
def process_chunk(members, chunk_index, chunk_count)
  process_members(members)
  LOGGER.debug("Processed chunk #{chunk_index + 1}/#{chunk_count} server #{@id} - index #{chunk_index} - length #{members.length}")

  return if chunk_index + 1 < chunk_count

  LOGGER.debug("Finished chunking server #{@id}")

  # Reset everything to normal
  @chunked = true
end
prune(days, reason = nil)
Alias for: begin_prune
prune_count(days) click to toggle source

Returns the amount of members that are candidates for pruning @param days [Integer] the number of days to consider for inactivity @return [Integer] number of members to be removed @raise [ArgumentError] if days is not between 1 and 30 (inclusive)

# 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
region() click to toggle source

@return [VoiceRegion, nil] voice region data for this server’s region @note This may return ‘nil` if this server’s voice region is deprecated.

# File lib/discordrb/data/server.rb, line 664
def region
  available_voice_regions.find { |e| e.id == @region_id }
end
region=(region) click to toggle source

Moves the server to another region. This will cause a voice interruption of at most a second. @param region [String] The new region the server should be in.

# File lib/discordrb/data/server.rb, line 670
def region=(region)
  update_server_data(region: region.to_s)
end
role(id) click to toggle source

Gets a role on this server based on its ID. @param id [String, Integer] The role ID to look for. @return [Role, nil] The role identified by the ID, or ‘nil` if it couldn’t be found.

# File lib/discordrb/data/server.rb, line 113
def role(id)
  id = id.resolve_id
  @roles.find { |e| e.id == id }
end
set_embed_channel(channel, reason = nil)
Alias for: set_widget_channel
set_embed_enabled(value, reason = nil)
Alias for: set_widget_enabled
set_widget_channel(channel, reason = nil) click to toggle source

Changes the channel on the server’s widget @param channel [Channel, String, Integer] the channel, or its ID, to be referenced by the widget @param reason [String, nil] the reason to be shown in the audit log for this action

# File lib/discordrb/data/server.rb, line 234
def set_widget_channel(channel, reason = nil)
  modify_widget(widget?, channel, reason)
end
Also aliased as: set_embed_channel
set_widget_enabled(value, reason = nil) click to toggle source

Sets whether this server’s widget is enabled @param value [true, false] @param reason [String, nil] the reason to be shown in the audit log for this action

# File lib/discordrb/data/server.rb, line 219
def set_widget_enabled(value, reason = nil)
  modify_widget(value, widget_channel, reason)
end
Also aliased as: set_embed_enabled
splash=(splash_hash) click to toggle source

Sets the server splash @param splash_hash [String] The splash hash

# File lib/discordrb/data/server.rb, line 749
def splash=(splash_hash)
  update_server_data(splash: splash_hash)
end
splash_hash()
Alias for: splash_id
splash_id() click to toggle source

@return [String] the hexadecimal ID used to identify this server’s splash image for their VIP invite page.

# File lib/discordrb/data/server.rb, line 353
def splash_id
  @splash_id ||= JSON.parse(API::Server.resolve(@bot.token, @id))['splash']
end
Also aliased as: splash_hash
splash_url() click to toggle source

@return [String, nil] the splash image URL for the server’s VIP invite page.

`nil` if there is no splash image.
# 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_channel() click to toggle source

@return [Channel, nil] the system channel (used for automatic welcome messages) of a server, or ‘nil` if none is set.

# File lib/discordrb/data/server.rb, line 818
def system_channel
  @bot.channel(@system_channel_id) if @system_channel_id
end
system_channel=(system_channel) click to toggle source

Sets the server’s system channel. @param system_channel [Channel, String, Integer, nil] The new system channel, or ‘nil` should it be disabled.

# File lib/discordrb/data/server.rb, line 694
def system_channel=(system_channel)
  update_server_data(system_channel_id: system_channel.resolve_id)
end
text_channels() click to toggle source

@return [Array<Channel>] an array of text channels on this server

# File lib/discordrb/data/server.rb, line 309
def text_channels
  @channels.select(&:text?)
end
unban(user, reason = nil) click to toggle source

Unbans a previously banned user from this server. @param user [User, String, Integer] The user to unban. @param reason [String] The reason the user is being unbanned.

# File lib/discordrb/data/server.rb, line 611
def unban(user, reason = nil)
  API::Server.unban_user(@bot.token, @id, user.resolve_id, reason)
end
update_data(new_data = nil) click to toggle source

Updates the cached data with new data @note For internal use only @!visibility private

# File lib/discordrb/data/server.rb, line 825
def update_data(new_data = nil)
  new_data ||= JSON.parse(API::Server.resolve(@bot.token, @id))
  @name = new_data[:name] || new_data['name'] || @name
  @region_id = new_data[:region] || new_data['region'] || @region_id
  @icon_id = new_data[:icon] || new_data['icon'] || @icon_id
  @afk_timeout = new_data[:afk_timeout] || new_data['afk_timeout'] || @afk_timeout

  afk_channel_id = new_data[:afk_channel_id] || new_data['afk_channel_id'] || @afk_channel
  @afk_channel_id = afk_channel_id.nil? ? nil : afk_channel_id.resolve_id
  widget_channel_id = new_data[:widget_channel_id] || new_data['widget_channel_id'] || @widget_channel
  @widget_channel_id = widget_channel_id.nil? ? nil : widget_channel_id.resolve_id
  system_channel_id = new_data[:system_channel_id] || new_data['system_channel_id'] || @system_channel
  @system_channel_id = system_channel_id.nil? ? nil : system_channel_id.resolve_id

  @widget_enabled = new_data[:widget_enabled] || new_data['widget_enabled']
  @splash = new_data[:splash_id] || new_data['splash_id'] || @splash_id

  @verification_level = new_data[:verification_level] || new_data['verification_level'] || @verification_level
  @explicit_content_filter = new_data[:explicit_content_filter] || new_data['explicit_content_filter'] || @explicit_content_filter
  @default_message_notifications = new_data[:default_message_notifications] || new_data['default_message_notifications'] || @default_message_notifications

  @large = new_data.key?('large') ? new_data['large'] : @large
  @member_count = new_data['member_count'] || @member_count || 0
  @splash_id = new_data['splash'] || @splash_id
  @banner_id = new_data['banner'] || @banner_id
  @features = new_data['features'] ? new_data['features'].map { |element| element.downcase.to_sym } : @features || []

  process_channels(new_data['channels']) if new_data['channels']
  process_roles(new_data['roles']) if new_data['roles']
  process_emoji(new_data['emojis']) if new_data['emojis']
  process_members(new_data['members']) if new_data['members']
  process_presences(new_data['presences']) if new_data['presences']
  process_voice_states(new_data['voice_states']) if new_data['voice_states']
end
update_emoji_data(new_data) click to toggle source

Updates the cached emoji data with new data @note For internal use only @!visibility private

# File lib/discordrb/data/server.rb, line 879
def update_emoji_data(new_data)
  @emoji = {}
  process_emoji(new_data['emojis'])
end
update_role_positions(role_positions) click to toggle source

Updates the positions of all roles on the server @note For internal use only @!visibility private

# File lib/discordrb/data/server.rb, line 413
def update_role_positions(role_positions)
  response = JSON.parse(API::Server.update_role_positions(@bot.token, @id, role_positions))
  response.each do |data|
    updated_role = Role.new(data, @bot, self)
    role(updated_role.id).update_from(updated_role)
  end
end
update_voice_state(data) click to toggle source

Updates a member’s voice state @note For internal use only @!visibility private

# File lib/discordrb/data/server.rb, line 454
def update_voice_state(data)
  user_id = data['user_id'].to_i

  if data['channel_id']
    unless @voice_states[user_id]
      # Create a new voice state for the user
      @voice_states[user_id] = VoiceState.new(user_id)
    end

    # Update the existing voice state (or the one we just created)
    channel = @channels_by_id[data['channel_id'].to_i]
    @voice_states[user_id].update(
      channel,
      data['mute'],
      data['deaf'],
      data['self_mute'],
      data['self_deaf']
    )
  else
    # The user is not in a voice channel anymore, so delete its voice state
    @voice_states.delete(user_id)
  end
end
users()
Alias for: members
verification_level() click to toggle source

@return [Symbol] the verification level of the server (:none = none, :low = ‘Must have a verified email on their Discord account’, :medium = ‘Has to be registered with Discord for at least 5 minutes’, :high = ‘Has to be a member of this server for at least 10 minutes’, :very_high = ‘Must have a verified phone on their Discord account’).

# File lib/discordrb/data/server.rb, line 714
def verification_level
  VERIFICATION_LEVELS.key @verification_level
end
verification_level=(level) click to toggle source

Sets the verification level of the server @param level [Integer, Symbol] The verification level from 0-4 or Symbol (see {VERIFICATION_LEVELS})

# File lib/discordrb/data/server.rb, line 720
def verification_level=(level)
  level = VERIFICATION_LEVELS[level] if level.is_a?(Symbol)

  update_server_data(verification_level: level)
end
voice_channels() click to toggle source

@return [Array<Channel>] an array of voice channels on this server

# File lib/discordrb/data/server.rb, line 314
def voice_channels
  @channels.select(&:voice?)
end
webhooks() click to toggle source

Requests a list of Webhooks on the server. @return [Array<Webhook>] webhooks on the server.

# File lib/discordrb/data/server.rb, line 785
def webhooks
  webhooks = JSON.parse(API::Server.webhooks(@bot.token, @id))
  webhooks.map { |webhook| Webhook.new(webhook, @bot) }
end
widget?()
Alias for: widget_enabled?
widget_banner_url(style) click to toggle source

@param style [Symbol] The style the picture should have. Possible styles are:

* `:banner1` creates a rectangular image with the server name, member count and icon, a "Powered by Discord" message on the bottom and an arrow on the right.
* `:banner2` creates a less tall rectangular image that has the same information as `banner1`, but the Discord logo on the right - together with the arrow and separated by a diagonal separator.
* `:banner3` creates an image similar in size to `banner1`, but it has the arrow in the bottom part, next to the Discord logo and with a "Chat now" text.
* `:banner4` creates a tall, almost square, image that prominently features the Discord logo at the top and has a "Join my server" in a pill-style button on the bottom. The information about the server is in the same format as the other three `banner` styles.
* `:shield` creates a very small, long rectangle, of the style you'd find at the top of GitHub `README.md` files. It features a small version of the Discord logo at the left and the member count at the right.

@return [String, nil] the widget banner URL to the server that displays the amount of online members,

server icon and server name in a stylish way. `nil` if the widget is not enabled.
# 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_channel() click to toggle source

@return [Channel, nil] the channel the server widget will make an invite for.

# 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
Also aliased as: embed_channel
widget_channel=(channel) click to toggle source

Changes the channel on the server’s widget @param channel [Channel, String, Integer] the channel, or its ID, to be referenced by the widget

# File lib/discordrb/data/server.rb, line 226
def widget_channel=(channel)
  modify_widget(widget?, channel)
end
Also aliased as: embed_channel=
widget_enabled=(value) click to toggle source

Sets whether this server’s widget is enabled @param value [true, false]

# File lib/discordrb/data/server.rb, line 211
def widget_enabled=(value)
  modify_widget(value, widget_channel)
end
Also aliased as: embed_enabled=
widget_enabled?() click to toggle source

@return [true, false] whether or not the server has widget enabled

# File lib/discordrb/data/server.rb, line 194
def widget_enabled?
  cache_widget_data if @widget_enabled.nil?
  @widget_enabled
end
Also aliased as: widget?, embed_enabled, embed?
widget_url() click to toggle source

@return [String, nil] the widget URL to the server that displays the amount of online members in a

stylish way. `nil` if the widget is not enabled.
# 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

Private Instance Methods

process_channels(channels) click to toggle source
# File lib/discordrb/data/server.rb, line 955
def process_channels(channels)
  @channels = []
  @channels_by_id = {}

  return unless channels

  channels.each do |element|
    channel = @bot.ensure_channel(element, self)
    @channels << channel
    @channels_by_id[channel.id] = channel
  end
end
process_emoji(emoji) click to toggle source
# File lib/discordrb/data/server.rb, line 920
def process_emoji(emoji)
  return if emoji.empty?

  emoji.each do |element|
    new_emoji = Emoji.new(element, @bot, self)
    @emoji[new_emoji.id] = new_emoji
  end
end
process_members(members) click to toggle source
# File lib/discordrb/data/server.rb, line 929
def process_members(members)
  return unless members

  members.each do |element|
    member = Member.new(element, self, @bot)
    @members[member.id] = member
  end
end
process_presences(presences) click to toggle source
# File lib/discordrb/data/server.rb, line 938
def process_presences(presences)
  # Update user statuses with presence info
  return unless presences

  presences.each do |element|
    next unless element['user']

    user_id = element['user']['id'].to_i
    user = @members[user_id]
    if user
      user.update_presence(element)
    else
      LOGGER.warn "Rogue presence update! #{element['user']['id']} on #{@id}"
    end
  end
end
process_roles(roles) click to toggle source
# File lib/discordrb/data/server.rb, line 906
def process_roles(roles)
  # Create roles
  @roles = []
  @roles_by_id = {}

  return unless roles

  roles.each do |element|
    role = Role.new(element, @bot, self)
    @roles << role
    @roles_by_id[role.id] = role
  end
end
process_voice_states(voice_states) click to toggle source
# File lib/discordrb/data/server.rb, line 968
def process_voice_states(voice_states)
  return unless voice_states

  voice_states.each do |element|
    update_voice_state(element)
  end
end
update_server_data(new_data) click to toggle source
# File lib/discordrb/data/server.rb, line 891
def update_server_data(new_data)
  response = JSON.parse(API::Server.update(@bot.token, @id,
                                           new_data[:name] || @name,
                                           new_data[:region] || @region_id,
                                           new_data[:icon_id] || @icon_id,
                                           new_data[:afk_channel_id] || @afk_channel_id,
                                           new_data[:afk_timeout] || @afk_timeout,
                                           new_data[:splash] || @splash,
                                           new_data[:default_message_notifications] || @default_message_notifications,
                                           new_data[:verification_level] || @verification_level,
                                           new_data[:explicit_content_filter] || @explicit_content_filter,
                                           new_data[:system_channel_id] || @system_channel_id))
  update_data(response)
end