Class: Discordrb::Channel

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

Overview

A Discord channel, including data like the topic

Constant Summary collapse

TYPES =

Map of channel types

{
  text: 0,
  dm: 1,
  voice: 2,
  group: 3,
  category: 4
}.freeze

Instance Attribute Summary collapse

Attributes included from IDObject

#id

Instance Method Summary collapse

Methods included from IDObject

#==, #creation_time, synthesise

Instance Attribute Details

#bitrateInteger


1328
1329
1330
# File 'lib/discordrb/data.rb', line 1328

def bitrate
  @bitrate
end

#nameString


1307
1308
1309
# File 'lib/discordrb/data.rb', line 1307

def name
  @name
end

#nsfwtrue, false Also known as: nsfw?


1338
1339
1340
# File 'lib/discordrb/data.rb', line 1338

def nsfw
  @nsfw
end

#owner_idInteger? (readonly)


1319
1320
1321
# File 'lib/discordrb/data.rb', line 1319

def owner_id
  @owner_id
end

#parent_idInteger? (readonly)


1313
1314
1315
# File 'lib/discordrb/data.rb', line 1313

def parent_id
  @parent_id
end

#positionInteger


1335
1336
1337
# File 'lib/discordrb/data.rb', line 1335

def position
  @position
end

#rate_limit_per_userInteger Also known as: slowmode_rate


1342
1343
1344
# File 'lib/discordrb/data.rb', line 1342

def rate_limit_per_user
  @rate_limit_per_user
end

#recipientsArray<Recipient>? (readonly)


1322
1323
1324
# File 'lib/discordrb/data.rb', line 1322

def recipients
  @recipients
end

#serverServer? (readonly)


1310
1311
1312
# File 'lib/discordrb/data.rb', line 1310

def server
  @server
end

#topicString


1325
1326
1327
# File 'lib/discordrb/data.rb', line 1325

def topic
  @topic
end

#typeInteger (readonly)


1316
1317
1318
# File 'lib/discordrb/data.rb', line 1316

def type
  @type
end

#user_limitInteger Also known as: limit


1331
1332
1333
# File 'lib/discordrb/data.rb', line 1331

def user_limit
  @user_limit
end

Instance Method Details

#add_group_users(user_ids) ⇒ Channel Also known as: add_group_user

Adds a user to a group channel.


1933
1934
1935
1936
1937
1938
1939
1940
# File 'lib/discordrb/data.rb', line 1933

def add_group_users(user_ids)
  raise 'Attempted to add a user to a non-group channel!' unless group?
  user_ids = [user_ids] unless user_ids.is_a? Array
  user_ids.each do |user_id|
    API::Channel.add_group_user(@bot.token, @id, user_id.resolve_id)
  end
  self
end

#await(key, attributes = {}, &block) ⇒ Object

Deprecated.

Will be changed to blocking behavior in v4.0. Use #await! instead.

Add an Await for a message in this channel. This is identical in functionality to adding a Events::MessageEvent await with the in attribute as this channel.

See Also:


1885
1886
1887
# File 'lib/discordrb/data.rb', line 1885

def await(key, attributes = {}, &block)
  @bot.add_await(key, Discordrb::Events::MessageEvent, { in: @id }.merge(attributes), &block)
end

#await!(attributes = {}) ⇒ Object

Add a blocking Await for a message in this channel. This is identical in functionality to adding a Events::MessageEvent await with the in attribute as this channel.

See Also:


1892
1893
1894
# File 'lib/discordrb/data.rb', line 1892

def await!(attributes = {})
  @bot.add_await!(Discordrb::Events::MessageEvent, { in: @id }.merge(attributes))
end

#categoryChannel? Also known as: parent


1429
1430
1431
# File 'lib/discordrb/data.rb', line 1429

def category
  @bot.channel(@parent_id) if @parent_id
end

#category=(channel) ⇒ Object Also known as: parent=

Sets this channels parent category

Raises:

  • (ArgumentError)

    if the target channel isn't a category


1438
1439
1440
1441
1442
# File 'lib/discordrb/data.rb', line 1438

def category=(channel)
  channel = @bot.channel(channel)
  raise ArgumentError, 'Cannot set parent category to a channel that isn\'t a category' unless channel.category?
  update_channel_data(parent_id: channel.id)
end

#category?true, false


1424
1425
1426
# File 'lib/discordrb/data.rb', line 1424

def category?
  @type == 4
end

