class Discordrb::Member

A member is a user on a server. It differs from regular users in that it has roles, voice statuses and things like that.

Public Class Methods

new(data, server, bot) click to toggle source

@!visibility private

Calls superclass method
# File lib/discordrb/data/member.rb, line 63
def initialize(data, server, bot)
  @bot = bot

  @user = bot.ensure_user(data['user'])
  super @user # Initialize the delegate class

  @server = server
  @server_id = server&.id || data['guild_id'].to_i

  @role_ids = data['roles']&.map(&:to_i) || []

  @nick = data['nick']
  @joined_at = data['joined_at'] ? Time.parse(data['joined_at']) : nil
  @boosting_since = data['premium_since'] ? Time.parse(data['premium_since']) : nil
  timeout_until = data['communication_disabled_until']
  @communication_disabled_until = timeout_until ? Time.parse(timeout_until) : nil
  @permissions = Permissions.new(data['permissions']) if data['permissions']
end

Public Instance Methods

add_role(role, reason = nil) click to toggle source

Adds one or more roles to this member. @param role [Role, Array<Role, String, Integer>, String, Integer] The role(s), or their ID(s), to add. @param reason [String] The reason the user’s roles are being changed.

# File lib/discordrb/data/member.rb, line 172
def add_role(role, reason = nil)
  role_ids = role_id_array(role)

  if role_ids.count == 1
    API::Server.add_member_role(@bot.token, @server_id, @user.id, role_ids[0], reason)
  else
    old_role_ids = resolve_role_ids
    new_role_ids = (old_role_ids + role_ids).uniq
    API::Server.update_member(@bot.token, @server_id, @user.id, roles: new_role_ids, reason: reason)
  end
end
ban(message_days = 0, reason: nil) click to toggle source

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

# File lib/discordrb/data/member.rb, line 252
def ban(message_days = 0, reason: nil)
  server.ban(@user, message_days, reason: reason)
end
boosting?() click to toggle source

@return [true, false] if this user is a Nitro Booster of this server.

# File lib/discordrb/data/member.rb, line 105
def boosting?
  !@boosting_since.nil?
end
color()
Alias for: colour
color_role()
Alias for: colour_role
colour() click to toggle source

@return [ColourRGB, nil] the colour this member has.

# File lib/discordrb/data/member.rb, line 222
def colour
  return nil unless colour_role

  colour_role.color
end
Also aliased as: color
colour_role() click to toggle source

@return [Role, nil] the role this member is basing their colour on.

# File lib/discordrb/data/member.rb, line 213
def colour_role
  coloured_roles = roles.select { |v| v.colour.combined.nonzero? }
  return nil if coloured_roles.empty?

  coloured_roles.max_by(&:position)
end
Also aliased as: color_role
communication_disabled?() click to toggle source

Check if the current user has communication disabled. @return [true, false]

# File lib/discordrb/data/member.rb, line 128
def communication_disabled?
  !@communication_disabled_until.nil? && @communication_disabled_until > Time.now
end
Also aliased as: timeout?
communication_disabled_until=(timeout_until) click to toggle source

