Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions lib/discordrb/api/channel.rb
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,21 @@ def start_typing(token, channel_id)
)
end

# Update the status of a voice channel.
# https://discord.com/developers/docs/resources/channel#set-voice-channel-status
def set_voice_channel_status(token, channel_id, status:, reason: nil)
Discordrb::API.request(
:channels_cid_voice_status,
channel_id,
:put,
"#{Discordrb::API.api_base}/channels/#{channel_id}/voice-status",
{ status: }.to_json,
content_type: :json,
Authorization: token,
'X-Audit-Log-Reason': reason
)
end

# Get a list of pinned messages in a channel
# https://discord.com/developers/docs/resources/message#get-channel-pins
def pinned_messages(token, channel_id, limit = 50, before = nil)
Expand Down
18 changes: 18 additions & 0 deletions lib/discordrb/bot.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1531,6 +1531,24 @@ def handle_dispatch(type, data)
event.channel.process_last_pin_timestamp(data['last_pin_timestamp']) if data.key?('last_pin_timestamp')

raise_event(event)
when :VOICE_CHANNEL_STATUS_UPDATE
@channels[data['id'].to_i]&.process_voice_status(data['status'])

event = ChannelStatusUpdateEvent.new(data, self)
raise_event(event)
when :VOICE_CHANNEL_START_TIME_UPDATE
@channels[data['id'].to_i]&.process_start_time(data['voice_start_time'])

event = ChannelStartTimeUpdateEvent.new(data, self)
raise_event(event)
when :CHANNEL_INFO
data['channels'].each do |inner|
next unless (channel = @channels[inner['id'].to_i])

channel.process_voice_status(inner['status']) if inner.key?('status')

channel.process_start_time(inner['voice_start_time']) if inner.key?('voice_start_time')
end
when :GUILD_MEMBER_ADD
add_guild_member(data)

Expand Down
30 changes: 30 additions & 0 deletions lib/discordrb/container.rb
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,36 @@ def channel_recipient_remove(attributes = {}, &block)
register_event(ChannelRecipientRemoveEvent, attributes, block)
end

# This **event** is raised whenever the status for a voice channel is updated.
# @param attributes [Hash] The event's attributes.
# @option attributes [String, Regexp] :status Matches the new status of the voice channel.
# @option attributes [String, Integer, Server] :server Matches the server where the status was updated.
# @option attributes [String, Integer, Channel] :channel Matches the channel where the status was updated.
# @yield The block is executed when the event is raised.
# @yieldparam event [ChannelStatusUpdateEvent] The event that was raised.
# @return [ChannelStatusUpdateEventHandler] the event handler that was registered.
def channel_status_update(attributes = {}, &block)
register_event(ChannelStatusUpdateEvent, attributes, block)
end

alias_method :voice_channel_status, :channel_status_update

# This **event** is raised whenever the start time for a voice channel is updated.
# @param attributes [Hash] The event's attributes.
# @option attributes [Time] :after Matches a time after the start time of the voice channel.
# @option attributes [Time] :before Matches a time before the start time of the voice channel.
# @option attributes [Time, Integer] :start_time Unix timestamp of the new start time of the voice channel.
# @option attributes [String, Integer, Server] :server Matches the server where the start time was updated.
# @option attributes [String, Integer, Channel] :channel Matches the channel where the start time was updated.
# @yield The block is executed when the event is raised.
# @yieldparam event [ChannelStartTimeUpdateEvent] The event that was raised.
# @return [ChannelStartTimeUpdateEventHandler] the event handler that was registered.
def channel_start_time_update(attributes = {}, &block)
register_event(ChannelStartTimeUpdateEvent, attributes, block)
end

alias_method :voice_channel_start_time, :channel_start_time_update

# This **event** is raised when a user's voice state changes. This includes when a user joins, leaves, or
# moves between voice channels, as well as their mute and deaf status for themselves and on the server.
# @param attributes [Hash] The event's attributes.
Expand Down
11 changes: 10 additions & 1 deletion lib/discordrb/data/audit_logs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ class AuditLogs
166 => :onboarding_create,
167 => :onboarding_update,
190 => :home_settings_create,
191 => :home_settings_update
191 => :home_settings_update,
192 => :voice_channel_status_update,
193 => :voice_channel_status_delete
}.freeze