#childrenArray<Channel> Also known as: channels

Returns the children of this channel, if it is a category. Otherwise returns an empty array.


1570
1571
1572
1573
# File 'lib/discordrb/data.rb', line 1570

def children
  return [] unless category?
  server.channels.select { |c| c.parent_id == id }
end

#create_group(user_ids) ⇒ Channel

Creates a Group channel


1923
1924
1925
1926
1927
1928
# File 'lib/discordrb/data.rb', line 1923

def create_group(user_ids)
  raise 'Attempted to create group channel on a non-pm channel!' unless pm?
  response = API::Channel.create_group(@bot.token, @id, user_ids.shift)
  channel = Channel.new(JSON.parse(response), @bot)
  channel.add_group_users(user_ids)
end

#default_channel?true, false Also known as: default?


1600
1601
1602
# File 'lib/discordrb/data.rb', line 1600

def default_channel?
  server.default_channel == self
end

#define_overwrite(overwrite) ⇒ Object #define_overwrite(thing, allow, deny) ⇒ Object

Defines a permission overwrite for this channel that sets the specified thing to the specified allow and deny permission sets, or change an existing one.

Overloads:

  • #define_overwrite(thing, allow, deny) ⇒ Object

    Examples:

    Define a permission overwrite for a user that can then mention everyone and use TTS, but not create any invites

    allow = Discordrb::Permissions.new
    allow.can_mention_everyone = true
    allow.can_send_tts_messages = true
    
    deny = Discordrb::Permissions.new
    deny.can_create_instant_invite = true
    
    channel.define_overwrite(user, allow, deny)
    

1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
# File 'lib/discordrb/data.rb', line 1738

def define_overwrite(thing, allow = 0, deny = 0, reason: nil)
  unless thing.is_a? Overwrite
    allow_bits = allow.respond_to?(:bits) ? allow.bits : allow
    deny_bits = deny.respond_to?(:bits) ? deny.bits : deny

    thing = Overwrite.new thing, allow: allow_bits, deny: deny_bits
  end

  API::Channel.update_permission(@bot.token, @id, thing.id, thing.allow.bits, thing.deny.bits, thing.type, reason)
end

#delete(reason = nil) ⇒ Object

Permanently deletes this channel


1678
1679
1680
# File 'lib/discordrb/data.rb', line 1678

def delete(reason = nil)
  API::Channel.delete(@bot.token, @id, reason)
end

#delete_message(message) ⇒ Object

Deletes a message on this channel. Mostly useful in case a message needs to be deleted when only the ID is known


1672
1673
1674
# File 'lib/discordrb/data.rb', line 1672

def delete_message(message)
  API::Channel.delete_message(@bot.token, @id, message.resolve_id)
end

#delete_messages(messages, strict = false) ⇒ Integer

Deletes a collection of messages

Raises:

  • (ArgumentError)

    if the amount of messages is not a value between 2 and 100


1867
1868
1869
1870
1871
1872
# File 'lib/discordrb/data.rb', line 1867

def delete_messages(messages, strict = false)
  raise ArgumentError, 'Can only delete between 2 and 100 messages!' unless messages.count.between?(2, 100)

  messages.map!(&:resolve_id)
  bulk_delete(messages, strict)
end

#delete_overwrite(target, reason = nil) ⇒ Object

Deletes a permission overwrite for this channel


1752
1753
1754
1755
1756
# File 'lib/discordrb/data.rb', line 1752

def delete_overwrite(target, reason = nil)
  raise 'Tried deleting a overwrite for an invalid target' unless target.is_a?(Member) || target.is_a?(User) || target.is_a?(Role) || target.is_a?(Profile) || target.is_a?(Recipient) || target.respond_to?(:resolve_id)

  API::Channel.delete_permission(@bot.token, @id, target.resolve_id, reason)
end

#group?true, false


1419
1420
1421
# File 'lib/discordrb/data.rb', line 1419

def group?
  @type == 3
end

#history(amount, before_id = nil, after_id = nil, around_id = nil) ⇒ Array<Message>

Retrieves some of this channel's message history.

Examples:

Count the number of messages in the last 50 messages that contain the letter 'e'.

message_count = channel.history(50).count {|message| message.content.include? "e"}

Get the last 10 messages before the provided message.

last_ten_messages = channel.history(10, message.id)

1799
1800
1801
1802
# File 'lib/discordrb/data.rb', line 1799

