Class: DiscordRDA::Channel

Inherits:
Entity
  • Object
show all
Defined in:
lib/discord_rda/entity/channel.rb

Overview

Represents a Discord channel. Can be text, voice, category, DM, thread, etc.

Constant Summary collapse

TYPES =

Channel types

{
  guild_text: 0,
  dm: 1,
  guild_voice: 2,
  group_dm: 3,
  guild_category: 4,
  guild_announcement: 5,
  announcement_thread: 10,
  public_thread: 11,
  private_thread: 12,
  guild_stage_voice: 13,
  guild_directory: 14,
  guild_forum: 15,
  guild_media: 16
}.freeze

Class Attribute Summary collapse

Attributes inherited from Entity

#id

Instance Method Summary collapse

Methods inherited from Entity

#==, attribute, from_hash, #hash, #initialize, #inspect, #to_h, #to_json

Constructor Details

This class inherits a constructor from DiscordRDA::Entity

Class Attribute Details

.apiObject

Returns the value of attribute api.



60
61
62
# File 'lib/discord_rda/entity/channel.rb', line 60

def api
  @api
end

Instance Method Details

#active?Boolean

Check if the channel is considered active (has recent messages)

Returns:

  • (Boolean)

    True if active



255
256
257
258
# File 'lib/discord_rda/entity/channel.rb', line 255

def active?
  return false unless last_message_id
  last_message_at > Time.now - 86400 # Active within last 24 hours
end

#announcement?Boolean

Check if this is an announcement channel

Returns:

  • (Boolean)

    True if announcement



119
120
121
# File 'lib/discord_rda/entity/channel.rb', line 119

def announcement?
  type == 5
end

#archive_timestampTime?

Get thread archive timestamp

Returns:

  • (Time, nil)

    Archive timestamp



181
182
183
184
# File 'lib/discord_rda/entity/channel.rb', line 181

def archive_timestamp
  ts = &.dig('archive_timestamp')
  Time.parse(ts) if ts
end

#archived?Boolean?

Check if thread is archived

Returns:

  • (Boolean, nil)

    True if archived



175
176
177
# File 'lib/discord_rda/entity/channel.rb', line 175

def archived?
  &.dig('archived')
end

#auto_archive_daysInteger

Get the default auto archive duration in days

Returns:

  • (Integer)

    Days



275
276
277
# File 'lib/discord_rda/entity/channel.rb', line 275

def auto_archive_days
  (default_auto_archive_duration || 4320) / 1440 # Convert minutes to days, default 3 days
end

#auto_archive_durationInteger?

Get auto archive duration in minutes

Returns:

  • (Integer, nil)

    Auto archive duration



169
170
171
# File 'lib/discord_rda/entity/channel.rb', line 169

def auto_archive_duration
  default_auto_archive_duration
end

#category?Boolean

Check if this is a category

Returns:

  • (Boolean)

    True if category



95
96
97
# File 'lib/discord_rda/entity/channel.rb', line 95

def category?
  type == 4
end

#category_idSnowflake?

Get the category (parent) ID

Returns:



151
152
153
# File 'lib/discord_rda/entity/channel.rb', line 151

def category_id
  parent_id if category?
end

#channel_typeSymbol

Get channel type as symbol

Returns:

  • (Symbol)

    Channel type



65
66
67
# File 'lib/discord_rda/entity/channel.rb', line 65

def channel_type
  TYPES.key(type) || :unknown
end

#created_atTime

Get created_at from snowflake

Returns:

  • (Time)

    Channel creation time



200
201
202
# File 'lib/discord_rda/entity/channel.rb', line 200

def created_at
  id.timestamp
end

#directory?Boolean

Check if this is a directory channel

Returns:

  • (Boolean)

    True if directory



214
215
216
# File 'lib/discord_rda/entity/channel.rb', line 214

def directory?
  type == 14
end

#display_nameString

Get formatted name with type indicator

Returns:

  • (String)

    Formatted name



244
245
246
247
248
249
250
251
# File 'lib/discord_rda/entity/channel.rb', line 244

def display_name
  case type
  when 0, 5 then "# #{name}"
  when 2, 13 then "🔊 #{name}"
  when 4 then "📁 #{name}"
  else name
  end
end

#dm?Boolean

Check if this is a DM channel

Returns:

  • (Boolean)

    True if DM



83
84
85
# File 'lib/discord_rda/entity/channel.rb', line 83

def dm?
  type == 1
end

#fetch_all_messages(max: nil, batch_size: 100, direction: :backwards) {|Message| ... } ⇒ Array<Message>