# @!visibility private
Expand All @@ -94,6 +96,7 @@ class AuditLogs
stage_instance_delete sticker_delete scheduled_event_delete
thread_delete soundboard_sound_delete auto_moderation_rule_delete
onboarding_prompt_delete message_unpin auto_moderation_block_message
voice_channel_status_delete
].freeze

# @!visibility private
Expand All @@ -105,6 +108,7 @@ class AuditLogs
soundboard_sound_update auto_moderation_rule_update onboarding_prompt_update
onboarding_update home_settings_update creator_monetization_terms_accepted
auto_moderation_user_communication_disabled auto_moderation_quarantine_user
voice_channel_status_update
].freeze

# @return [Hash<String => User>] the users included in the audit logs.
Expand Down Expand Up @@ -175,6 +179,9 @@ class Entry
# @return [Symbol, nil] the type of the permission overwrite.
attr_reader :overwrite_type

# @return [String, nil] the new status of the voice channel.
attr_reader :status

# @return [String, nil] the reason for this action occurring.
attr_reader :reason

Expand Down Expand Up @@ -215,6 +222,7 @@ def initialize(logs, server, bot, data)
@overwrite_role_name = options['role_name']
@overwrite_id = options['id']&.to_i
@overwrite_type = Overwrite::TYPES.key(options['type']) if options['type']
@status = options['status'] == '' ? nil : options['status']
end

# @return [Server, Channel, Member, User, Role, Invite, Webhook, Emoji, nil] the target being performed on.
Expand Down Expand Up @@ -418,6 +426,7 @@ def self.target_type_for(action)
when 163..165 then :onboarding_prompt
when 166..167 then :onboarding
when 190..191 then :home_settings
when 192..193 then :voice_channel_status

else :unknown
end
Expand Down
63 changes: 56 additions & 7 deletions lib/discordrb/data/channel.rb
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ def nsfw?
end

# Get the time at when this channel was created at.
# @return [Time, nil] The time at when the channel was created at.
# @return [Time] The time at when the channel was created at.
def creation_time
return @create_timestamp if @create_timestamp

Expand Down Expand Up @@ -991,6 +991,30 @@ def start_thread(name, auto_archive_duration, message: nil, type: 11)
@bot.ensure_channel(JSON.parse(data))
end

# Fetch the status of the voice channel.
# @return [String, nil] The status of the voice channel, or `nil`.
def status
if !instance_variable_defined?(:@status) && voice?
@bot.gateway.send_request_channel_info(@server_id, %i[status voice_start_time])

sleep(0.01) until instance_variable_defined?(:@status)
end

@status
end

# Fetch the start time of the sesison for the voice channel.
# @return [Time, nil] The time at when the voice session started, or `nil`.
def start_time
if !instance_variable_defined?(:@start_time) && voice?
@bot.gateway.send_request_channel_info(@server_id, %i[status voice_start_time])

sleep(0.01) until instance_variable_defined?(:@start_time)
end

@start_time
end