def history(amount, before_id = nil, after_id = nil, around_id = nil)
  logs = API::Channel.messages(@bot.token, @id, amount, before_id, after_id, around_id)
  JSON.parse(logs).map { |message| Message.new(message, @bot) }
end

#inspectObject

The default inspect method is overwritten to give more useful output.


1983
1984
1985
# File 'lib/discordrb/data.rb', line 1983

def inspect
  "<Channel name=#{@name} id=#{@id} topic=\"#{@topic}\" type=#{@type} position=#{@position} server=#{@server}>"
end

#invitesArray<Invite>

Requests a list of Invites to the channel.


1976
1977
1978
1979
1980
# File 'lib/discordrb/data.rb', line 1976

def invites
  raise 'Tried to request invites from a non-server channel' unless server
  invites = JSON.parse(API::Channel.invites(@bot.token, @id))
  invites.map { |invite_data| Invite.new(invite_data, @bot) }
end

#leave_groupObject Also known as: leave

Leaves the group.


1959
1960
1961
1962
# File 'lib/discordrb/data.rb', line 1959

def leave_group
  raise 'Attempted to leave a non-group channel!' unless group?
  API::Channel.leave_group(@bot.token, @id)
end

#load_message(message_id) ⇒ Message? Also known as: message

Returns a single message from this channel's history by ID.


1815
1816
1817
1818
1819
1820
# File 'lib/discordrb/data.rb', line 1815

def load_message(message_id)
  response = API::Channel.message(@bot.token, @id, message_id)
  return Message.new(JSON.parse(response), @bot)
rescue RestClient::ResourceNotFound
  return nil
end

#make_invite(max_age = 0, max_uses = 0, temporary = false, unique = false, reason = nil) ⇒ Invite Also known as: invite

Creates a new invite to this channel.


1903
1904
1905
1906
# File 'lib/discordrb/data.rb', line 1903

def make_invite(max_age = 0, max_uses = 0, temporary = false, unique = false, reason = nil)
  response = API::Channel.create_invite(@bot.token, @id, max_age, max_uses, temporary, unique, reason)
  Invite.new(JSON.parse(response), @bot)
end

#member_overwritesOverwrite


1590
1591
1592
# File 'lib/discordrb/data.rb', line 1590

def member_overwrites
  permission_overwrites :member
end

#mentionString


1351
1352
1353
# File 'lib/discordrb/data.rb', line 1351

def mention
  "<##{@id}>"
end

#permission_overwritesHash<Integer => Overwrite> #permission_overwrites(type) ⇒ Array<Overwrite> Also known as: overwrites

This channel's permission overwrites

Overloads:

  • #permission_overwritesHash<Integer => Overwrite>

    The overwrites represented as a hash of role/user ID to an Overwrite object

  • #permission_overwrites(type) ⇒ Array<Overwrite>

    Return an array of a certain type of overwrite


1528
1529
1530
1531
# File 'lib/discordrb/data.rb', line 1528

def permission_overwrites(type = nil)
  return @permission_overwrites unless type
  @permission_overwrites.values.select { |e| e.type == type }
end

#permission_overwrites=(overwrites) ⇒ Object

Bulk sets this channels permission overwrites


1537
1538
1539
# File 'lib/discordrb/data.rb', line 1537

def permission_overwrites=(overwrites)
  update_channel_data(permission_overwrites: overwrites)
end

#pinsArray<Message>

Requests all pinned messages in a channel.


1826
1827
1828
1829
# File 'lib/discordrb/data.rb', line 1826

def pins
  msgs = API::Channel.pinned_messages(@bot.token, @id)
  JSON.parse(msgs).map { |msg| Message.new(msg, @bot) }
end

#pm?true, false


1409
1410
1411
# File 'lib/discordrb/data.rb', line 1409

def pm?
  @type == 1
end

#private?true, false


1346
1347
1348
# File 'lib/discordrb/data.rb', line 1346

def private?
  pm? || group?
end

#prune(amount, strict = false) {|message| ... } ⇒ Integer

Delete the last N messages on this channel.

Examples:

Pruning messages from a specific user ID

channel.prune(100) { |m| m.author.id == 83283213010599936 }

Yields:

  • (message)

    Yields each message in this channels history for filtering the messages to delete

Raises:

  • (ArgumentError)

    if the amount of messages is not a value between 2 and 100


1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
# File 'lib/discordrb/data.rb', line 1840