Fetch all messages from the channel with automatic pagination

Parameters:

  • max (Integer) (defaults to: nil)

    Maximum messages to fetch (nil for all)

  • batch_size (Integer) (defaults to: 100)

    Messages per request (1-100)

  • direction (Symbol) (defaults to: :backwards)

    :backwards (older first) or :forwards (newer first)

Yields:

  • (Message)

    Optional block called for each message

Returns:

  • (Array<Message>)

    All fetched messages



303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
# File 'lib/discord_rda/entity/channel.rb', line 303

def fetch_all_messages(max: nil, batch_size: 100, direction: :backwards)
  return [] unless self.class.api

  messages = []
  last_id = nil

  loop do
    batch = if direction == :forwards
              fetch_messages(limit: batch_size, after: last_id)
            else
              fetch_messages(limit: batch_size, before: last_id)
            end

    break if batch.empty?

    batch.each do |message|
      messages << message
      yield message if block_given?

      return messages if max && messages.length >= max
    end

    last_id = direction == :forwards ? batch.last.id : batch.last.id

    # Stop if we got fewer messages than requested (reached the end)
    break if batch.length < batch_size
  end

  messages
end

#fetch_messages(limit: 50, before: nil, after: nil, around: nil) ⇒ Array<Message>

Fetch messages from the channel with pagination support

Parameters:

  • limit (Integer) (defaults to: 50)

    Number of messages (1-100, default 50)

  • before (String, Snowflake) (defaults to: nil)

    Get messages before this message ID

  • after (String, Snowflake) (defaults to: nil)

    Get messages after this message ID

  • around (String, Snowflake) (defaults to: nil)

    Get messages around this message ID (returns 25 before + 25 after)

Returns:



285
286
287
288
289
290
291
292
293
294
295
# File 'lib/discord_rda/entity/channel.rb', line 285

def fetch_messages(limit: 50, before: nil, after: nil, around: nil)
  return [] unless self.class.api

  params = { limit: limit }
  params[:before] = before.to_s if before
  params[:after] = after.to_s if after
  params[:around] = around.to_s if around

  data = self.class.api.get("/channels/#{id}/messages", params: params)
  data.map { |m| Message.new(m) }
end

#forum?Boolean

Check if this is a forum channel

Returns:

  • (Boolean)

    True if forum



107
108
109
# File 'lib/discord_rda/entity/channel.rb', line 107

def forum?
  type == 15
end

#group_dm?Boolean

Check if this is a group DM

Returns:

  • (Boolean)

    True if group DM



89
90
91
# File 'lib/discord_rda/entity/channel.rb', line 89

def group_dm?
  type == 3
end

#invitable?Boolean?

Check if thread is invitable

Returns:

  • (Boolean, nil)

    True if invitable



194
195
196
# File 'lib/discord_rda/entity/channel.rb', line 194

def invitable?
  &.dig('invitable')
end

#jump_url(guild_id: nil) ⇒ String

Get the jump URL for this channel

Parameters:

  • guild_id (Snowflake, String) (defaults to: nil)

    Optional guild ID

Returns:

  • (String)

    Jump URL



132
133
134
135
# File 'lib/discord_rda/entity/channel.rb', line 132

def jump_url(guild_id: nil)
  gid = guild_id || self.guild_id
  "https://discord.com/channels/#{gid}/#{id}"
end

#last_message_ageFloat?

Get the age of the last message

Returns:

  • (Float, nil)

    Seconds since last message



262
263
264
265
# File 'lib/discord_rda/entity/channel.rb', line 262

def last_message_age
  return nil unless last_message_at
  Time.now - last_message_at
end

#last_message_atTime?

Get last message timestamp

Returns:

  • (Time, nil)

    Last message time



139
140
141
# File 'lib/discord_rda/entity/channel.rb', line 139

def last_message_at
  last_message_id&.timestamp
end

#locked?Boolean?

Check if thread is locked

Returns:

  • (Boolean, nil)

    True if locked



188
189
190
# File 'lib/discord_rda/entity/channel.rb', line 188

def locked?
  &.dig('locked')
end

#media?Boolean

Check if this is a media channel

Returns:

  • (Boolean)

    True if media channel



113
114
115
# File 'lib/discord_rda/entity/channel.rb', line 113

def media?
  type == 16
end

#mentionString

Get mention string for the channel

Returns:

  • (String)

    Channel mention



125
126
127
# File 'lib/discord_rda/entity/channel.rb', line 125

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

