Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Message Flags #292

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
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
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
Loading