def prune(amount, strict = false, &block)
  raise ArgumentError, 'Can only delete between 1 and 100 messages!' unless amount.between?(1, 100)

  messages =
    if block_given?
      history(amount).select(&block).map(&:id)
    else
      history_ids(amount)
    end

  case messages.size
  when 0
    0
  when 1
    API::Channel.delete_message(@bot.token, @id, messages.first)
    1
  else
    bulk_delete(messages, strict)
  end
end

#recipientRecipient?


1356
1357
1358
# File 'lib/discordrb/data.rb', line 1356

def recipient
  @recipients.first if pm?
end

#remove_group_users(user_ids) ⇒ Channel Also known as: remove_group_user

Removes a user from a group channel.


1947
1948
1949
1950
1951
1952
1953
1954
# File 'lib/discordrb/data.rb', line 1947

def remove_group_users(user_ids)
  raise 'Attempted to remove a user from a non-group channel!' unless group?
  user_ids = [user_ids] unless user_ids.is_a? Array
  user_ids.each do |user_id|
    API::Channel.remove_group_user(@bot.token, @id, user_id.resolve_id)
  end
  self
end

#role_overwritesOverwrite


1595
1596
1597
# File 'lib/discordrb/data.rb', line 1595

def role_overwrites
  permission_overwrites :role
end

#send_embed(message = '', embed = nil) {|embed| ... } ⇒ Message

Convenience method to send a message with an embed.

Examples:

Send a message with an embed

channel.send_embed do |embed|
  embed.title = 'The Ruby logo'
  embed.image = Discordrb::Webhooks::EmbedImage.new(url: 'https://www.ruby-lang.org/images/header-ruby-logo.png')
end

Yields:

  • (embed)

    Yields the embed to allow for easy building inside a block.

Yield Parameters:

  • embed (Discordrb::Webhooks::Embed)

    The embed from the parameters, or a new one.


1642
1643
1644
1645
1646
# File 'lib/discordrb/data.rb', line 1642

def send_embed(message = '', embed = nil)
  embed ||= Discordrb::Webhooks::Embed.new
  yield(embed) if block_given?
  send_message(message, false, embed)
end

#send_file(file, caption: nil, tts: false) ⇒ Object

Sends a file to this channel. If it is an image, it will be embedded.

Examples:

Send a file from disk

channel.send_file(File.open('rubytaco.png', 'r'))

1666
1667
1668
# File 'lib/discordrb/data.rb', line 1666

def send_file(file, caption: nil, tts: false)
  @bot.send_file(@id, file, caption: caption, tts: tts)
end

#send_message(content, tts = false, embed = nil) ⇒ Message Also known as: send

Sends a message to this channel.


1616
1617
1618
# File 'lib/discordrb/data.rb', line 1616

def send_message(content, tts = false, embed = nil)
  @bot.send_message(@id, content, tts, embed)
end

#send_multiple(content) ⇒ Object

Sends multiple messages to a channel


1650
1651
1652
# File 'lib/discordrb/data.rb', line 1650

def send_multiple(content)
  content.each { |e| send_message(e) }
end

#send_temporary_message(content, timeout, tts = false, embed = nil) ⇒ Object

Sends a temporary message to this channel.


1627
1628
1629
# File 'lib/discordrb/data.rb', line 1627

def send_temporary_message(content, timeout, tts = false, embed = nil)
  @bot.send_temporary_message(@id, content, timeout, tts, embed)
end

#slowmode?true, false


1607
1608
1609
# File 'lib/discordrb/data.rb', line 1607

def slowmode?
  @rate_limit_per_user != 0
end

#sort_after(other = nil, lock_permissions = false) ⇒ Object

Sorts this channel's position to follow another channel.

Raises:

  • (TypeError)

1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
# File 'lib/discordrb/data.rb', line 1451

