Skip to content

Commit

Permalink
Merge pull request #292 from Droid00000/flags
Browse files Browse the repository at this point in the history
Message Flags
  • Loading branch information
swarley authored Jan 7, 2025
2 parents 972fdd6 + f7073a0 commit 6a8ea12
Show file tree
Hide file tree
Showing 11 changed files with 64 additions and 41 deletions.
8 changes: 4 additions & 4 deletions lib/discordrb/api/channel.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ def message(token, channel_id, message_id)
# https://discord.com/developers/docs/resources/channel#create-message
# @param attachments [Array<File>, nil] Attachments to use with `attachment://` in embeds. See
# https://discord.com/developers/docs/resources/channel#create-message-using-attachments-within-embeds
def create_message(token, channel_id, message, tts = false, embeds = nil, nonce = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil)
body = { content: message, tts: tts, embeds: embeds, nonce: nonce, allowed_mentions: allowed_mentions, message_reference: message_reference, components: components&.to_a }
def create_message(token, channel_id, message, tts = false, embeds = nil, nonce = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil, flags = nil)
body = { content: message, tts: tts, embeds: embeds, nonce: nonce, allowed_mentions: allowed_mentions, message_reference: message_reference, components: components&.to_a, flags: flags }
body = if attachments
files = [*0...attachments.size].zip(attachments).to_h
{ **files, payload_json: body.to_json }
Expand Down Expand Up @@ -117,13 +117,13 @@ def upload_file(token, channel_id, file, caption: nil, tts: false)

# Edit a message
# https://discord.com/developers/docs/resources/channel#edit-message
def edit_message(token, channel_id, message_id, message, mentions = [], embeds = nil, components = nil)
def edit_message(token, channel_id, message_id, message, mentions = [], embeds = nil, components = nil, flags = nil)
Discordrb::API.request(
:channels_cid_messages_mid,
channel_id,
:patch,
"#{Discordrb::API.api_base}/channels/#{channel_id}/messages/#{message_id}",
{ content: message, mentions: mentions, embeds: embeds, components: components }.to_json,
{ content: message, mentions: mentions, embeds: embeds, components: components, flags: flags }.reject { |_, v| v == :undef }.to_json,
Authorization: token,
content_type: :json
)
Expand Down
12 changes: 7 additions & 5 deletions lib/discordrb/bot.rb
Original file line number Diff line number Diff line change
Expand Up @@ -401,15 +401,16 @@ def delete_invite(code)
# @param allowed_mentions [Hash, Discordrb::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
# @param message_reference [Message, String, Integer, nil] The message, or message ID, to reply to if any.
# @param components [View, Array<Hash>] Interaction components to associate with this message.
# @param flags [Integer] Flags for this message. Currently only SUPPRESS_EMBEDS (1 << 2) and SUPPRESS_NOTIFICATIONS (1 << 12) can be set.
# @return [Message] The message that was sent.
def send_message(channel, content, tts = false, embeds = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil)
def send_message(channel, content, tts = false, embeds = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil, flags = 0)
channel = channel.resolve_id
debug("Sending message to #{channel} with content '#{content}'")
allowed_mentions = { parse: [] } if allowed_mentions == false
message_reference = { message_id: message_reference.id } if message_reference.respond_to?(:id)
embeds = (embeds.instance_of?(Array) ? embeds.map(&:to_hash) : [embeds&.to_hash]).compact

response = API::Channel.create_message(token, channel, content, tts, embeds, nil, attachments, allowed_mentions&.to_hash, message_reference, components)
response = API::Channel.create_message(token, channel, content, tts, embeds, nil, attachments, allowed_mentions&.to_hash, message_reference, components, flags)
Message.new(JSON.parse(response), self)
end