# Start a thread in a forum or media channel.
# @param name [String] The name of the forum post to create.
# @param auto_archive_duration [Integer, nil] How long before the post is automatically archived.
Expand Down Expand Up @@ -1028,6 +1052,8 @@ def start_forum_thread(name:, auto_archive_duration: nil, rate_limit_per_user: n
Message.new(response['message'].merge!('channel_id' => response['id'], 'thread' => response), @bot)
end

# Get the emoji shown on posts in this forum or media channel.
# @return [Emoji, nil] The emoji shown on posts in this forum or media channel, or `nil`.
def default_reaction
@default_reaction.is_a?(Integer) ? server.emojis[@default_reaction] : @default_reaction
end
Expand Down Expand Up @@ -1144,14 +1170,15 @@ def remove_member(member)
# @param position [Integer, nil] The new sorting position of the channel. Generally, this parameter should not be used. Please use {#sort_after} instead.
# @param auto_archive_duration [Integer] The amount of minutes after which the thread will stop showing in the channel list.
# @param default_thread_rate_limit_per_user [Integer] The default slowmode rate to set on threads created in the text or forum channel.
# @param status [String, nil] The status to set for the voice channel; between 1-500 characters, or `nil` to clear the existing status.
# @param reason [String, nil] The reason to show in the server's audit log for modifying the channel.
# @return [nil]
def modify(
name: :undef, type: :undef, topic: :undef, nsfw: :undef, rate_limit_per_user: :undef, bitrate: :undef,
user_limit: :undef, permission_overwrites: :undef, parent: :undef, voice_region: :undef, video_quality_mode: :undef,
default_auto_archive_duration: :undef, flags: :undef, tags: :undef, default_reaction: :undef, default_sort_order: :undef,
default_forum_layout: :undef, archived: :undef, locked: :undef, invitable: :undef, add_flags: :undef, remove_flags: :undef,
position: :undef, auto_archive_duration: :undef, default_thread_rate_limit_per_user: :undef, reason: nil
position: :undef, auto_archive_duration: :undef, default_thread_rate_limit_per_user: :undef, status: :undef, reason: nil
)
data = {
name: name,
Expand Down Expand Up @@ -1179,7 +1206,7 @@ def modify(
}

if tags != :undef && (thread_only? || thread?)
tags = (thread? ? tags&.map(&:resolve_id) : tags&.map(&:to_h))
tags = (thread? ? tags&.map(&:resolve_id)&.uniq : tags&.map(&:to_h))

data[thread_only? ? :available_tags : :applied_tags] = tags
end
Expand All @@ -1204,6 +1231,12 @@ def modify(
data[:flags] = ((@flags & ~to_flags.call(remove_flags)) | to_flags.call(add_flags))
end

if status != :undef && voice?
API::Channel.set_voice_channel_status(@bot.token, @id, status: status, reason: reason)

return unless data.any? { |_, value| value != :undef }
end

update_data(JSON.parse(API::Channel.update!(@bot.token, @id, **data, reason: reason)))
nil
end
Expand All @@ -1214,24 +1247,40 @@ def inspect
end

# Set the last pin timestamp of a channel.
# @param time [String, nil] the time of the last pinned message in the channel
# @param time [String, nil] The time of the last pinned message in the channel.
# @note For internal use only
# @!visibility private
def process_last_pin_timestamp(time)
@last_pin_timestamp = time ? Time.parse(time) : time
end

# Set the last message ID of a channel.
# @param id [Integer, nil] the ID of the last message in a channel
# @param id [Integer, nil] The ID of the last message in a channel.
# @note For internal use only
# @!visibility private
def process_last_message_id(id)
@last_message_id = id
end

# Set the voice channel status of a channel.
# @param status [String, nil] The status of the voice channel.
# @note For internal use only
# @!visibility private
def process_voice_status(status)
@status = status&.empty? ? nil : status
end

# Set the start time of a voice channel.
# @param time [Integer, nil] The start time of the voice channel.
# @note For internal use only
# @!visibility private
def process_start_time(time)
@start_time = time ? Time.at(time) : time
end

# Set the available tags of a channel.
# @param tag [Hash] the data for the tag to create
# @param reason [String, nil] the reason to show in the audit log
# @param tag [Hash] The data for the tag to create.
# @param reason [String, nil] The reason to show in the audit log.
# @note For internal use only
# @!visibility private
def update_tags(tag, reason)
Expand Down
17 changes: 12 additions & 5 deletions lib/discordrb/data/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1506,11 +1506,18 @@ def process_active_threads(threads)
end

def process_incident_actions(incidents)
incidents ||= {}
@raid_detected_at = incidents['raid_detected_at'] ? Time.parse(incidents['raid_detected_at']) : nil
@dms_disabled_until = incidents['dms_disabled_until'] ? Time.parse(incidents['dms_disabled_until']) : nil
@dm_spam_detected_at = incidents['dm_spam_detected_at'] ? Time.parse(incidents['dm_spam_detected_at']) : nil
@invites_disabled_until = incidents['invites_disabled_until'] ? Time.parse(incidents['invites_disabled_until']) : nil
incidents&.each do |key, value|
case key
when 'raid_detected_at'
@raid_detected_at = value ? Time.parse(value) : nil
when 'dms_disabled_until'
@dms_disabled_until = value ? Time.parse(value) : nil
when 'dm_spam_detected_at'
@dm_spam_detected_at = value ? Time.parse(value) : nil
when 'invites_disabled_until'
@invites_disabled_until = value ? Time.parse(value) : nil
end
end
end

def process_scheduled_events(events)
Expand Down
Loading
Loading