Set a user’s timeout duration, or remove it by setting the timeout to ‘nil`. @param timeout_until [Time, nil] When the timeout will end.

# File lib/discordrb/data/member.rb, line 136
def communication_disabled_until=(timeout_until)
  raise ArgumentError, 'A time out cannot exceed 28 days' if timeout_until && timeout_until > (Time.now + 2_419_200)

  API::Server.update_member(@bot.token, @server_id, @user.id, communication_disabled_until: timeout_until.iso8601)
end
Also aliased as: timeout=
deaf() click to toggle source

@return [true, false] whether this member is deafened server-wide.

# File lib/discordrb/data/member.rb, line 36
def deaf
  voice_state_attribute(:deaf)
end
Also aliased as: deafened?
deafened?()
Alias for: deaf
display_name() click to toggle source

@return [String] the name the user displays as (nickname if they have one, global_name if they have one, username otherwise)

# File lib/discordrb/data/member.rb, line 293
def display_name
  nickname || global_name || username
end
highest_role() click to toggle source

@return [Role] the highest role this member has.

# File lib/discordrb/data/member.rb, line 200
def highest_role
  roles.max_by(&:position)
end
hoist_role() click to toggle source

@return [Role, nil] the role this member is being hoisted with.

# File lib/discordrb/data/member.rb, line 205
def hoist_role
  hoisted_roles = roles.select(&:hoist)
  return nil if hoisted_roles.empty?

  hoisted_roles.max_by(&:position)
end
inspect() click to toggle source

Overwriting inspect for debug purposes

# File lib/discordrb/data/member.rb, line 347
def inspect
  "<Member user=#{@user.inspect} server=#{@server&.inspect || @server_id} joined_at=#{@joined_at} roles=#{@roles&.inspect || @role_ids} voice_channel=#{@voice_channel.inspect} mute=#{@mute} deaf=#{@deaf} self_mute=#{@self_mute} self_deaf=#{@self_deaf}>"
end
kick(reason = nil) click to toggle source

Kicks this member from the server. @param reason [String] The reason this member is being kicked.

# File lib/discordrb/data/member.rb, line 264
def kick(reason = nil)
  server.kick(@user, reason)
end
modify_roles(add, remove, reason = nil) click to toggle source

Adds and removes roles from a member. @param add [Role, Array<Role>] The role(s) to add. @param remove [Role, Array<Role>] The role(s) to remove. @param reason [String] The reason the user’s roles are being changed. @example Remove the ‘Member’ role from a user, and add the ‘Muted’ role to them.

to_add = server.roles.find {|role| role.name == 'Muted'}
to_remove = server.roles.find {|role| role.name == 'Member'}
member.modify_roles(to_add, to_remove)
# File lib/discordrb/data/member.rb, line 160
def modify_roles(add, remove, reason = nil)
  add_role_ids = role_id_array(add)
  remove_role_ids = role_id_array(remove)
  old_role_ids = resolve_role_ids
  new_role_ids = (old_role_ids - remove_role_ids + add_role_ids).uniq

  API::Server.update_member(@bot.token, @server_id, @user.id, roles: new_role_ids, reason: reason)
end
mute() click to toggle source

@return [true, false] whether this member is muted server-wide.

# File lib/discordrb/data/member.rb, line 31
def mute
  voice_state_attribute(:mute)
end
Also aliased as: muted?
muted?()
Alias for: mute
nick=(nick) click to toggle source

@see Member#set_nick

# File lib/discordrb/data/member.rb, line 269
def nick=(nick)
  set_nick(nick)
end
Also aliased as: nickname=
nickname=(nick)
Alias for: nick=
owner?() click to toggle source

@return [true, false] whether this member is the server owner.

# File lib/discordrb/data/member.rb, line 110
def owner?
  server.owner == self
end
remove_role(role, reason = nil) click to toggle source

Removes one or more roles from this member. @param role [Role, Array<Role>] The role(s) to remove. @param reason [String] The reason the user’s roles are being changed.

# File lib/discordrb/data/member.rb, line 187
def remove_role(role, reason = nil)
  role_ids = role_id_array(role)

  if role_ids.count == 1
    API::Server.remove_member_role(@bot.token, @server_id, @user.id, role_ids[0], reason)
  else
    old_role_ids = resolve_role_ids
    new_role_ids = old_role_ids.reject { |i| role_ids.include?(i) }
    API::Server.update_member(@bot.token, @server_id, @user.id, roles: new_role_ids, reason: reason)
  end
end
role?(role) click to toggle source

@param role [Role, String, Integer] the role to check or its ID. @return [true, false] whether this member has the specified role.

# File lib/discordrb/data/member.rb, line 116
def role?(role)
  role = role.resolve_id
  roles.any?(role)
end
roles() click to toggle source

@return [Array<Role>] the roles this member has. @raise [Discordrb::Errors::NoPermission] This can happen when receiving interactions for servers in which the bot is not

authorized with the `bot` scope.
# File lib/discordrb/data/member.rb, line 97
def roles
  return @roles if @roles

  update_roles(@role_ids)
  @roles
end
roles=(role) click to toggle source

@see Member#set_roles

# File lib/discordrb/data/member.rb, line 122
def roles=(role)
  set_roles(role)
end
self_deaf() click to toggle source

@return [true, false] whether this member has deafened themselves.

# File lib/discordrb/data/member.rb, line 46
def self_deaf
  voice_state_attribute(:self_deaf)
end
Also aliased as: self_deafened?
self_deafened?()
Alias for: self_deaf
self_mute() click to toggle source

@return [true, false] whether this member has muted themselves.

# File lib/discordrb/data/member.rb, line 41
def self_mute
  voice_state_attribute(:self_mute)
end
Also aliased as: self_muted?
self_muted?()
Alias for: self_mute
server() click to toggle source

@return [Server] the server this member is on. @raise [Discordrb::Errors::NoPermission] This can happen when receiving interactions for servers in which the bot is not

authorized with the `bot` scope.
# File lib/discordrb/data/member.rb, line 85
def server
  return @server if @server

  @server = @bot.server(@server_id)
  raise Discordrb::Errors::NoPermission, 'The bot does not have access to this server' unless @server

  @server
end
server_deafen() click to toggle source

Server deafens this member.

# File lib/discordrb/data/member.rb, line 230
def server_deafen
  API::Server.update_member(@bot.token, @server_id, @user.id, deaf: true)
end
server_mute() click to toggle source

Server mutes this member.

# File lib/discordrb/data/member.rb, line 240
def server_mute
  API::Server.update_member(@bot.token, @server_id, @user.id, mute: true)
end
server_undeafen() click to toggle source

Server undeafens this member.

# File lib/discordrb/data/member.rb, line 235
def server_undeafen
  API::Server.update_member(@bot.token, @server_id, @user.id, deaf: false)
end
server_unmute() click to toggle source

Server unmutes this member.

# File lib/discordrb/data/member.rb, line 245
def server_unmute
  API::Server.update_member(@bot.token, @server_id, @user.id, mute: false)
end
set_nick(nick, reason = nil) click to toggle source

Sets or resets this member’s nickname. Requires the Change Nickname permission for the bot itself and Manage Nicknames for other users. @param nick [String, nil] The string to set the nickname to, or nil if it should be reset. @param reason [String] The reason the user’s nickname is being changed.

# File lib/discordrb/data/member.rb, line 279
def set_nick(nick, reason = nil)
  # Discord uses the empty string to signify 'no nickname' so we convert nil into that
  nick ||= ''

  if @user.current_bot?
    API::User.change_own_nickname(@bot.token, @server_id, nick, reason)
  else
    API::Server.update_member(@bot.token, @server_id, @user.id, nick: nick, reason: nil)
  end
end
Also aliased as: set_nickname
set_nickname(nick, reason = nil)
Alias for: set_nick
set_roles(role, reason = nil) click to toggle source

Bulk sets a member’s roles. @param role [Role, Array<Role>] The role(s) to set. @param reason [String] The reason the user’s roles are being changed.

# File lib/discordrb/data/member.rb, line 147
def set_roles(role, reason = nil)
  role_ids = role_id_array(role)
  API::Server.update_member(@bot.token, @server_id, @user.id, roles: role_ids, reason: reason)
end
timeout=(timeout_until)
timeout?()
unban(reason = nil) click to toggle source

Unbans this member from the server. @param reason [String] The reason this member is being unbanned.

# File lib/discordrb/data/member.rb, line 258
def unban(reason = nil)
  server.unban(@user, reason)
end
update_boosting_since(time) click to toggle source

Update this member’s boosting timestamp @note For internal user only. @!visibility private

# File lib/discordrb/data/member.rb, line 320
def update_boosting_since(time)
  @boosting_since = time
end
update_communication_disabled_until(time) click to toggle source

@!visibility private

# File lib/discordrb/data/member.rb, line 325
def update_communication_disabled_until(time)
  time = time ? Time.parse(time) : nil
  @communication_disabled_until = time
end
update_data(data) click to toggle source

Update this member @note For internal use only. @!visibility private

# File lib/discordrb/data/member.rb, line 333
def update_data(data)
  update_roles(data['roles']) if data['roles']
  update_nick(data['nick']) if data.key?('nick')
  @mute = data['mute'] if data.key?('mute')
  @deaf = data['deaf'] if data.key?('deaf')

  @joined_at = Time.parse(data['joined_at']) if data['joined_at']
  timeout_until = data['communication_disabled_until']
  @communication_disabled_until = timeout_until ? Time.parse(timeout_until) : nil
end
update_nick(nick) click to toggle source

Update this member’s nick @note For internal use only. @!visibility private

# File lib/discordrb/data/member.rb, line 313
def update_nick(nick)
  @nick = nick
end
update_roles(role_ids) click to toggle source

Update this member’s roles @note For internal use only. @!visibility private

# File lib/discordrb/data/member.rb, line 300
def update_roles(role_ids)
  @roles = [server.role(@server_id)]
  role_ids.each do |id|
    # It is possible for members to have roles that do not exist
    # on the server any longer. See https://github.com/discordrb/discordrb/issues/371
    role = server.role(id)
    @roles << role if role
  end
end
voice_channel() click to toggle source

@return [Channel] the voice channel this member is in.

# File lib/discordrb/data/member.rb, line 51
def voice_channel
  voice_state_attribute(:voice_channel)
end

Private Instance Methods

resolve_role_ids() click to toggle source
# File lib/discordrb/data/member.rb, line 368
def resolve_role_ids
  @roles ? @roles.collect(&:id) : @role_ids
end
role_id_array(role) click to toggle source

Utility method to get a list of role IDs from one role or an array of roles

# File lib/discordrb/data/member.rb, line 354
def role_id_array(role)
  if role.is_a? Array
    role.map(&:resolve_id)
  else
    [role.resolve_id]
  end
end
voice_state_attribute(name) click to toggle source

Utility method to get data out of this member’s voice state

# File lib/discordrb/data/member.rb, line 363
def voice_state_attribute(name)
  voice_state = server.voice_states[@user.id]
  voice_state&.send name
end