Expand All @@ -424,11 +425,12 @@ def send_message(channel, content, tts = false, embeds = nil, attachments = nil,
# @param allowed_mentions [Hash, Discordrb::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
# @param message_reference [Message, String, Integer, nil] The message, or message ID, to reply to if any.
# @param components [View, Array<Hash>] Interaction components to associate with this message.
def send_temporary_message(channel, content, timeout, tts = false, embeds = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil)
# @param flags [Integer] Flags for this message. Currently only SUPPRESS_EMBEDS (1 << 2) and SUPPRESS_NOTIFICATIONS (1 << 12) can be set.
def send_temporary_message(channel, content, timeout, tts = false, embeds = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil, flags = 0)
Thread.new do
Thread.current[:discordrb_name] = "#{@current_thread}-temp-msg"

message = send_message(channel, content, tts, embeds, attachments, allowed_mentions, message_reference, components)
message = send_message(channel, content, tts, embeds, attachments, allowed_mentions, message_reference, components, flags)
sleep(timeout)
message.delete
end
Expand Down Expand Up @@ -1219,7 +1221,7 @@ def process_token(type, token)

def handle_dispatch(type, data)
# Check whether there are still unavailable servers and there have been more than 10 seconds since READY
if @unavailable_servers&.positive? && (Time.now - @unavailable_timeout_time) > 10 && !((@intents || 0) & INTENTS[:servers]).zero?
if @unavailable_servers&.positive? && (Time.now - @unavailable_timeout_time) > 10 && !(@intents || 0).nobits?(INTENTS[:servers])
# The server streaming timed out!
LOGGER.debug("Server streaming timed out with #{@unavailable_servers} servers remaining")
LOGGER.debug('Calling ready now because server loading is taking a long time. Servers may be unavailable due to an outage, or your bot is on very large servers.')
Expand Down
2 changes: 1 addition & 1 deletion lib/discordrb/data/activity.rb
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def instance?

# @!visibility private
def flag_set?(sym)
!(@flags & FLAGS[sym]).zero?
!@flags.nobits?(FLAGS[sym])
end

# Timestamps for the start and end of instanced activities
Expand Down
15 changes: 9 additions & 6 deletions lib/discordrb/data/channel.rb
Original file line number Diff line number Diff line change
Expand Up @@ -428,9 +428,10 @@ def slowmode?
# @param allowed_mentions [Hash, Discordrb::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
# @param message_reference [Message, String, Integer, nil] The message, or message ID, to reply to if any.
# @param components [View, Array<Hash>] Interaction components to associate with this message.
# @param flags [Integer] Flags for this message. Currently only SUPPRESS_EMBEDS (1 << 2) and SUPPRESS_NOTIFICATIONS (1 << 12) can be set.
# @return [Message] the message that was sent.
def send_message(content, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil)
@bot.send_message(@id, content, tts, embed, attachments, allowed_mentions, message_reference, components)
def send_message(content, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil, flags = 0)
@bot.send_message(@id, content, tts, embed, attachments, allowed_mentions, message_reference, components, flags)
end

alias_method :send, :send_message
Expand All @@ -444,8 +445,9 @@ def send_message(content, tts = false, embed = nil, attachments = nil, allowed_m
# @param allowed_mentions [Hash, Discordrb::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
# @param message_reference [Message, String, Integer, nil] The message, or message ID, to reply to if any.
# @param components [View, Array<Hash>] Interaction components to associate with this message.
def send_temporary_message(content, timeout, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil)
@bot.send_temporary_message(@id, content, timeout, tts, embed, attachments, allowed_mentions, message_reference, components)
# @param flags [Integer] Flags for this message. Currently only SUPPRESS_EMBEDS (1 << 2) and SUPPRESS_NOTIFICATIONS (1 << 12) can be set.
def send_temporary_message(content, timeout, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil, flags = 0)
@bot.send_temporary_message(@id, content, timeout, tts, embed, attachments, allowed_mentions, message_reference, components, flags)
end

# Convenience method to send a message with an embed.
Expand All @@ -461,16 +463,17 @@ def send_temporary_message(content, timeout, tts = false, embed = nil, attachmen
# @param allowed_mentions [Hash, Discordrb::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
# @param message_reference [Message, String, Integer, nil] The message, or message ID, to reply to if any.
# @param components [View, Array<Hash>] Interaction components to associate with this message.
# @param flags [Integer] Flags for this message. Currently only SUPPRESS_EMBEDS (1 << 2) and SUPPRESS_NOTIFICATIONS (1 << 12) can be set.
# @yield [embed] Yields the embed to allow for easy building inside a block.
# @yieldparam embed [Discordrb::Webhooks::Embed] The embed from the parameters, or a new one.
# @return [Message] The resulting message.
def send_embed(message = '', embed = nil, attachments = nil, tts = false, allowed_mentions = nil, message_reference = nil, components = nil)
def send_embed(message = '', embed = nil, attachments = nil, tts = false, allowed_mentions = nil, message_reference = nil, components = nil, flags = 0)
embed ||= Discordrb::Webhooks::Embed.new
view = Discordrb::Webhooks::View.new

yield(embed, view) if block_given?

send_message(message, tts, embed, attachments, allowed_mentions, message_reference, components || view.to_a)
send_message(message, tts, embed, attachments, allowed_mentions, message_reference, components || view.to_a, flags)
end

# Sends multiple messages to a channel
Expand Down
26 changes: 20 additions & 6 deletions lib/discordrb/data/message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ class Message
# @return [Array<Component>]
attr_reader :components

# @return [Integer] flags set on the message
attr_reader :flags

# @!visibility private
def initialize(data, bot)
@bot = bot
Expand Down Expand Up @@ -157,6 +160,7 @@ def initialize(data, bot)

@components = []
@components = data['components'].map { |component_data| Components.from_data(component_data, @bot) } if data['components']
@flags = data['flags'] || 0
end

# Replies to this message with the specified content.
Expand All @@ -176,31 +180,33 @@ def reply(content)
# @param allowed_mentions [Hash, Discordrb::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
# @param mention_user [true, false] Whether the user that is being replied to should be pinged by the reply.
# @param components [View, Array<Hash>] Interaction components to associate with this message.
# @param flags [Integer] Flags for this message. Currently only SUPPRESS_EMBEDS (1 << 2) and SUPPRESS_NOTIFICATIONS (1 << 12) can be set.
# @return (see #respond)
def reply!(content, tts: false, embed: nil, attachments: nil, allowed_mentions: {}, mention_user: false, components: nil)
def reply!(content, tts: false, embed: nil, attachments: nil, allowed_mentions: {}, mention_user: false, components: nil, flags: 0)
allowed_mentions = { parse: [] } if allowed_mentions == false
allowed_mentions = allowed_mentions.to_hash.transform_keys(&:to_sym)
allowed_mentions[:replied_user] = mention_user

respond(content, tts, embed, attachments, allowed_mentions, self, components)
respond(content, tts, embed, attachments, allowed_mentions, self, components, flags)
end

# (see Channel#send_message)
def respond(content, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil)
@channel.send_message(content, tts, embed, attachments, allowed_mentions, message_reference, components)
def respond(content, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil, flags = 0)
@channel.send_message(content, tts, embed, attachments, allowed_mentions, message_reference, components, flags)
end

# Edits this message to have the specified content instead.
# You can only edit your own messages.
# @param new_content [String] the new content the message should have.
# @param new_embeds [Hash, Discordrb::Webhooks::Embed, Array<Hash>, Array<Discordrb::Webhooks::Embed>, nil] The new embeds the message should have. If `nil` the message will be changed to have no embeds.
# @param new_components [View, Array<Hash>] The new components the message should have. If `nil` the message will be changed to have no components.
# @param flags [Integer] Flags for this message. Currently only SUPPRESS_EMBEDS (1 << 2) can be edited.
# @return [Message] the resulting message.
def edit(new_content, new_embeds = nil, new_components = nil)
def edit(new_content, new_embeds = nil, new_components = nil, flags = 0)
new_embeds = (new_embeds.instance_of?(Array) ? new_embeds.map(&:to_hash) : [new_embeds&.to_hash]).compact
new_components = new_components.to_a

response = API::Channel.edit_message(@bot.token, @channel.id, @id, new_content, [], new_embeds, new_components)
response = API::Channel.edit_message(@bot.token, @channel.id, @id, new_content, [], new_embeds, new_components, flags)
Message.new(JSON.parse(response), @bot)
end

Expand Down Expand Up @@ -292,6 +298,14 @@ def my_reactions
@reactions.select(&:me)
end

# Removes embeds from the message
# @return [Message] the resulting message.
def suppress_embeds
flags = @flags | (1 << 2)
response = API::Channel.edit_message(@bot.token, @channel.id, @id, :undef, :undef, :undef, :undef, flags)
Message.new(JSON.parse(response), @bot)
end

# Reacts to a message.
# @param reaction [String, #to_reaction] the unicode emoji or {Emoji}
def create_reaction(reaction)
Expand Down
2 changes: 1 addition & 1 deletion lib/discordrb/data/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def members
@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?
raise 'The :server_members intent is required to get server members' if @bot.gateway.intents.nobits?(INTENTS[:server_members])

@bot.request_chunks(@id)
sleep 0.05 until @chunked
Expand Down
2 changes: 1 addition & 1 deletion lib/discordrb/data/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def avatar_url(format = nil)

FLAGS.each do |name, value|
define_method("#{name}?") do
(@public_flags & value).positive?
@public_flags.anybits?(value)
end
end
end
Expand Down
15 changes: 9 additions & 6 deletions lib/discordrb/events/message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ module Respondable
# @param allowed_mentions [Hash, Discordrb::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
# @param message_reference [Message, String, Integer, nil] The message, or message ID, to reply to if any.
# @param components [View, Array<Hash>, nil] A collection of components to attach to the message.
# @param flags [Integer] Flags for this message. Currently only SUPPRESS_EMBEDS (1 << 2) and SUPPRESS_NOTIFICATIONS (1 << 12) can be set.
# @return [Discordrb::Message] the message that was sent
def send_message(content, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil)
channel.send_message(content, tts, embed, attachments, allowed_mentions, message_reference, components)
def send_message(content, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil, flags = 0)
channel.send_message(content, tts, embed, attachments, allowed_mentions, message_reference, components, flags)
end

# The same as {#send_message}, but yields a {Webhooks::Embed} for easy building of embedded content inside a block.
Expand All @@ -32,11 +33,12 @@ def send_message(content, tts = false, embed = nil, attachments = nil, allowed_m
# @param allowed_mentions [Hash, Discordrb::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
# @param message_reference [Message, String, Integer, nil] The message, or message ID, to reply to if any.
# @param components [View, Array<Hash>, nil] A collection of components to attach to the message.
# @param flags [Integer] Flags for this message. Currently only SUPPRESS_EMBEDS (1 << 2) and SUPPRESS_NOTIFICATIONS (1 << 12) can be set.
# @yield [embed] Yields the embed to allow for easy building inside a block.
# @yieldparam embed [Discordrb::Webhooks::Embed] The embed from the parameters, or a new one.
# @return [Message] The resulting message.
def send_embed(message = '', embed = nil, attachments = nil, tts = false, allowed_mentions = nil, message_reference = nil, components = nil, &block)
channel.send_embed(message, embed, attachments, tts, allowed_mentions, message_reference, components, &block)
def send_embed(message = '', embed = nil, attachments = nil, tts = false, allowed_mentions = nil, message_reference = nil, components = nil, flags = 0, &block)
channel.send_embed(message, embed, attachments, tts, allowed_mentions, message_reference, components, flags, &block)
end

# Sends a temporary message to the channel this message was sent in, right now.
Expand All @@ -47,8 +49,9 @@ def send_embed(message = '', embed = nil, attachments = nil, tts = false, allowe
# @param attachments [Array<File>] Files that can be referenced in embeds via `attachment://file.png`
# @param allowed_mentions [Hash, Discordrb::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
# @param components [View, Array<Hash>, nil] A collection of components to attach to the message.
def send_temporary_message(content, timeout, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, components = nil)
channel.send_temporary_message(content, timeout, tts, embed, attachments, allowed_mentions, components)
# @param flags [Integer] Flags for this message. Currently only SUPPRESS_EMBEDS (1 << 2) and SUPPRESS_NOTIFICATIONS (1 << 12) can be set.
def send_temporary_message(content, timeout, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, components = nil, flags = 0)
channel.send_temporary_message(content, timeout, tts, embed, attachments, allowed_mentions, components, flags)
end

# Adds a string to be sent after the event has finished execution. Avoids problems with rate limiting because only
Expand Down
2 changes: 1 addition & 1 deletion lib/discordrb/gateway.rb
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,7 @@ def handle_dispatch(packet)

@session = Session.new(data['session_id'])
@session.sequence = 0
@bot.__send__(:notify_ready) if @intents && (@intents & INTENTS[:servers]).zero?
@bot.__send__(:notify_ready) if @intents && @intents.nobits?(INTENTS[:servers])
when :RESUMED
# The RESUMED event is received after a successful op 6 (resume). It does nothing except tell the bot the
# connection is initiated (like READY would). Starting with v5, it doesn't set a new heartbeat interval anymore
Expand Down
Loading

0 comments on commit 6a8ea12

Please sign in to comment.