def sort_after(other = nil, lock_permissions = false)
  raise TypeError, 'other must be one of Channel, NilClass, or #resolve_id' unless other.is_a?(Channel) || other.nil? || other.respond_to?(:resolve_id)
  other = @bot.channel(other.resolve_id) if other

  # Container for the API request payload
  move_argument = []

  if other
    raise ArgumentError, 'Can only sort a channel after a channel of the same type!' unless other.category? || (@type == other.type)

    raise ArgumentError, 'Can only sort a channel after a channel in the same server!' unless other.server == server

    # Store `others` parent (or if `other` is a category itself)
    parent = if category? && other.category?
               # If we're sorting two categories, there is no new parent
               nil
             elsif other.category?
               # `other` is the category this channel will be moved into
               other
             else
               # `other`'s parent is the category this channel will be
               # moved into (if it exists)
               other.parent
             end
  end

  # Collect and sort the IDs within the context (category or not) that we
  # need to form our payload with
  ids = if parent
          parent.children
        else
          @server.channels.reject(&:parent_id).select { |c| c.type == @type }
        end.sort_by(&:position).map(&:id)

  # Move our channel ID after the target ID by deleting it,
  # getting the index of `other`, and inserting it after.
  ids.delete(@id) if ids.include?(@id)
  index = other ? (ids.index { |c| c == other.id } || -1) + 1 : 0
  ids.insert(index, @id)

  # Generate `move_argument`, making the positions in order from how
  # we have sorted them in the above logic
  ids.each_with_index do |id, pos|
    # These keys are present in each element
    hash = { id: id, position: pos }

    # Conditionally add `lock_permissions` and `parent_id` if we're
    # iterating past ourself
    if id == @id
      hash[:lock_permissions] = true if lock_permissions
      hash[:parent_id] = parent.nil? ? nil : parent.id
    end

    # Add it to the stack
    move_argument << hash
  end

  API::Server.update_channel_positions(@bot.token, @server.id, move_argument)
end

#split_send(content) ⇒ Object

Splits a message into chunks whose length is at most the Discord character limit, then sends them individually. Useful for sending long messages, but be wary of rate limits!


1656
1657
1658
# File 'lib/discordrb/data.rb', line 1656

def split_send(content)
  send_multiple(Discordrb.split_message(content))
end

#start_typingObject

Starts typing, which displays the typing indicator on the client for five seconds. If you want to keep typing you'll have to resend this every five seconds. (An abstraction for this will eventually be coming)

Examples:

Send a typing indicator for the bot in a given channel.

channel.start_typing()

1915
1916
1917
# File 'lib/discordrb/data.rb', line 1915

def start_typing
  API::Channel.start_typing(@bot.token, @id)
end

#sync_overwritesObject Also known as: sync

Syncs this channels overwrites with its parent category

Raises:

  • (RuntimeError)

    if this channel is not in a category


1553
1554
1555
1556
# File 'lib/discordrb/data.rb', line 1553

def sync_overwrites
  raise 'Cannot sync overwrites on a channel with no parent category' unless parent
  self.permission_overwrites = parent.permission_overwrites
end

#synchronized?true, ... Also known as: synced?


1561
1562
1563
1564
# File 'lib/discordrb/data.rb', line 1561

def synchronized?
  return unless parent
  permission_overwrites == parent.permission_overwrites
end

#text?true, false


1404
1405
1406
# File 'lib/discordrb/data.rb', line 1404

def text?
  @type.zero?
end

#text_channelsArray<Channel>

Returns the text channels in this category, if it is a category channel. Otherwise returns an empty array.


1579
1580
1581
# File 'lib/discordrb/data.rb', line 1579

def text_channels
  children.select(&:text?)
end

#usersArray<Member>

The list of users currently in this channel. For a voice channel, it will return all the members currently in that channel. For a text channel, it will return all online members that have permission to read it.


1778
1779
1780
1781
1782
1783
1784
# File 'lib/discordrb/data.rb', line 1778

def users
  if text?
    @server.online_members(include_idle: true).select { |u| u.can_read_messages? self }
  elsif voice?
    @server.voice_states.map { |id, voice_state| @server.member(id) if !voice_state.voice_channel.nil? && voice_state.voice_channel.id == @id }.compact
  end
end

#voice?true, false


1414
1415
1416
# File 'lib/discordrb/data.rb', line 1414

def voice?
  @type == 2
end

#voice_channelsArray<Channel>

Returns the voice channels in this category, if it is a category channel. Otherwise returns an empty array.


1585
1586
1587
# File 'lib/discordrb/data.rb', line 1585

def voice_channels
  children.select(&:voice?)
end

#webhooksArray<Webhook>

Requests a list of Webhooks on the channel.


1968
1969
1970
1971
1972
# File 'lib/discordrb/data.rb', line 1968

def webhooks
  raise 'Tried to request webhooks from a non-server channel' unless server
  webhooks = JSON.parse(API::Channel.webhooks(@bot.token, @id))
  webhooks.map { |webhook_data| Webhook.new(webhook_data, @bot) }
end