#mention_with_prefixString

Get mention string for the channel with type indicator

Returns:

  • (String)

    Channel mention with ‘#’ prefix for text channels



238
239
240
# File 'lib/discord_rda/entity/channel.rb', line 238

def mention_with_prefix
  text? ? "<##{id}>" : mention
end

#messages_iterator(batch_size: 100, direction: :backwards) ⇒ MessageIterator

Create an iterator for fetching messages

Parameters:

  • batch_size (Integer) (defaults to: 100)

    Messages per request (1-100)

  • direction (Symbol) (defaults to: :backwards)

    :backwards (older first) or :forwards (newer first)

Returns:



338
339
340
# File 'lib/discord_rda/entity/channel.rb', line 338

def messages_iterator(batch_size: 100, direction: :backwards)
  MessageIterator.new(self, batch_size: batch_size, direction: direction)
end

#news?Boolean

Check if this is a news/announcement channel

Returns:

  • (Boolean)

    True if news channel



269
270
271
# File 'lib/discord_rda/entity/channel.rb', line 269

def news?
  type == 5
end

#nsfw?Boolean

Check if channel is NSFW

Returns:

  • (Boolean)

    True if NSFW



145
146
147
# File 'lib/discord_rda/entity/channel.rb', line 145

def nsfw?
  nsfw
end

#permission_overwritesPermission?

Get permissions as Permission object

Returns:



206
207
208
209
210
# File 'lib/discord_rda/entity/channel.rb', line 206

def permission_overwrites
  return nil unless permissions

  Permission.new(permissions.to_i)
end

#search_messages(content: nil, author_id: nil, limit: 1000) ⇒ Array<Message>

Search for messages by content (client-side filtering) Note: Discord API doesn’t support server-side message search, this fetches and filters

Parameters:

  • content (String) (defaults to: nil)

    Content to search for

  • author_id (String) (defaults to: nil)

    Filter by author ID

  • limit (Integer) (defaults to: 1000)

    Maximum messages to search

Returns:

  • (Array<Message>)

    Matching messages



348
349
350
351
352
353
354
355
356
357
358
359
360
361
# File 'lib/discord_rda/entity/channel.rb', line 348

def search_messages(content: nil, author_id: nil, limit: 1000)
  return [] unless self.class.api

  results = []

  fetch_all_messages(max: limit) do |message|
    next if content && !message.content.to_s.downcase.include?(content.downcase)
    next if author_id && message.author&.id.to_s != author_id.to_s

    results << message
  end

  results
end

#slowmode?Boolean

Check if slowmode is enabled

Returns:

  • (Boolean)

    True if slowmode enabled



226
227
228
# File 'lib/discord_rda/entity/channel.rb', line 226

def slowmode?
  rate_limit_per_user.to_i > 0
end

#slowmode_delayInteger

Get slowmode delay in seconds

Returns:

  • (Integer)

    Rate limit per user



220
221
222
# File 'lib/discord_rda/entity/channel.rb', line 220

def slowmode_delay
  rate_limit_per_user || 0
end

#stage?Boolean

Check if this is a stage channel

Returns:

  • (Boolean)

    True if stage



157
158
159
# File 'lib/discord_rda/entity/channel.rb', line 157

def stage?
  type == 13
end

#synced?Boolean?

Check if channel is synced with category permissions

Returns:

  • (Boolean, nil)

    True if synced



232
233
234
# File 'lib/discord_rda/entity/channel.rb', line 232

def synced?
  @raw_data['parent_id'] && @raw_data['permission_overwrites']&.empty?
end

#text?Boolean

Check if this is a text channel

Returns:

  • (Boolean)

    True if text channel



71
72
73
# File 'lib/discord_rda/entity/channel.rb', line 71

def text?
  type == 0 || type == 5
end

#thread?Boolean

Check if this is a thread

Returns:

  • (Boolean)

    True if thread



101
102
103
# File 'lib/discord_rda/entity/channel.rb', line 101

def thread?
  type == 10 || type == 11 || type == 12
end

#video_quality_mode_nameString

Get video quality mode name

Returns:

  • (String)

    Video quality mode



163
164
165
# File 'lib/discord_rda/entity/channel.rb', line 163

def video_quality_mode_name
  video_quality_mode == 2 ? 'full' : 'auto'
end

#voice?Boolean

Check if this is a voice channel

Returns:

  • (Boolean)

    True if voice channel



77
78
79
# File 'lib/discord_rda/entity/channel.rb', line 77

def voice?
  type == 2 || type == 13
end