class Discordrb::Message
A message on Discord that was sent to a text channel
Attributes
@return [Array<Attachment>] the files attached to this message.
@return [Channel] the channel in which this message was sent.
@return [Array<Component>]
@return [String] the content of this message.
@return [Time] the timestamp at which this message was edited. ‘nil` if the message was never edited.
@return [true, false] whether the message was edited or not.
@return [true, false] whether the message was edited or not.
@return [Time] the timestamp at which this message was edited. ‘nil` if the message was never edited.
@return [Array<Embed>] the embed objects contained in this message.
@return [true, false] whether the message mentioned everyone or not.
@return [true, false] whether the message mentioned everyone or not.
@return [Array<User>] the users that were mentioned in this message.
@return [true, false] whether the message mentioned everyone or not.
@return [String] used for validating a message was sent.
@return [true, false] whether the message is pinned or not.
@return [true, false] whether the message is pinned or not.
@return [Array<Reaction>] the reaction objects contained in this message.
@return [Array<Role>] the roles that were mentioned in this message.
@return [Server, nil] the server in which this message was sent.
@return [String] the content of this message.
@return [Time] the timestamp at which this message was sent.
@return [String] the content of this message.
@return [true, false] whether the message used Text-To-Speech (TTS) or not.
@return [true, false] whether the message used Text-To-Speech (TTS) or not.
@return [Integer] what the type of the message is
@return [Member, User] the user that sent this message. (Will be a {Member} most of the time, it should only be a
{User} for old messages when the author has left the server since then)
@return [Integer, nil] the webhook ID that sent this message, or ‘nil` if it wasn’t sent through a webhook.
@return [Member, User] the user that sent this message. (Will be a {Member} most of the time, it should only be a
{User} for old messages when the author has left the server since then)
Public Class Methods
@!visibility private
# File lib/discordrb/data/message.rb, line 77 def initialize(data, bot) @bot = bot @content = data['content'] @channel = bot.channel(data['channel_id'].to_i) @pinned = data['pinned'] @type = data['type'] @tts = data['tts'] @nonce = data['nonce'] @mention_everyone = data['mention_everyone'] @referenced_message = Message.new(data['referenced_message'], bot) if data['referenced_message'] @message_reference = data['message_reference'] @server = @channel.server @webhook_id = data['webhook_id']&.to_i @author = if data['author'] if @webhook_id # This is a webhook user! It would be pointless to try to resolve a member here, so we just create # a User and return that instead. Discordrb::LOGGER.debug("Webhook user: #{data['author']['id']}") User.new(data['author'].merge({ '_webhook' => true }), @bot) elsif @channel.private? # Turn the message user into a recipient - we can't use the channel recipient # directly because the bot may also send messages to the channel Recipient.new(bot.user(data['author']['id'].to_i), @channel, bot) else member = @channel.server.member(data['author']['id'].to_i) if member member.update_data(data['member']) if data['member'] member.update_global_name(data['author']['global_name']) if data['author']['global_name'] else Discordrb::LOGGER.debug("Member with ID #{data['author']['id']} not cached (possibly left the server).") member = if data['member'] member_data = data['author'].merge(data['member']) Member.new(member_data, @server, bot) else @bot.ensure_user(data['author']) end end member end end @timestamp = Time.parse(data['timestamp']) if data['timestamp'] @edited_timestamp = data['edited_timestamp'].nil? ? nil : Time.parse(data['edited_timestamp']) @edited = !@edited_timestamp.nil? @id = data['id'].to_i @emoji = [] @reactions = [] data['reactions']&.each do |element| @reactions << Reaction.new(element) end @mentions = [] data['mentions']&.each do |element| @mentions << bot.ensure_user(element) end @role_mentions = [] # Role mentions can only happen on public servers so make sure we only parse them there if @channel.text? data['mention_roles']&.each do |element| @role_mentions << @channel.server.role(element.to_i) end end @attachments = [] @attachments = data['attachments'].map { |e| Attachment.new(e, self, @bot) } if data['attachments'] @embeds = [] @embeds = data['embeds'].map { |e| Embed.new(e, self) } if data['embeds'] @components = [] @components = data['components'].map { |component_data| Components.from_data(component_data, @bot) } if data['components'] end
Public Instance Methods
Returns a hash of all reactions to a message as keys and the users that reacted to it as values. @param limit [Integer] the limit of how many users to retrieve per distinct reaction emoji. ‘nil` will return all users @example Get all the users that reacted to a message for a giveaway.
giveaway_participants = message.all_reaction_users
@return [Hash<String => Array<User>>] A hash mapping the string representation of a
reaction to an array of users.
# File lib/discordrb/data/message.rb, line 334 def all_reaction_users(limit: 100) all_reactions = @reactions.map { |r| { r.to_s => reacted_with(r, limit: limit) } } all_reactions.reduce({}, :merge) end
Add an {Await} for a message with the same user and channel. @see Bot#add_await
@deprecated Will be changed to blocking behavior in v4.0. Use {#await!} instead.
# File lib/discordrb/data/message.rb, line 230 def await(key, attributes = {}, &block) @bot.add_await(key, Discordrb::Events::MessageEvent, { from: @author.id, in: @channel.id }.merge(attributes), &block) end
Add a blocking {Await} for a message with the same user and channel. @see Bot#add_await!
# File lib/discordrb/data/message.rb, line 236 def await!(attributes = {}, &block) @bot.add_await!(Discordrb::Events::MessageEvent, { from: @author.id, in: @channel.id }.merge(attributes), &block) end
Add an {Await} for a reaction to be added on this message. @see Bot#add_await
@deprecated Will be changed to blocking behavior in v4.0. Use {#await_reaction!} instead.
# File lib/discordrb/data/message.rb, line 243 def await_reaction(key, attributes = {}, &block) @bot.add_await(key, Discordrb::Events::ReactionAddEvent, { message: @id }.merge(attributes), &block) end
Add a blocking {Await} for a reaction to be added on this message. @see Bot#add_await!
# File lib/discordrb/data/message.rb, line 249 def await_reaction!(attributes = {}, &block) @bot.add_await!(Discordrb::Events::ReactionAddEvent, { message: @id }.merge(attributes), &block) end
Whether or not this message was of type “CHAT_INPUT_COMMAND” @return [true, false]
# File lib/discordrb/data/message.rb, line 379 def chat_input_command? @type == 20 end
Reacts to a message. @param reaction [String, to_reaction] the unicode emoji or {Emoji}
# File lib/discordrb/data/message.rb, line 291 def create_reaction(reaction) reaction = reaction.to_reaction if reaction.respond_to?(:to_reaction) API::Channel.create_reaction(@bot.token, @channel.id, @id, reaction) nil end
Deletes this message.
# File lib/discordrb/data/message.rb, line 208 def delete(reason = nil) API::Channel.delete_message(@bot.token, @channel.id, @id, reason) nil end
Removes all reactions from this message.
# File lib/discordrb/data/message.rb, line 355 def delete_all_reactions API::Channel.delete_all_reactions(@bot.token, @channel.id, @id) end
Deletes this client’s reaction on this message. @param reaction [String, to_reaction] the reaction to remove
# File lib/discordrb/data/message.rb, line 349 def delete_own_reaction(reaction) reaction = reaction.to_reaction if reaction.respond_to?(:to_reaction) API::Channel.delete_own_reaction(@bot.token, @channel.id, @id, reaction) end
Deletes a reaction made by a user on this message. @param user [User, String
, Integer] the user or user ID who used this reaction @param reaction [String, to_reaction] the reaction to remove
# File lib/discordrb/data/message.rb, line 342 def delete_reaction(user, reaction) reaction = reaction.to_reaction if reaction.respond_to?(:to_reaction) API::Channel.delete_user_reaction(@bot.token, @channel.id, @id, reaction, user.resolve_id) 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. @return [Message] the resulting message.
# File lib/discordrb/data/message.rb, line 199 def edit(new_content, new_embeds = nil, new_components = nil) 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) Message.new(JSON.parse(response), @bot) end
@return [Array<Emoji>] the emotes that were used/mentioned in this message.
# File lib/discordrb/data/message.rb, line 264 def emoji return if @content.nil? return @emoji unless @emoji.empty? @emoji = @bot.parse_mentions(@content).select { |el| el.is_a? Discordrb::Emoji } end
Check if any emoji were used in this message. @return [true, false] whether or not any emoji were used
# File lib/discordrb/data/message.rb, line 273 def emoji? emoji&.empty? end
@return [true, false] whether this message was sent by the current {Bot}.
# File lib/discordrb/data/message.rb, line 254 def from_bot? @author&.current_bot? end
The inspect method is overwritten to give more useful output
# File lib/discordrb/data/message.rb, line 360 def inspect "<Message content=\"#{@content}\" id=#{@id} timestamp=#{@timestamp} author=#{@author} channel=#{@channel}>" end
@return [String] a URL that a user can use to navigate to this message in the client
# File lib/discordrb/data/message.rb, line 365 def link "https://discord.com/channels/#{@server&.id || '@me'}/#{@channel.id}/#{@id}" end
Returns the reactions made by the current bot or user. @return [Array<Reaction>] the reactions
# File lib/discordrb/data/message.rb, line 285 def my_reactions @reactions.select(&:me) end
Pins this message
# File lib/discordrb/data/message.rb, line 214 def pin(reason = nil) API::Channel.pin_message(@bot.token, @channel.id, @id, reason) @pinned = true nil end
Returns the list of users who reacted with a certain reaction. @param reaction [String, to_reaction] the unicode emoji or {Emoji} @param limit [Integer] the limit of how many users to retrieve. ‘nil` will return all users @example Get all the users that reacted with a thumbs up.
thumbs_up_reactions = message.reacted_with("\u{1F44D}")
@return [Array<User>] the users who used this reaction
# File lib/discordrb/data/message.rb, line 305 def reacted_with(reaction, limit: 100) reaction = reaction.to_reaction if reaction.respond_to?(:to_reaction) reaction = reaction.to_s if reaction.respond_to?(:to_s) get_reactions = proc do |fetch_limit, after_id = nil| resp = API::Channel.get_reactions(@bot.token, @channel.id, @id, reaction, nil, after_id, fetch_limit) return JSON.parse(resp).map { |d| User.new(d, @bot) } end # Can be done without pagination return get_reactions.call(limit) if limit && limit <= 100 paginator = Paginator.new(limit, :down) do |last_page| if last_page && last_page.count < 100 [] else get_reactions.call(100, last_page&.last&.id) end end paginator.to_a end
Check if any reactions were used in this message. @return [true, false] whether or not this message has reactions
# File lib/discordrb/data/message.rb, line 279 def reactions? !@reactions.empty? end
@return [Message, nil] the Message
this Message
was sent in reply to.
# File lib/discordrb/data/message.rb, line 384 def referenced_message return @referenced_message if @referenced_message return nil unless @message_reference referenced_channel = @bot.channel(@message_reference['channel_id']) @referenced_message = referenced_channel.message(@message_reference['message_id']) end
Replies to this message with the specified content. @deprecated Please use {#respond}. @param content [String] The content to send. Should not be longer than 2000 characters or it will result in an error. @return (see respond
) @see Channel#send_message
# File lib/discordrb/data/message.rb, line 167 def reply(content) @channel.send_message(content) end
Responds to this message as an inline reply. @param content [String] The content to send. Should not be longer than 2000 characters or it will result in an error. @param tts [true, false] Whether or not this message should be sent using Discord text-to-speech. @param embed [Hash, Discordrb::Webhooks::Embed, nil] The rich embed to append to this message. @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 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. @return (see respond
)
# File lib/discordrb/data/message.rb, line 180 def reply!(content, tts: false, embed: nil, attachments: nil, allowed_mentions: {}, mention_user: false, components: nil) 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) end
Whether or not this message was sent in reply to another message @return [true, false]
# File lib/discordrb/data/message.rb, line 373 def reply? !@referenced_message.nil? end
(see Channel#send_message
)
# File lib/discordrb/data/message.rb, line 189 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) end
to_message
-> self or message @return [Discordrb::Message]
# File lib/discordrb/data/message.rb, line 408 def to_message self end
Unpins this message
# File lib/discordrb/data/message.rb, line 221 def unpin(reason = nil) API::Channel.unpin_message(@bot.token, @channel.id, @id, reason) @pinned = false nil end
@return [true, false] whether this message has been sent over a webhook.
# File lib/discordrb/data/message.rb, line 259 def webhook? !@webhook_id.nil? end